JSFiddle - React, Tailwind, and code Playground

by jcubed111

HTML

<canvas width=1000 height=800 id='canvas'></canvas>

<div id='sliders'>
<input type="range" id="0" min="-5" max="5" step="0.01" value="0">
<input type="range" id="1" min="-5" max="5" step="0.01" value="0">
<input type="range" id="2" min="-5" max="5" step="0.01" value="0">
<input type="range" id="3" min="-5" max="5" step="0.01" value="0">
<input type="range" id="4" min="-5" max="5" step="0.01" value="0">
<input type="range" id="5" min="-5" max="5" step="0.01" value="0">
<input type="range" id="6" min="-5" max="5" step="0.01" value="0">
<input type="range" id="7" min="-5" max="5" step="0.01" value="0">
<input type="range" id="8" min="-5" max="5" step="0.01" value="0">
<input type="range" id="9" min="-5" max="5" step="0.01" value="0">
<input type="range" id="10" min="-5" max="5" step="0.01" value="0">
<input type="range" id="11" min="-5" max="5" step="0.01" value="0">
<input type="range" id="12" min="-5" max="5" step="0.01" value="0">
<input type="range" id="13" min="-5" max="5" step="0.01" value="0">
<input type="range" id="14" min="-5" max="5" step="0.01" value="0">
<input type="range" id="15" min="-5" max="5" step="0.01" value="0">
<input type="range" id="16" min="-5" max="5" step="0.01" value="0">
<input type="range" id="17" min="-5" max="5" step="0.01" value="0">
<input type="range" id="18" min="-5" max="5" step="0.01" value="0">
<input type="range" id="19" min="-5" max="5" step="0.01" value="0">
<input type="range" id="20" min="-5" max="5" step="0.01" value="0">
<input type="range" id="21" min="-5" max="5" step="0.01" value="0">
<input type="range" id="22" min="-5" max="5" step="0.01" value="0">
<input type="range" id="23" min="-5" max="5" step="0.01" value="0">
<input type="range" id="24" min="-5" max="5" step="0.01" value="0">
<input type="range" id="25" min="-5" max="5" step="0.01" value="0">
<input type="range" id="26" min="-5" max="5" step="0.01" value="0">
<input type="range" id="27" min="-5" max="5" step="0.01" value="0">
<input type="range" id="28"...

SCSS

canvas{
	background: #fff;
}

#sliders{
	position: absolute;
	left: 0;
	top: 0;
	bottom: 0;
	padding: 10px;
	background: transparent;
	
	input{
		display: block;
		width: 300px;
	}
}

JavaScript

"use strict";
var ctx = document.getElementById('canvas').getContext('2d');
ctx.transform(1, 0, 0, -1, 0, document.getElementById('canvas').height)
ctx.scale(100, 100);


var curveValues = [];

$('input').on('input', function(event) {
	curveValues[+event.target.id] = +event.target.value;
	draw();
});
$('input').each(i => curveValues[i] = 0);

function curveAtTime(t) {
    t *= 2;
	var a = curveValues[~~t];
	var b = curveValues[~~t+1] - a;
	t %= 1;
	return a + b*(3*t*t - 2*t*t*t);
}

function draw() {
	ctx.clearRect(0, 0, 500, 500);
	
	ctx.beginPath();
	ctx.lineWidth = 0.01;
	
	var pos = {
		x: 6,
		y: 1,
	};
	var dir = {
		x: 0,
		y: 1,
	};

	ctx.moveTo(pos.x, pos.y);
	let step = 1/20;
	for(var t=0; t < curveValues.length/2 - 1; t+=step) {
		//let rot = 1 - 0.5*t;
		let rot = curveAtTime(t);
		// move
		pos.x += dir.x * step * 0.5*Math.PI;
		pos.y += dir.y * step * 0.5*Math.PI;

		ctx.lineTo(pos.x, pos.y);
		
		let width = 0.7/(t+3);
		ctx.lineTo(pos.x + dir.y*width, pos.y - dir.x*width);
		ctx.lineTo(pos.x - dir.y*width, pos.y + dir.x*width);

		// rotate
		let dTheta = rot * step * 0.5*Math.PI;
		dir = {
			x: dir.x * Math.cos(dTheta) - dir.y * Math.sin(dTheta),
			y: dir.x * Math.sin(dTheta) + dir.y * Math.cos(dTheta)
		};
	}
	ctx.stroke();
}

draw();