Thursday 27 April 2017

Pattern Making - Spirograph - JavaScript

This post contains an illustration of making a spirograph using HTML5 and Javascript. Note that down there, we have three small buttons for you to play with the animation. The concept used here is that I have two rods/arms attached back to back and I'm plotting the trajectory of end-point of the last rod. See the below animation to get a clear idea.



Note that the code mentioned above is not easily extendable but the coming posts in this series will show how you can create an array of rods, and loop over all the rods to track the path traced by the end point of the last rod.
You can always right click and go to view page source to view the code behind construction of the above spirograph, but for the sake of simplicity and cutting off all the dirty code, here is the clean code used to make the above spirograph.
HTML Code
<html>
<title>Rakshit</title>
<script type="text/javascript" src="a.js"></script>
<body>
    <canvas id="mycanvas" width="500" height="500"></canvas>
    <canvas id="desingcanvas" width="500" height="500"></canvas>
    <button id="stopButton">Stop</button>
    <button id="resumeButton">Resume</button>
    <button id="restartButton">Restart</button>

</body>

</html>


Javascript Code
/*
    This program adds two rotating rods, representing robotic arm

    This is a simple program that just adds 2 rods
    and gives the trajectory of the end point of the second rod
*/
var width=0;
var height=0;
var interval;
var rod1,rod2;
var drawing=false; // a global variable that keeps track of whether we are drawing or not.
window.onload = function(){
    var cns = document.getElementById("mycanvas");

    width = cns.width;
    height = cns.height;
    var context = cns.getContext("2d");
    var designContext =  document.getElementById("desingcanvas").getContext("2d");
    rod1=Rod.create(250,250,80,0,10.0,"#0000FF");
    rod2=Rod.create(rod1.endx,rod1.endy,130,Math.PI,80.0,"#FF0000");

    interval = setInterval(function(){draw(context,designContext);},1);

    var stopButton = document.getElementById("stopButton");
    stopButton.addEventListener("click",stopButtonClicked,false);
    var resumeButton = document.getElementById("resumeButton");
    resumeButton.addEventListener("click",resumeButtonClicked,false);
    var restartButton = document.getElementById("restartButton");
    restartButton.addEventListener("click",restartButtonClicked,false);

};

function stopButtonClicked()
{
    if(drawing)
    {
        clearInterval(interval);
        drawing=false;
    }
}
function resumeButtonClicked()
{
    if(drawing===false)
    {
        var context = document.getElementById("mycanvas").getContext("2d");
        var designContext =  document.getElementById("desingcanvas").getContext("2d");
        interval = setInterval(function(){draw(context,designContext,rod1,rod2);},1);
    }
}
function restartButtonClicked()
{
    if(drawing===true)
        clearInterval(interval);
    var canvas1 = document.getElementById("mycanvas");
    var canvas2 = document.getElementById("desingcanvas");
    var context = canvas1.getContext("2d");
    var designContext =  canvas2.getContext("2d");

    context.clearRect(0,0,canvas1.width,canvas1.height);
    designContext.clearRect(0,0,canvas2.width,canvas2.height);

    interval = setInterval(function(){draw(context,designContext,rod1,rod2);},1);
}

var Rod={
    startx:0,
    starty:0,
    endx:0,
    endy:0,
    length:0,
    angle:0,
    speed:100,
    color:"#000000",
    create:function(startx,starty,length,angle,speed,color)
    {
        var obj=Object.create(this);
        obj.startx=startx;
        obj.starty=starty;
        obj.length=length;
        obj.angle=angle;
        obj.speed=speed/500.0;

        obj.color=color;

        obj.endx=startx+length*Math.cos(angle);
        obj.endy=starty+length*Math.sin(angle);
        return obj;
    },

    update:function(startx,starty)
    {
        this.startx=startx;
        this.starty=starty;
        this.angle+=this.speed;
        if(this.angle>2*Math.PI)
            this.angle=0;
        this.endx=this.startx+this.length*Math.cos(this.angle);
        this.endy=this.starty+this.length*Math.sin(this.angle);
    },

    drawRod:function(context)
    {
        context.strokeStyle = this.color;
        context.lineWidth = 2;
        context.beginPath();
        context.moveTo(this.startx,this.starty);
        context.lineTo(this.endx,this.endy);
        context.stroke();
        context.closePath();
    }

};


function draw(context,designContext)
{
    drawing=true;
    designContext.strokeStyle="#FF0000";
    designContext.lineWidth=0.25;
    designContext.beginPath();
    designContext.moveTo(rod2.endx,rod2.endy);

    context.clearRect(0,0,width,height);

    rod1.drawRod(context);
    rod1.update(rod1.startx,rod1.starty);
    rod2.drawRod(context);
    rod2.update(rod1.endx,rod1.endy);

    designContext.lineTo(rod2.endx,rod2.endy);
    designContext.stroke();
    designContext.closePath();
}

Please bear with me as I am new to javascript and comment if you have any new idea or find anything wrong in this post.

No comments:

Post a Comment