1
votes

How could I draw 2D bezier curve with custom width - something like a ribbon? For a specific reason just setting the lineWidth is not enough.

Is there a library I could use? I've googled a lot but did not find anything useful.

EDIT: my question is duplicate of Outline of cubic bezier curve stroke and potentially How to offset a cubic bezier curve?

1
When you say "ribbon", Are you wanting a Bezier curve with a variable width?markE
nope, I meant a bezeir curve with an constant offset.daniel.sedlacek

1 Answers

2
votes

Here is a combination of beziers used to form single Bezier shapes.

enter image description here

Here is code and a Fiddle: http://jsfiddle.net/m1erickson/rCMdX/

<!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 canvas1=document.getElementById("canvas1");
    var ctx1=canvas1.getContext("2d");
    var canvas2=document.getElementById("canvas2");
    var ctx2=canvas2.getContext("2d");

    drawUniformRibbon(50,50,100,35,175,175,350,100,8);
    drawVariableRibbon(50,50,75,25,175,175,350,100,8,18);

    function drawUniformRibbon(x1,y1,cx1,cy1,cx2,cy2,x2,y2,width){
      ctx1.fillStyle = "red";  
      ctx1.beginPath();  
      ctx1.moveTo(x1, y1-width);  
      ctx1.bezierCurveTo(cx1, cy1, cx2, cy2, x2, y2+width);
      ctx1.lineTo(x2, y2+width*2);  
      ctx1.bezierCurveTo(cx2, cy2+width, cx1, cy1+width, x1, y1);
      ctx1.lineTo(x1, y1);
      ctx1.closePath();  
      ctx1.fill();
      ctx1.stroke(); 
    }

    function drawVariableRibbon(x1,y1,cx1,cy1,cx2,cy2,x2,y2,startWidth,endWidth){
      ctx2.fillStyle = "yellow";  
      ctx2.beginPath();  
      ctx2.moveTo(x1, y1-startWidth);  
      ctx2.bezierCurveTo(cx1, cy1, cx2, cy2, x2, y2);
      ctx2.lineTo(x2, y2+endWidth);  
      ctx2.bezierCurveTo(cx2, cy2, cx1, cy1, x1, y1+startWidth);
      ctx2.lineTo(x1, y1);
      ctx2.closePath();  
      ctx2.fill();
      ctx2.stroke(); 
    }

}); // end $(function(){});
</script>

</head>

<body>
    <canvas id="canvas1" width=400 height=200></canvas><br/>
    <canvas id="canvas2" width=400 height=200></canvas>
</body>
</html>