JSFiddle - React, Tailwind, and code Playground
HTML
<h4>Gradient with transparency 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
var step_size = 100/18;
for (var t = 0; t <= 100 + 0.1; t += step_size) {
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;
var overlap = 0.2;
var outside_color = 'rgba(255,0,0,0.0)';
var inside_color = 'rgba(255,0,0,0.7)';
// draw a gradient-stroked line tangent to each point on the curve
var line_width = 40;
var half_width = line_width/2;
for (var i = 0; i < points.length - 1; i++) {
var x1 = points[i].x, y1 = points[i].y;
var x2 = points[i+1].x, y2 = points[i+1].y;
var angle1 = points[i].angle, angle2 = points[i+1].angle;
var midangle = (angle1 + angle2)/ 2;
// calc the topside and bottomside points of the tangent line
var gradientOffsetX1 = x1 + half_width * Math.cos(midangle);
var gradientOffsetY1 = y1 + half_width * Math.sin(midangle);
var gradientOffsetX2 = x1 + half_width * Math.cos(midangle - PI);
var gradientOffsetY2 = y1 + half_width *...