<div class="container">
<div class="box">
<canvas></canvas>
<p>t = <span class="text"></span></p>
</div>
</div>
.container {
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.box {
position: relative;
border: 1px solid #ccc;
padding: 30px;
}
p {
position: absolute;
top: 30px;
left: 30px;
}
canvas {
display: block;
}
View Compiled
const T_SIZE = 100
const WIDTH = 200
const HEIGHT = 200
const PADDING = 5
const P0 = { x: 0, y: 0 }
const P3 = { x: 1, y: 1 }
class Canvas {
constructor(el) {
this.el = el
this.ctx = el.getContext('2d')
this.el.width = WIDTH
this.el.height = HEIGHT
this.ctx.strokeStyle = '#444'
this.ctx.lineWidth = 2
this.points = []
}
addPoint(normalizedX, normalizedY) {
const x = PADDING + normalizedX * (WIDTH - PADDING * 2)
const y = PADDING + (1 - normalizedY) * (HEIGHT - PADDING * 2)
this.points.push({ x, y })
}
clearPoints() {
this.points = []
}
draw() {
this.ctx.beginPath()
this.points.forEach(({ x, y }, i) => {
if (i === 0) {
this.ctx.moveTo(x, y)
} else {
this.ctx.lineTo(x, y)
}
})
this.ctx.stroke()
}
clear() {
this.ctx.clearRect(0, 0, WIDTH, HEIGHT)
}
}
class Bezier {
constructor(p1, p2) {
this.p1 = p1
this.p2 = p2
}
calc(t) {
return {
x: Math.pow(1 - t, 3) * P0.x + 3 * Math.pow(1 - t, 2) * t * this.p1.x + 3 * (1 - t) * Math.pow(t, 2) * this.p2.x + Math.pow(t, 3) * P3.x,
y: Math.pow(1 - t, 3) * P0.y + 3 * Math.pow(1 - t, 2) * t * this.p1.y + 3 * (1 - t) * Math.pow(t, 2) * this.p2.y + Math.pow(t, 3) * P3.y
}
}
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms))
}
function round(val, digit = 2) {
return Math.round(val * Math.pow(10, digit)) / Math.pow(10, digit)
}
async function main() {
const p1 = { x: 0.76, y: 0 }
const p2 = { x: 0.24, y: 1 }
const bezier = new Bezier(p1, p2)
const canvas = new Canvas(document.querySelector('canvas'))
const text = document.querySelector('.text')
const drawBezier = async () => {
for (let i = 0; i < T_SIZE; i++) {
const t = i / (T_SIZE - 1)
const { x, y } = bezier.calc(t)
canvas.addPoint(x, y)
canvas.clear()
canvas.draw()
text.textContent = round(t)
await sleep(16)
}
}
const loop = async () => {
canvas.clearPoints()
await drawBezier()
await sleep(800)
loop()
}
loop()
}
main()
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.