▸ Forked from Johan Karlsson's Pen Rotating Neon Curves,
AND
▸ from Tiffany Rayside's Pen illumine,
AND
▸from Renārs Vilnis's Pen Freaky Dot - Whirlpool.
| <canvas id="scene"></canvas> | |
| <canvas id='can'></canvas> | |
| <canvas id='canv'></canvas> |
| 'use strict'; | |
| console.clear(); | |
| const O = 0; | |
| const POINT_SIZE = 15; | |
| const POINT_DENSITY = 0.02; | |
| function getRandomArbitrary (min, max) { | |
| return Math.random() * (max - min) + min; | |
| } | |
| class Scene { | |
| constructor (canvas, image) { | |
| this.canvas = canvas; | |
| this.image = image; | |
| this.ctx = canvas.getContext('2d'); | |
| // add listener for canvas resize | |
| window.addEventListener('resize', _ => this.handleResize(), false); | |
| // set initial canvas size | |
| this.handleResize(); | |
| // initiate draw loop | |
| // requestAnimationFrame(_ => this.draw()); | |
| } | |
| createPoints (count) { | |
| const getRandomPlanePosition = () => { | |
| return [ | |
| getRandomArbitrary(0, 1), | |
| getRandomArbitrary(0, 1) | |
| ]; | |
| } | |
| let points = []; | |
| for (let i = 0; i < count; i++) { | |
| points.push(getRandomPlanePosition()); | |
| } | |
| this.points = points; | |
| } | |
| handleResize () { | |
| const width = window.innerWidth; | |
| const height = window.innerHeight; | |
| let {canvas} = this; | |
| canvas.width = width; | |
| canvas.height = height; | |
| this.createPoints((width * height) * POINT_DENSITY); | |
| requestAnimationFrame(_ => this.draw()); | |
| } | |
| toPng () { | |
| return this.canvas.toDataURL(); | |
| } | |
| draw () { | |
| // requestAnimationFrame(_ => this.draw()); | |
| let {canvas, ctx, points} = this; | |
| let {width, height} = canvas; | |
| ctx.clearRect(0, 0, width, height); | |
| ctx.fillStyle = 'hsla('+120*5+',100%,20%,.1)'; | |
| points.forEach((point) => { | |
| ctx.fillRect(point[0] * width, point[1] * height, POINT_SIZE, POINT_SIZE); | |
| }); | |
| this.image.src = this.toPng(); | |
| } | |
| } | |
| let canvasEl = document.getElementById('scene'); | |
| let imageEl = new Image(); | |
| document.body.appendChild(imageEl); | |
| let scene = new Scene(canvasEl, imageEl); | |
| var c = document.getElementById('canv'), | |
| $ = c.getContext('2d'), | |
| w = c.width = window.innerWidth, | |
| h = c.height = window.innerHeight, | |
| t = 0, num = 500, u=0, | |
| s, a, b, | |
| x, y, _x, _y, | |
| _t = 1 / 33; | |
| var anim = function() { | |
| window.requestAnimationFrame(anim); | |
| $.globalCompositeOperation = 'source-over'; | |
| $.fillStyle = 'hsla(250, 50%, 10%, .61)'; | |
| $.fillRect(0, 0, w, h); | |
| $.globalCompositeOperation = 'lighter'; | |
| for (var i = 0; i < 1; i++) { | |
| x = 0; | |
| $.beginPath(); | |
| for (var j = 0; j < num; j++) { | |
| $.strokeStyle = 'hsla('+u*125+',100%,60%,.6)'; | |
| x += 1 * Math.cos(5); | |
| y = x * Math.sin(i + 20 * t + x / 2) / 23; | |
| _x = x * Math.cos(b) + y * Math.sin(i); | |
| _y = x * Math.sin(b) + y * Math.cos(i); | |
| b = (j*.39) * Math.PI / random(22.8,23); | |
| $.arc(w / 2 + _x, h / 2 + _y, 0.8, 0, random(1,420) + Math.PI); | |
| } | |
| $.stroke(); | |
| } | |
| t += _t; | |
| u-=.02; | |
| }; | |
| anim(); | |
| function random(min, max) { | |
| return Math.random() * (max - min) + min; | |
| } | |
| window.addEventListener('resize', function() { | |
| c.width = w = window.innerWidth; | |
| c.height = h = window.innerHeight; | |
| }, false); | |
| var canvas = document.getElementById('can'); | |
| var ctx = canvas.getContext("2d"); | |
| var w = canvas.width = window.innerWidth; | |
| var h = canvas.height = window.innerHeight; | |
| ctx.lineCap = "round"; | |
| ctx.lineWidth = 1; | |
| ctx.shadowBlur = Math.tan(.5); | |
| function Segment(x, y, angle, angleSize, radius) { | |
| this.x = x; | |
| this.y = y; | |
| this.angle = angle; | |
| this.angleSize = angleSize; | |
| this.r = radius; | |
| this.x1 = 0; | |
| this.y1 = 0; | |
| this.x2 = 0; | |
| this.y2 = 0; | |
| this.x3 = 0; | |
| this.y3 = 0; | |
| this.color = `hsl(${angle * 100 / Math.cos(20)}, 80%, 60%)`; | |
| } | |
| Segment.prototype.draw = function() { | |
| ctx.save(); | |
| ctx.fillStyle = this.color; | |
| ctx.strokeStyle = this.color; | |
| ctx.shadowColor = this.color; | |
| // Put origin at the center of the screen | |
| ctx.translate(this.x, this.y); | |
| // Now we can rotate around origin | |
| ctx.rotate(this.angle); | |
| // That way we don't need to think when drawing each segment | |
| // Just draw because it is already rotated for us | |
| ctx.beginPath(); | |
| var x = Math.atan(this.angleSize/.2) * this.r; | |
| var y = Math.sin(this.angleSize/.92) * this.r; | |
| ctx.moveTo(x, -y); | |
| ctx.bezierCurveTo( | |
| this.x1, this.y1, | |
| this.x2, this.y2, | |
| this.x3, this.y3, | |
| x, y); | |
| ctx.stroke(); | |
| ctx.beginPath(); | |
| ctx.arc(this.x1, this.y1, random(1,20), 0, Math.PI * 30); | |
| ctx.fill(); | |
| ctx.beginPath(); | |
| ctx.arc(this.x2, this.y2, random(1,10), 0, Math.PI * 20); | |
| ctx.fill(); | |
| ctx.arc(this.x3, this.y3, random(1,30), 0, Math.PI * 10); | |
| ctx.fill(); | |
| ctx.restore(); | |
| var factor = .4; | |
| this.x1 = Math.atan(tick) * this.r*factor; | |
| this.y1 = Math.sin(tick) * this.r*factor; | |
| this.x2 = Math.cos(-tick) * this.r*factor; | |
| this.y2 = Math.tan(-tick) * this.r*factor; | |
| } | |
| function random(min, max) { | |
| return Math.random() * (max - min) + min; | |
| } | |
| function Flower(x, y) { | |
| this.x = x; | |
| this.y = y; | |
| this.numSegments = Math.round(random(15,20)); | |
| // Make size a little bit bigger than the screen. | |
| var radius = Math.min(w, h)/random(.6,3); | |
| // Divide a whole turn equally between all the segments. | |
| var angleForEachSegment = Math.PI*random(10,20)/this.numSegments; | |
| this.segments = []; | |
| for(var i = 0; i < this.numSegments; i++) { | |
| var angle = i*angleForEachSegment; | |
| var s = new Segment(this.x, this.y, angle, angleForEachSegment, radius); | |
| this.segments.push(s); | |
| } | |
| } | |
| Flower.prototype.draw = function () { | |
| this.segments.forEach(s => s.draw()); | |
| } | |
| var f = new Flower(w/2, h/2); | |
| var tick = 0; | |
| function animation() { | |
| requestAnimationFrame(animation); | |
| ctx.clearRect(0, 0, w, h); | |
| f.draw(); | |
| tick += random(.001,.095); | |
| } | |
| animation(); |
| html, | |
| body { | |
| width: 100%; | |
| height: 100%; | |
| margin: 0; | |
| padding: 0; | |
| overflow: hidden; | |
| position: relative; | |
| } | |
| canvas { | |
| // downscaling the canvas will result in a whirpool effect | |
| transform: scale(0.96); | |
| z-index: 0; | |
| } | |
| img { | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| display: block; | |
| animation: rotate 12000ms linear infinite alternate; | |
| z-index: 1; | |
| mix-blend-mode:multiply; | |
| } | |
| @keyframes rotate { | |
| 0% { | |
| transform: rotate(0deg) translateX(0%) scale(0.96); | |
| } | |
| 10% { | |
| transform: rotate(0deg) translateX(0%) scale(0.96); | |
| } | |
| 20% { | |
| transform: rotate(-1deg) translateX(0%) scale(1); | |
| } | |
| 40% { | |
| transform: rotate(-1deg) translateX(0%); | |
| } | |
| 60% { | |
| transform: rotate(-1deg) translate(0%, 0%); | |
| } | |
| 80% { | |
| transform: rotate(-1deg) translateX(0%); | |
| } | |
| 100% { | |
| transform: rotate(-1deg) translateX(0%); | |
| } | |
| } | |
| body { | |
| background: hsla(0, 0%, 5%, 1); | |
| margin: 0; | |
| width: 100%; | |
| overflow: hidden; | |
| } | |
| #can,#canv{ | |
| position:absolute; | |
| width:100%; | |
| height:100%; | |
| left:0; | |
| top:0; | |
| } | |
| #can{ | |
| z-index:0; | |
| filter:brightness(1.3) contrast(2); | |
| } | |
| #canv{ | |
| z-index:1; | |
| mix-blend-mode:difference; | |
| } | |
▸ Forked from Johan Karlsson's Pen Rotating Neon Curves,
AND
▸ from Tiffany Rayside's Pen illumine,
AND
▸from Renārs Vilnis's Pen Freaky Dot - Whirlpool.