JSFiddle - React, Tailwind, and code Playground
by mvasilkov
HTML
<canvas></canvas>
CSS
body {
background: #fbfbfb;
margin: 0;
overflow: hidden;
}
canvas {
background: #000;
display: block;
left: 50%;
margin: -250px 0 0 -250px;
position: absolute;
top: 50%;
}
JavaScript
/* https://github.com/mvasilkov/new-year-fir-tree */
if (typeof requestAnimationFrame != 'function') {
['moz', 'webkit', 'ms'].some(function (p) {
var f = this[p + 'RequestAnimationFrame']
return typeof f == 'function'? (requestAnimationFrame = f): false
}) || (requestAnimationFrame = function (f) {
return setTimeout(f, 0)
})
}
(function (canvas) {
/* Settings */
var thetaEnd = 6 * Math.PI,
lineSpacing = 1 / 30,
lineLength = 0.5 * lineSpacing,
rate = 1 / (2 * Math.PI),
factor = rate / 3,
cycle = 200,
opacityMin = 0.69,
opacityDif = 48,
scene = [],
/* Rendering */
offsetX = 250,
offsetY = 310,
scaleX = 400,
scaleY = 400,
camX = 0,
camY = 2,
camZ = -3,
cSize = 500,
c = canvas.getContext('2d')
canvas.width = canvas.height = cSize
c.lineWidth = 1.44
scene.push(new Coil({ color: '255,0,0', theta0: Math.PI }))
scene.push(new Coil({ color: '100,200,255' }))
requestAnimationFrame(paint)
function paint() {
var offset = 1 - Date.now() / cycle % 1, i = 0
requestAnimationFrame(paint)
c.clearRect(0, 0, cSize, cSize)
for (; i < scene.length; ++i)
scene[i].paint(offset)
}
function project(point) {
return [offsetX + scaleX * (point[0] - camX) / -(point[2] + camZ),
offsetY + scaleY * (point[1] - camY) / -(point[2] + camZ)]
}
function clamp(val, a, b) {
return (val < a)? a: (val > b)? b: val
}
function Coil(options) {
this.color = options.color || '255,255,255'
this.theta0 = options.theta0 || 0
this.lineSpacing = options.lineSpacing || lineSpacing
this.lineLength = options.lineLength || lineLength
this.rate = options.rate || rate
this.factor = options.factor || factor
...