JSFiddle - React, Tailwind, and code Playground
by neosoyn
HTML
<h4>Creating a gradient running across a path</h4>
<canvas id="canvas" width=300 height=300></canvas>
CSS
body {
background-color: ivory;
}
#canvas {
border:1px solid red;
}
JavaScript
// canvas related variables
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
// variables defining a cubic bezier curve
var PI2 = Math.PI * 2;
var s = {
x: 20,
y: 30
};
var c1 = {
x: 200,
y: 40
};
var c2 = {
x: 40,
y: 200
};
var e = {
x: 270,
y: 220
};
// an array of points plotted along the bezier curve
var points = [];
// we use PI often so put it in a variable
var PI = Math.PI;
// plot 400 points along the curve
// and also calculate the angle of the curve at that point
for (var t = 0; t <= 100; t += 0.25) {
var T = t / 100;
// plot a point on the curve
var pos = getCubicBezierXYatT(s, c1, c2, e, T);
// calculate the tangent angle of the curve at that point
var tx = bezierTangent(s.x, c1.x, c2.x, e.x, T);
var ty = bezierTangent(s.y, c1.y, c2.y, e.y, T);
var a = Math.atan2(ty, tx) - PI / 2;
// save the x/y position of the point and the tangent angle
// in the points array
points.push({
x: pos.x,
y: pos.y,
angle: a
});
}
// Note: increase the lineWidth if
// the gradient has noticable gaps
ctx.lineWidth = 2;
// draw a gradient-stroked line tangent to each point on the curve
for (var i = 0; i < points.length; i++) {
// calc the topside and bottomside points of the tangent line
var offX1 = points[i].x + 20 * Math.cos(points[i].angle);
var offY1 = points[i].y + 20 * Math.sin(points[i].angle);
var offX2 = points[i].x + 20 * Math.cos(points[i].angle - PI);
var offY2 = points[i].y + 20 * Math.sin(points[i].angle - PI);
// create a gradient stretching between
// the calculated top & bottom points
var gradient = ctx.createLinearGradient(offX1, offY1, offX2, offY2);
gradient.addColorStop(0.00, 'red');
gradient.addColorStop(1 / 6, 'orange');
gradient.addColorStop(2 / 6, 'yellow');
gradient.addColorStop(3 / 6, 'green')
gradient.addColorStop(4 / 6, 'aqua');
...