div(id='container')
  canvas(id='bezier', class='canvas', width='600', height='400')
  - for (let i = 0; i < 11; ++i)
    div(id='box'+i,class='box')
View Compiled
body { background-color:#000; overflow: hidden; }
body, html { height: 100%; width: 100%; margin: 0; padding: 0; }
.canvas { position:relative; margin:auto; top:0; left:0; }
#container { position: absolute; }
.box {
  position: absolute;
  pointer-events: none;
  top: -4px; left: -4px;
  height: 8px; width: 8px;
  background-color: red;
  animation: bezier 1s linear infinite;
  transform: translate3d(var(--p5x), var(--p5y), 0);
}

@for $i from 3 to 6 {
  @property --p#{$i}x {
    syntax: '<length>';
    inherits: false;
    initial-value: 0px;
  }
  @property --p#{$i}y {
    syntax: '<length>';
    inherits: false;
    initial-value: 0px;
  }
}
:root {
  --p0x: 50px;
  --p0y: 200px;
  --p1x: 200px;
  --p1y: 40px;
  --p2x: 350px;
  --p2y: 100px;
}
@keyframes bezier {
  from { --p3x: var(--p0x); --p3y: var(--p0y); }
  to { --p3x: var(--p1x); --p3y: var(--p1y); }
  from { --p4x: var(--p1x); --p4y: var(--p1y); }
  to { --p4x: var(--p2x); --p4y: var(--p2y); }
  from { --p5x: var(--p3x); --p5y: var(--p3y); }
  to { --p5x: var(--p4x); --p5y: var(--p4y); }
}

@for $i from 1 to 11 {
  #box#{$i} { animation-delay: #{-0.1 * $i}s; }
}
View Compiled
var canvas;
var ctx;
var xa = 50;
var ya = 200;
var xc = 200;
var yc = 40;
var xb = 350;
var yb = 100;
var WIDTH = 700;
var HEIGHT = 400;
var dragok = false;
var pointA = false;
var pointControl = false;
var pointB = false;

function rect(x,y,w,h) {
 ctx.beginPath();
 ctx.rect(x,y,w,h);
 ctx.closePath();
 ctx.fill();
}

function clear() {
 ctx.clearRect(0, 0, WIDTH, HEIGHT);
}

function init() {
 canvas = document.getElementById("bezier");
 ctx = canvas.getContext("2d");
 canvas.setAttribute('width', WIDTH);
 canvas.setAttribute('height', HEIGHT);
 return setInterval(draw, 10);
}

function draw() {
 clear();
 ctx.fillStyle = "#FAF7F8";
 rect(0,0,WIDTH,HEIGHT);
 ctx.fillStyle = "#444444";
 rect(xa - 5, ya - 5, 10, 10);
 rect(xb - 5, yb - 5, 10, 10);
 ctx.fillStyle = "#0095cd"; 
 rect(xc - 5, yc - 5, 10, 10);
 
  lerp(xa, ya, xc, yc);
  lerp(xb, yb, xc, yc);
  
  bezier();
}

function lerp(pAx, pAy, pBx, pBy){
  ctx.strokeStyle = "#0095cd";
  ctx.beginPath();
  ctx.moveTo(pAx,pAy);
  ctx.lineTo(pBx,pBy);
  ctx.stroke();
}

function bezier(){
  ctx.strokeStyle ="#000";
  ctx.beginPath();
  ctx.moveTo(xa,ya);
  ctx.quadraticCurveTo(xc,yc,xb,yb);
  ctx.stroke();
  
  const rootElement = document.querySelector(':root');
  rootElement.style.setProperty('--p0x', xa + 'px');
  rootElement.style.setProperty('--p0y', ya + 'px');
  rootElement.style.setProperty('--p1x', xc + 'px');
  rootElement.style.setProperty('--p1y', yc + 'px');
  rootElement.style.setProperty('--p2x', xb + 'px');
  rootElement.style.setProperty('--p2y', yb + 'px');
}
function myMove(e){
 if (dragok){
   if (pointA){
     xa = e.pageX - canvas.offsetLeft;
     ya = e.pageY - canvas.offsetTop;
   } else if (pointB){
     xb = e.pageX - canvas.offsetLeft;
     yb = e.pageY - canvas.offsetTop;
   } else if (pointControl){
     xc = e.pageX - canvas.offsetLeft;
     yc = e.pageY - canvas.offsetTop;
   }
 }
}

function myDown(e){
 if (e.pageX < xa + 5 + canvas.offsetLeft && e.pageX > xa - 5 +
 canvas.offsetLeft && e.pageY < ya + 5 + canvas.offsetTop &&
 e.pageY > ya -5 + canvas.offsetTop){
  xa = e.pageX - canvas.offsetLeft;
  ya = e.pageY - canvas.offsetTop;
  dragok = true;
  pointA = true;
  canvas.onmousemove = myMove;
 } else if (e.pageX < xb + 5 + canvas.offsetLeft && e.pageX > xb - 5 +
 canvas.offsetLeft && e.pageY < yb + 5 + canvas.offsetTop &&
 e.pageY > yb -5 + canvas.offsetTop){
  xb = e.pageX - canvas.offsetLeft;
  yb = e.pageY - canvas.offsetTop;
  dragok = true;
  pointB = true;
  canvas.onmousemove = myMove;
 } else if (e.pageX < xc + 5 + canvas.offsetLeft && e.pageX > xc - 5 +
 canvas.offsetLeft && e.pageY < yc + 5 + canvas.offsetTop &&
 e.pageY > yc -5 + canvas.offsetTop){
  xc = e.pageX - canvas.offsetLeft;
  yc = e.pageY - canvas.offsetTop;
  dragok = true;
  pointControl = true;
  canvas.onmousemove = myMove;
 }
}

function myUp(){
 dragok = false;
 pointA = false;
 pointControl = false;
 pointB = false;
 canvas.onmousemove = null;
}

init();
canvas.onmousedown = myDown;
canvas.onmouseup = myUp;

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.