vivatus
vivatus

Reputation: 2333

Drawing Shapes along a curved path in canvas

I've been doing some googling but I could not find the answer (I think I'm asking the wrong question), but I was wondering if it would be possible to draw a set of objects along a path.

For example, is it possible to draw a path using quadraticCurveTo(), and then drawing a set of circles along that curve?

Thanks in advance.

Upvotes: 0

Views: 2428

Answers (2)

markE
markE

Reputation: 105035

This equation will give you points at interval along a quadratic curve.

At the start of the curve T==0.00

At the end of the curve T==1.00

function getQuadraticBezierXYatT(startPt,controlPt,endPt,T) {
    var x = Math.pow(1-T,2) * startPt.x + 2 * (1-T) * T * controlPt.x + Math.pow(T,2) * endPt.x; 
    var y = Math.pow(1-T,2) * startPt.y + 2 * (1-T) * T * controlPt.y + Math.pow(T,2) * endPt.y; 
    return( {x:x,y:y} );
}

So you could plot circles along the quadratic curve like this: http://jsfiddle.net/m1erickson/j79sK/

enter image description here

This code example uses html canvas instead of the KineticJS library, but you can easily "new up" a Kinetic.Circle at the points where this example does context.arc

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>
<script>
$(function(){

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

    var startPoint={x:50,y:150};
    var controlPoint={x:125,y:20};
    var endPoint={x:200,y:150};

    ctx.beginPath();
    ctx.moveTo(startPoint.x,startPoint.y);
    ctx.quadraticCurveTo(controlPoint.x,controlPoint.y,endPoint.x,endPoint.y);
    ctx.stroke();

    for(var t=0;t<101;t+=5){
        var point=getQuadraticBezierXYatT(startPoint,controlPoint,endPoint,t/100);
        ctx.beginPath();
        ctx.arc(point.x,point.y,3,0,Math.PI*2);
        ctx.closePath();
        ctx.fillStyle=randomColor();
        ctx.fill();
    }

    function getQuadraticBezierXYatT(startPt,controlPt,endPt,T) {
        var x = Math.pow(1-T,2) * startPt.x + 2 * (1-T) * T * controlPt.x + Math.pow(T,2) * endPt.x; 
        var y = Math.pow(1-T,2) * startPt.y + 2 * (1-T) * T * controlPt.y + Math.pow(T,2) * endPt.y; 
        return( {x:x,y:y} );
    }

    function randomColor(){ 
        return('#'+Math.floor(Math.random()*16777215).toString(16));
    }

}); // end $(function(){});
</script>
</head>
<body>
    <button id="test">Test</button><br>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>

Upvotes: 4

KaliedaRik
KaliedaRik

Reputation: 388

Yes ... but it is a huge amount of work to do this in raw JavaScript. The simplest way to tackle it is to use a JavaScript library for manipulating the HTML Canvas element - there's dozens of them out there: Current State of Javascript Canvas Libraries?.

Here's my attempt: http://codepen.io/kaliedarik/pen/imxtf

(disclaimer: I wrote Scrawl.js)

Upvotes: 0

Related Questions