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-name: move-x, move-y;
animation-duration: 1s;
animation-iteration-count: infinite;
animation-timing-function:
cubic-bezier(
calc(1 / 3), calc((var(--p1x) - var(--p0x)) / (var(--p3x) - var(--p0x))),
calc(2 / 3), calc((var(--p2x) - var(--p0x)) / (var(--p3x) - var(--p0x)))),
cubic-bezier(
calc(1 / 3), calc((var(--p1y) - var(--p0y)) / (var(--p3y) - var(--p0y))),
calc(2 / 3), calc((var(--p2y) - var(--p0y)) / (var(--p3y) - var(--p0y))));
}
:root {
--p0x: 50;
--p0y: 100;
--p1x: 330;
--p1y: -250;
--p2x: 390;
--p2y: 350;
--p3x: 30;
--p3y: 50;
--debug: calc((var(--p1x) - var(--p0x)) / (var(--p3x) - var(--p0x)));
}
@keyframes move-x {
from { left: calc(1px * var(--p0x) - 4px); }
to { left: calc(1px * var(--p3x) - 4px); }
}
@keyframes move-y {
from { top: calc(1px * var(--p0y) - 4px); }
to { top: calc(1px * var(--p3y) - 4px); }
}
@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 = 100;
var xca = 250;
var yca = 50;
var xb = 30;
var yb = 50;
var xcb = 150;
var ycb = 150;
var WIDTH = 700;
var HEIGHT = 400;
var dragok = false;
var pointA = false;
var pointControlA = false;
var pointB = false;
var pointControlB = 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(xca - 5, yca - 5, 10, 10);
rect(xcb - 5, ycb - 5, 10, 10);
lerp(xa, ya, xca, yca);
lerp(xb, yb, xcb, ycb);
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.bezierCurveTo(xca,yca,xcb,ycb,xb,yb);
ctx.stroke();
const rootElement = document.querySelector(':root');
rootElement.style.setProperty('--p0x', xa);
rootElement.style.setProperty('--p0y', ya);
rootElement.style.setProperty('--p1x', xca);
rootElement.style.setProperty('--p1y', yca);
rootElement.style.setProperty('--p2x', xcb);
rootElement.style.setProperty('--p2y', ycb);
rootElement.style.setProperty('--p3x', xb);
rootElement.style.setProperty('--p3y', yb);
}
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 (pointControlA){
xca = e.pageX - canvas.offsetLeft;
yca = e.pageY - canvas.offsetTop;
} else if (pointControlB){
xcb = e.pageX - canvas.offsetLeft;
ycb = e.pageY - canvas.offsetTop;
}
}
}
function myDown(e){
/*var debugX = e.pageX - 5 - canvas.offsetLeft;
var debugY = e.pageY -5 - canvas.offsetTop;
console.log('x '+debugX+' y '+debugY);*/
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 < xca + 5 + canvas.offsetLeft && e.pageX > xca - 5 +
canvas.offsetLeft && e.pageY < yca + 5 + canvas.offsetTop &&
e.pageY > yca -5 + canvas.offsetTop){
xca = e.pageX - canvas.offsetLeft;
yca = e.pageY - canvas.offsetTop;
dragok = true;
pointControlA = true;
canvas.onmousemove = myMove;
} else if (e.pageX < xcb + 5 + canvas.offsetLeft && e.pageX > xcb - 5 +
canvas.offsetLeft && e.pageY < ycb + 5 + canvas.offsetTop &&
e.pageY > ycb -5 + canvas.offsetTop){
xcb = e.pageX - canvas.offsetLeft;
ycb = e.pageY - canvas.offsetTop;
dragok = true;
pointControlB = true;
canvas.onmousemove = myMove;
}
}
function myUp(){
dragok = false;
pointA = false;
pointControlA = false;
pointB = false;
pointControlB = false;
canvas.onmousemove = null;
}
init();
canvas.onmousedown = myDown;
canvas.onmouseup = myUp;
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.