Reputation: 23
I am trying to make an irregular curve line for the progress graph to show on my website. I've tried it using jQuery and I got sin wave successfully but I want to achieve an irregular wave line like shown in the image below. How can I achieve it?
See the following image. Sample image of what I want
html code
<canvas height="500" width="600" id="my_canvas"></canvas>
jQuery Code
var my_canvas=$('#my_canvas').get(0);
var gctx = my_canvas.getContext("2d");
gctx.stroke();
gctx.beginPath();
gctx.moveTo(10, 125);
gctx.lineWidth=1;
gctx.strokeStyle= '#f00040';
var x = [];
var y = [];
for (var angle = 0; angle <590; angle+=1){
gctx.lineJoin = 'round';
y.push(125 - 120*( Math.sin(( Math.PI/180 ) * angle)));
x.push(10 + angle);
gctx.lineTo((10 + angle),((125 - 120*( Math.sin(( Math.PI/180 ) *
angle)))));
}
gctx.stroke();
Upvotes: 1
Views: 406
Reputation: 33024
This is how I would do it: In order to draw the curve I need a set of points. I will use quadratic bezier curve where the points (except the first and the last) are control points. Since apparently you need to animate the stroke I've done it using SVG. For the animation I'm using CSS as explained here: How SVG Line Animation Works
//An array of points used to draw the curve
let points = [
{
x: 10,
y: 24
},
{
x: 70,
y: 110
},
{
x: 117,
y: 10
},
{
x: 130,
y: 142
},
{
x: 200,
y: 70
},
{
x: 270,
y: 143
},
{
x: 320,
y: 24
}
];
// a function that draws the curve using the points as control points
function drawCurve(points) {
//find the first midpoint and move to it
var p = {};
p.x = points[0].x;
p.y = points[0].y;
let d = `M${p.x}, ${p.y}`;
//curve through the rest, stopping at each midpoint
for (var i = 0; i < points.length - 2; i++) {
var mp = {};
mp.x = (points[i].x + points[i + 1].x) / 2;
mp.y = (points[i].y + points[i + 1].y) / 2;
d += `Q${points[i].x},${points[i].y},${mp.x},${mp.y}`;
}
//curve through the last point, back to the first midpoint
d += `Q${points[points.length - 2].x},${points[points.length - 2].y}, ${
points[points.length - 1].x
},${points[points.length - 1].y}`;
track.setAttributeNS(null, "d", d);
//for the animation
//1. get the total path length
let pathLength = track.getTotalLength();
//2. set the stroke-dasharray and the stroke-dashoffset for the animation
theUse.style.strokeDasharray = pathLength;
theUse.style.strokeDashoffset = pathLength;
}
drawCurve(points);
function randomIntFromInterval(mn, mx) {
return ~~(Math.random() * (mx - mn + 1) + mn);
}
#base{
stroke:#ccc;
stroke-width:5px;
fill:none;
}
#theUse{
stroke:black;
stroke-width:1px;
fill:none;
animation: dash 5s linear forwards;
}
@keyframes dash {
to {
stroke-dashoffset: 0;
}
}
<svg viewBox="0 0 330 200" id="svg">
<defs>
<path id="track" /></defs>
<use xlink:href="#track" id="base" />
<use xlink:href="#track" id="theUse" />
</svg>
Upvotes: 2