cssAudio - Activefile-genericCSS - ActiveGeneric - ActiveHTML - ActiveImage - ActiveJS - ActiveSVG - ActiveText - Activefile-genericVideo - Activehtmlicon-personicon-teamoctocatpop-outspinnerstartv

Pen Settings

CSS Base

Vendor Prefixing

Add External CSS

These stylesheets will be added in this order and before the code you write in the CSS editor. You can also add another Pen here, and it will pull the CSS from it. Try typing "font" or "ribbon" below.

Quick-add: + add another resource

Add External JavaScript

These scripts will run in this order and before the code in the JavaScript editor. You can also link to another Pen here, and it will run the JavaScript from it. Also try typing the name of any popular library.

Quick-add: + add another resource

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

            
              body {
  margin: 0;
}

#canvas {
  background-color: #DEDCDF;
}
            
          
!
            
              'use strict';
var windowHeight = window.innerHeight;
var windowWidth = window.innerWidth;
var PI2 = Math.PI * 2;
var PI = Math.PI;
var PIOneThird = PI / 3;

//canvas
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

setUpCanvas();

function setUpCanvas() {
  canvas.width = windowWidth;
  canvas.height = windowHeight;
  ctx.fillStyle = '#DEDCDF';
  ctx.fillRect(0, 0, windowWidth, windowHeight);
}
//キャンバスをクリア
function clearCanvas() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
}

//ベクトル
class Vector {
  constructor(x, y) {
      this.x = x;
      this.y = y;
      return this;
    }
    //加算
  add(x, y) {
    if (x instanceof Vector) {
      this.x += x.x;
      this.y += x.y;
      return this;
    } else {
      this.x += x;
      this.y += y;
      return this;
    }
  }
  static add(vectorA, vectorB) {
      var x = vectorA.x + vectorB.x;
      var y = vectorA.y + vectorB.y;
      return new Vector(x, y);
    }
    //減算
  sub(x, y) {
    if (x instanceof Vector) {
      this.x -= x.x;
      this.y -= x.y;
      return this;
    } else {
      this.x -= x;
      this.y -= y;
      return this;
    }
  }
  static sub(vectorA, vectorB) {
      var x = vectorA.x - vectorB.x;
      var y = vectorA.y - vectorB.y;
      return new Vector(x, y);
    }
    // ベクトル乗算
  mult(n) {
    this.x = this.x * n;
    this.y = this.y * n;
    return this;
  }
    //ベクトル除算
  div(n) {
      this.x = this.x / n;
      this.y = this.y / n;
      return this;
    }
    //ベクトルの大きさを返す
  mag() {
      return Math.sqrt(this.x * this.x + this.y * this.y);
    }
    //正規化する
  normalize() {
      var size = this.mag();
      if (size === 0) {
        return this;
      }
      this.x = this.x * (1 / size);
      this.y = this.y * (1 / size);
      return this;
    }
    //最大値
  limit(max) {
      if (this.mag() > max) {
        return this.normalize().mult(max);
      } else {
        return this;
      }
    }
    //回転
  rotate(angle) {
    var cos = Math.cos(angle);
    var sin = Math.sin(angle);

    var newX = this.x * cos - this.y * sin;
    var newY = this.x * sin + this.y * cos;
    this.x = newX;
    this.y = newY;
    return this;
  }
    //ベクトルの角度を返す
  static angle(vectorA) {
      var theta = Math.atan2(vectorA.y, vectorA.x);
      return theta;
    }
    //長さ1のランダムな値を返す
  static random2D() {
      this.x = (Math.random() * 2) - 1;
      this.y = (Math.random() * 2) - 1;
      return this.normalize();
    }
    //角度から長さ1のベクトルを返す
  static fromAngle(angle) {
      return new Vector(Math.cos(angle), Math.sin(angle));
    }
    //同じ値をもったVectorを返す
  static copy(vectorA) {
      return new Vector(vectorA.x, vectorA.y);
    }
    //ベクトル内積
  static dot(vectorA, vectorB) {
      return vectorA.x * vectorB.x + vectorA.y * vectorB.y;
    }
    //ベクトル間の角度を返す
  static angleBetween(vectorA, vectorB) {
    var theta = Math.acos((this.dot(vectorA, vectorB)) / (vectorA.mag() * vectorB.mag()));
    return theta;
  }
}

//生成された線を管理する
class Lines{
  constructor(){
    this.nextArr = [];
    this.arr = [];
  }
  //リストに加える
  add(kochLine){
    this.arr.push(kochLine);
  }
  //次の世代へ進める
  update(){
    this.arr = this.nextArr;
    this.nextArr = [];
  }
  // コッホ曲線をつくる
  generate(){
    clearCanvas();
    ctx.strokeStyle = '#607C7C';

    for (var i = 0; i < this.arr.length; i++) {
      //線の位置をアップレートし描く
      this.arr[i].update();
      this.arr[i].draw();
      //次の世代の線をつくって配列に追加
      var nextVertex = this.arr[i].nextVertex();
      for (var j = 0; j < nextVertex.length - 1; j++) {
        this.nextArr.push(new KochLine(nextVertex[j], nextVertex[j + 1]));
      }
    }
    this.update();
  }
}


//コッホ曲線
class KochLine{
  constructor(start, end){
    this.line = Vector.sub(end, start);
    this.a = Vector.copy(start);
    this.e = Vector.copy(end);
  }
  update(){
    this.b = Vector.copy(this.line).div(3).add(this.a);
    this.c = Vector.copy(this.line).div(3).rotate(PIOneThird).add(this.b);
    this.d = Vector.copy(this.line).div(3).mult(2).add(this.a);
  }
  draw(){
    ctx.beginPath();
    ctx.moveTo(this.a.x, this.a.y);
    ctx.lineTo(this.b.x, this.b.y);
    ctx.lineTo(this.c.x, this.c.y);
    ctx.lineTo(this.d.x, this.d.y);
    ctx.lineTo(this.e.x, this.e.y);
    ctx.stroke();
    ctx.closePath();
  }
  //次の世代の頂点を返す
  nextVertex(){
    return [this.a, this.b, this.c, this.d, this.e];
  }
}

var lines = new Lines();
//最初のライン
var kochLine = new KochLine(new Vector(0, 10), new Vector(windowWidth, 10));
//リストに追加
lines.arr.push(kochLine);
//1pxになるまでコッホ曲線を描く
while (lines.arr[0].line.mag() > 1) {
  lines.generate();
}

            
          
!
999px
Close

Asset uploading is a PRO feature.

As a PRO member, you can drag-and-drop upload files here to use as resources. Images, Libraries, JSON data... anything you want. You can even edit them anytime, like any other code on CodePen.

Go PRO

Loading ..................

Console