cssAudio - Activefile-genericCSS - ActiveGeneric - ActiveHTML - ActiveImage - ActiveJS - ActiveSVG - ActiveText - Activefile-genericVideo - ActiveLovehtmlicon-new-collectionicon-personicon-teamlog-outoctocatpop-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.

            
              <canvas id="canvas" width="450px" height="450px"></canvas>
            
          
!
            
              * {
	border: 0;
	margin: 0;
}
canvas {
  background-color: rgb(255, 255, 255);
}
            
          
!
            
              // https://msvaljek.blogspot.com/2013/09/pi-to-rad-visualization.html
/*
      solution for:
      https://i.imgur.com/4ibsGlI.gif
      
      by @msvaljek
*/

var canvas = document.getElementById('canvas'),
    ctx = canvas.getContext('2d'),
    cwidth = canvas.width,
    cheight = canvas.height;

window.requestAnimFrame = (function(){
  return window.requestAnimationFrame ||
  window.webkitRequestAnimationFrame ||
  window.mozRequestAnimationFrame ||
  function( callback ) {
    window.setTimeout(callback, 1000 / 60);
  };
})();

var PiRad = function () {
  this.state = 'begin';

  this.circleColor = 'rgb(31, 31, 255)';
  this.crossColor = 'rgb(235, 235, 235)';
  this.markerColor = 'rgb(255, 0, 0)';
  this.textColor = 'rgb(255, 208, 22)';
  this.innerCircleFill = 'rgb(255, 242, 204)';
  this.innerCircleStroke = 'rgb(255, 203, 47)';
};

PiRad.prototype.changeState = function (newState, timeout) {
  var that = this;
  (function() {
    if (newState !== this.nextState) {
      setTimeout(function() {that.state = newState;}, timeout);
      this.nextState = newState;
    }
  })();
};

PiRad.prototype.draw = function () {
  var that = this;
  ctx.lineWidth = 1;
  ctx.strokeStyle = this.crossColor;

  ctx.beginPath();
  ctx.moveTo(25, cheight / 2);
  ctx.lineTo(cwidth - 25, cheight / 2);
  ctx.stroke();

  ctx.beginPath();
  ctx.moveTo(cwidth / 2, 25);
  ctx.lineTo(cwidth / 2, cheight - 25);
  ctx.stroke();

  this.drawSmallCircle();

  if (this.state === 'begin') {
    this.nextState = '';
    this.smallCircleColor = 'red';
    this.movingDot = {
      x: cwidth / 2,
      y: cheight / 2,
      dx: 5,
      a: 0,
      da: 0.2
    };
    this.movingCenter = {
      x: cwidth / 2,
      y: cheight / 2,
      a: Math.PI,
      da: 0.1
    };
    this.r = 150;
    this.innerR = 40;
    this.textOut = {
      x: 200,
      y: 270
    };
    this.marker = {
      a: -1,
      b: 0,
      s: 0.05
    };
    this.lines = [];
    this.circleMarks = [];

    that.state = 'idle';
    this.changeState('moveRedDotOut', 1000);

  } else if (this.state === 'moveRedDotOut') {

    this.drawRedDotWithConnectionToCenter();

    if ((this.movingDot.x - cwidth / 2) >= this.r) {
      this.movingDot.x = cwidth / 2 + this.r;

      this.changeState('moveRedDotAround', 2000);

    } else {
      this.movingDot.x += this.movingDot.dx;

    }

  } else if (this.state === 'moveRedDotAround') {
    if (this.movingDot.a - this.movingDot.da > Math.PI * -2) {
      this.movingDot.a -= this.movingDot.da;
    } else {
      this.movingDot.a = -2 * Math.PI;
      this.changeState('drawRAndStartWait', 1000);
    }

    this.movingDot.x = cwidth / 2 + Math.cos(this.movingDot.a) * this.r;
    this.movingDot.y = cheight / 2 + Math.sin(this.movingDot.a) * this.r;

    this.drawCircleToAngle(this.movingDot.a);
    this.drawRedDotWithConnectionToCenter();

  } else if (this.state === 'drawRAndStartWait') {
    this.drawR();
    this.changeState('hideR', 3000);

  } else if (this.state === 'hideR') {
    this.drawCircleToAngle(this.movingDot.a);
    this.drawRedDotWithConnectionToCenter();
    this.changeState('moveRedLineUp', 2000);

  } else if (this.state === 'moveRedLineUp') {
    this.smallCircleColor = 'black';

    if (this.movingCenter.a + this.movingCenter.da < 3 * Math.PI / 2) {
      this.movingCenter.a += this.movingCenter.da;
    } else {
      this.movingCenter.a = 3 * Math.PI / 2;
      this.changeState('stickRedLineToCircle', 3000);
    }

    this.movingCenter.x = this.movingDot.x + Math.cos(this.movingCenter.a) * this.r;
    this.movingCenter.y = this.movingDot.y + Math.sin(this.movingCenter.a) * this.r;

    this.drawCircleToAngle(this.movingDot.a);
    this.drawRedDotWithMovingCenter();

  } else if (this.state === 'stickRedLineToCircle') {
    var endx = cwidth / 2 + Math.cos(-1) * this.r;
    var endy = cheight / 2 + Math.sin(-1) * this.r;

    if (endx < this.movingCenter.x) {
      this.movingCenter.x -= 2;
    } else {
      this.movingCenter.x = endx;
    }

    if (endy > this.movingCenter.y) {
      this.movingCenter.y += 0.7;
    } else {
      this.movingCenter.y = endy;
    }

    if (this.movingCenter.x == endx && this.movingCenter.y == endy) {
      this.changeState('markFirstSegment', 2000);
    }

    this.drawCircleToAngle(this.movingDot.a);
    this.drawRedDotWithMovingCenterCurved();

  } else if (this.state === 'markFirstSegment') {
    this.drawMarkedSegments();
    this.changeState('outputOneRad', 2000);

  } else if (this.state === 'outputOneRad') {
    this.drawSomeText('1 rad');
    this.drawMarkedSegments();
    this.changeState('startMarking', 2000);

  } else if (this.state === 'startMarking') {
    this.circleMarks[0] = 0;
    this.lines[0] = -1;

    if (this.marker.a > -2) {
      this.marker.a -= this.marker.s;
      this.marker.b = this.marker.a + 1;
    } else {
      this.marker.a = -2;
      this.marker.b = -1;
      this.state = 'mark2Rad';
    }

    this.drawSomeText('1 rad');
    this.drawMarkedSegments();

  } else if (this.state === 'mark2Rad') {
    this.drawSomeText('2 rad');
    this.drawMarkedSegments();
    this.changeState('startMarking3', 2000);

  } else if (this.state === 'startMarking3') {
    this.circleMarks[1] = -1;
    this.lines[1] = -2;

    if (this.marker.a > -3) {
      this.marker.a -= this.marker.s;
      this.marker.b = this.marker.a + 1;
    } else {
      this.marker.a = -3;
      this.marker.b = -2;
      this.state = 'mark3Rad';
    }

    this.drawSomeText('2 rad');
    this.drawMarkedSegments();

  } else if (this.state === 'mark3Rad') {
    this.drawSomeText('3 rad');
    this.drawMarkedSegments();
    this.changeState('startMarkingPi', 2000);

  } else if (this.state === 'startMarkingPi') {
    this.circleMarks[2] = -2;
    this.lines[2] = -3;

    if (this.marker.a > -Math.PI) {
      this.marker.a -= this.marker.s / 8;
    } else {
      this.marker.a = -Math.PI;
    }

    if (this.marker.b > -3) {
      this.marker.b -= this.marker.s / 2;
    } else {
      this.marker.b = -3;
    }

    if (this.marker.a === -Math.PI && this.marker.b === -3) {
      this.state = 'markPi';
    } else {
      this.drawSomeText('3 rad');
    }

    this.drawMarkedSegments();

  } else if (this.state === 'markPi') {
    this.drawSomeText('π rad');
    this.drawMarkedSegments();
    this.changeState('removePiMarkings', 2000);

  } else if (this.state === 'removePiMarkings') {
    this.circleMarks.length = 0;
    this.circleMarks[0] = 0;
    this.circleMarks[1] = Math.PI;
    this.lines.length = 0;
    this.marker.b = this.marker.a;
    this.drawSomeText('π rad');
    this.drawMarkedSegments({hideRedMarkers: true});
    this.changeState('movePiTextUp', 2000);

  } else if (this.state === 'movePiTextUp') {
    if (this.textOut.y > 170) {
      this.textOut.y -= 5;
    }

    this.drawMarkedSegments({hideRedMarkers: true});
    this.drawSomeText('π rad');

    this.changeState('moveToTwoPi', 2000);

  } else if (this.state === 'moveToTwoPi') {

    if (this.marker.a > -2 * Math.PI) {
      this.marker.a -= this.marker.s;

    } else {
      this.marker.a = -2 * Math.PI;
      this.textOut.x -= 25;
      this.state = 'mark2Pi';

    }
    this.circleMarks[2] = this.marker.a;

    this.marker.b = this.marker.a;

    this.drawMarkedSegments({hideRedMarkers: true});
    this.drawSomeText('π rad');

  } else if (this.state === 'mark2Pi') {
    this.circleMarks.length = 0;
    this.circleMarks[0] = 0;
    this.drawSomeText('2π rad');
    this.drawMarkedSegments({hideRedMarkers: true});

    this.changeState('displayFinal', 2000);

  } else if (this.state === 'displayFinal') {
    this.circleMarks.length = 0;
    this.drawSomeText('2π rad');
    this.drawMarkedSegments({hideRedMarkers: true, hideInnerCircle: true});

    this.changeState('begin', 4000);
  }

};

PiRad.prototype.drawRedDotWithConnectionToCenter = function () {
  ctx.beginPath();
  ctx.fillStyle = this.smallCircleColor;
  ctx.arc(this.movingDot.x, this.movingDot.y, 4, 0, 2 * Math.PI);
  ctx.fill();

  ctx.lineWidth = 2;
  ctx.strokeStyle = this.markerColor;
  ctx.beginPath();
  ctx.moveTo(cwidth / 2, cheight / 2);
  ctx.lineTo(this.movingDot.x, this.movingDot.y);
  ctx.stroke();
};

PiRad.prototype.drawRedDotWithMovingCenter = function () {
  ctx.strokeStyle = ctx.fillStyle = this.markerColor;
  ctx.beginPath();
  ctx.arc(this.movingDot.x, this.movingDot.y, 4, 0, 2 * Math.PI);
  ctx.fill();

  ctx.beginPath();
  ctx.arc(this.movingCenter.x, this.movingCenter.y, 4, 0, 2 * Math.PI);
  ctx.fill();

  ctx.lineWidth = 2;
  ctx.beginPath();
  ctx.moveTo(this.movingCenter.x, this.movingCenter.y);
  ctx.lineTo(this.movingDot.x, this.movingDot.y);
  ctx.stroke();
};

PiRad.prototype.drawRedDotWithMovingCenterCurved = function () {
  ctx.strokeStyle = ctx.fillStyle = this.markerColor;
  ctx.beginPath();
  ctx.arc(this.movingDot.x, this.movingDot.y, 4, 0, 2 * Math.PI);
  ctx.fill();

  ctx.beginPath();
  ctx.arc(this.movingCenter.x, this.movingCenter.y, 4, 0, 2 * Math.PI);
  ctx.fill();

  var endx = ~~(cwidth / 2 + Math.cos(-1) * this.r);
  var endy = ~~(cheight / 2 + Math.sin(-1) * this.r);

  var distance = ~~(Math.sqrt(Math.pow(endx - this.movingCenter.x, 2) + Math.pow(endy - this.movingCenter.y, 2)));
  var factor = 1.12 + distance / 400;

  var x = ~~(cwidth / 2 + Math.cos(-0.5) * this.r * factor);
  var y = ~~(cheight / 2 + Math.sin(-0.5) * this.r * factor);

  ctx.lineWidth = 2;
  ctx.beginPath();
  ctx.moveTo(this.movingDot.x, this.movingDot.y);
  ctx.quadraticCurveTo(x, y, this.movingCenter.x, this.movingCenter.y);
  ctx.stroke();
};

PiRad.prototype.drawR = function () {
    this.drawCircleToAngle(this.movingDot.a);
    this.drawRedDotWithConnectionToCenter();
    ctx.fillStyle = this.markerColor;
    ctx.font = '60px arial italic';
    ctx.fillText('r', 290, 210);
};

PiRad.prototype.drawSomeText = function (text) {
    ctx.fillStyle = this.textColor;
    ctx.font = '40px arial italic bold';
    ctx.fillText(text, this.textOut.x, this.textOut.y);
};

PiRad.prototype.drawCircleToAngle = function (angle) {
  ctx.beginPath();
  ctx.strokeStyle = this.circleColor;
  ctx.lineWidth = 1;
  ctx.arc(cwidth / 2, cheight / 2, this.r, 0, angle, true);
  ctx.stroke();
};

PiRad.prototype.drawInnerCircleToAngle = function (angle) {
  ctx.strokeStyle = this.innerCircleStroke;
  ctx.fillStyle = this.innerCircleFill;
  ctx.lineWidth = 1;

  ctx.beginPath();
  ctx.moveTo(cwidth / 2, cheight / 2);
  ctx.arc(cwidth / 2, cheight / 2, this.innerR, 0, angle, true);
  ctx.closePath();
  ctx.fill();
  ctx.stroke();
};

PiRad.prototype.drawSmallCircle = function () {
  ctx.beginPath();
  ctx.fillStyle = this.smallCircleColor;
  ctx.arc(cwidth / 2, cheight / 2, 4, 0, 2 * Math.PI);
  ctx.fill();
};

PiRad.prototype.drawMarkedSegments = function (config) {
    if (!config || !config.hideInnerCircle) {
      this.drawCircleToAngle(2 * Math.PI);
      this.drawInnerCircleToAngle(this.marker.a);
    }

    ctx.strokeStyle = this.innerCircleStroke;

    for (var i = 0; i < this.lines.length; i++) {
        ctx.lineWidth = 0.5;
        ctx.beginPath();
        ctx.moveTo(cwidth / 2, cheight / 2);
        ctx.lineTo(cwidth / 2 + Math.cos(this.lines[i]) * this.r, cheight / 2 + Math.sin(this.lines[i]) * this.r);
        ctx.stroke();
    }

    for (var j = 0; j < this.circleMarks.length; j++) {
      ctx.fillStyle = this.innerCircleStroke;
      ctx.beginPath();
      ctx.arc(cwidth / 2 + Math.cos(this.circleMarks[j]) * this.r, cheight / 2 + Math.sin(this.circleMarks[j]) * this.r, 4, 0, 2 * Math.PI);
      ctx.fill();
    }

    var bx = cwidth / 2 + Math.cos(this.marker.b) * this.r,
        by = cheight / 2 + Math.sin(this.marker.b) * this.r,
        ax = cwidth / 2 + Math.cos(this.marker.a) * this.r,
        ay = cheight / 2 + Math.sin(this.marker.a) * this.r;

    if (!config || !config.hideInnerCircle) {
      ctx.lineWidth = 2;
      ctx.beginPath();
      ctx.moveTo(cwidth / 2, cheight / 2);
      ctx.lineTo(cwidth / 2 + this.r, cheight / 2);
      ctx.stroke();

      ctx.beginPath();
      ctx.moveTo(cwidth / 2, cheight / 2);
      ctx.lineTo(ax, ay);
      ctx.stroke();

      this.drawSmallCircle();
    } else {
      ctx.lineWidth = 2;
    }

    ctx.strokeStyle = this.innerCircleStroke;
    ctx.beginPath();
    ctx.arc(cwidth / 2, cheight / 2, this.r, 0, this.marker.b, true);
    ctx.stroke();

    if (!config || !config.hideRedMarkers) {
      ctx.lineWidth = 2;
      ctx.strokeStyle = ctx.fillStyle = this.markerColor;
      ctx.beginPath();
      ctx.arc(ax, ay, 4, 0, 2 * Math.PI);
      ctx.fill();

      ctx.beginPath();
      ctx.arc(bx, by, 4, 0, 2 * Math.PI);
      ctx.fill();

      ctx.beginPath();
      ctx.arc(cwidth / 2, cheight / 2, this.r, this.marker.a, this.marker.b, false);
      ctx.stroke();
    }
};

var piRad = new PiRad();

(function animloop() {
  requestAnimFrame(animloop);
  ctx.clearRect(0, 0, cwidth, cheight);
  piRad.draw();
})();
            
          
!
999px
Loading ..................

Console