Created
November 28, 2021 07:57
-
-
Save LeetCodes/1df8d61f43997c45c8aa446c06c0fe6d to your computer and use it in GitHub Desktop.
NWaKvKx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<canvas id="canvas"></canvas> | |
<div id="hud"> | |
<div id="msg"></div> | |
<div id="algos"></div> | |
</div> | |
<div id="help"> | |
<div> | |
<h1>THE SPIRAL</h1> | |
<h4>Music Player / Visualizer v1.0.0</h4> | |
<h3>HELP SCREEN</h3> | |
</div> | |
<div class="text"> | |
<p>Not indicated for people susceptible to rapid flashing lights.</p> | |
<p>Best in <span class="keys">full-screen (press F key)</span> and accompanied by your favorite music playlist. If key commands aren't working click on screen first to focus it.</p> | |
<p>PLAYER: <span class="keys"> Click Add Track(s) to select one or multiple audio files</span> from your device (as long as the device supports it). The files get added to the playlist (scroll to see as only one gets shown to save space). Use the controls to play, stop etc. and click on the progress bar to skip.<span class="keys"> Use the P key to hide / show the player.</span> When a track is finished the next one will play and the playlist will loop.</p> | |
<p>VISUALIZER: Spiral will do it's own thing or you can <span class="keys">click, touch or press space bar to create a new spiral</span>. | |
Changes algorithm every 100 seconds by default, <span class="keys">press I key to increase </span> by 10 seconds or <span class="keys">D to decrease.</span> Or press <span class="keys">M to toggle between auto-changing and manual mode. </span> These will take effect after the next change.</p> | |
<p>The algorithm name is displayed on screen when it changes. <span class="keys">Press S for silence mode to toggle it on/off. </span> | |
<p><span class="help">H to open / close the help screen.</span></p> | |
</div> | |
</div> | |
<div id="player"> | |
<div id="picker"> | |
<label id="click-label" for="input">Add Track(s)</label> | |
<input type="file" id="input" accept="audio/*" multiple> | |
<ol id="playlist"> | |
</ol> | |
<div id="controls"> | |
<button id="prev"> | |
<ion-icon name="play-skip-back-outline"></ion-icon> | |
</button> | |
<button id="play"> | |
<ion-icon id="play-pause-icon" name="play-outline"></ion-icon> | |
</button> | |
<button id="stop"> | |
<ion-icon name="stop-outline"></ion-icon> | |
</button> | |
<button id="next"> | |
<ion-icon name="play-skip-forward-outline"></ion-icon> | |
</button> | |
</div> | |
</div> | |
<div id="progress"> | |
<progress id="progress-percent" max="100" value="0"></progress> | |
</div> | |
</div> | |
<audio id="audio"></audio> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CanvasRenderingContext2D.prototype.roundRect = function ( | |
x, | |
y, | |
width, | |
height, | |
radius, | |
fill, | |
stroke | |
) { | |
const cornerRadius = { | |
upperLeft: 0, | |
upperRight: 0, | |
lowerLeft: 0, | |
lowerRight: 0 | |
}; | |
if (typeof stroke == "undefined") { | |
stroke = true; | |
} | |
if (typeof radius === "object") { | |
for (let side in radius) { | |
cornerRadius[side] = radius[side]; | |
} | |
} | |
this.beginPath(); | |
this.moveTo(x + cornerRadius.upperLeft, y); | |
this.lineTo(x + width - cornerRadius.upperRight, y); | |
this.quadraticCurveTo(x + width, y, x + width, y + cornerRadius.upperRight); | |
this.lineTo(x + width, y + height - cornerRadius.lowerRight); | |
this.quadraticCurveTo( | |
x + width, | |
y + height, | |
x + width - cornerRadius.lowerRight, | |
y + height | |
); | |
this.lineTo(x + cornerRadius.lowerLeft, y + height); | |
this.quadraticCurveTo(x, y + height, x, y + height - cornerRadius.lowerLeft); | |
this.lineTo(x, y + cornerRadius.upperLeft); | |
this.quadraticCurveTo(x, y, x + cornerRadius.upperLeft, y); | |
this.closePath(); | |
if (stroke) { | |
this.stroke(); | |
} | |
if (fill) { | |
this.fill(); | |
} | |
}; | |
// DOM References | |
const canvas = document.querySelector("#canvas"); | |
const ctx = canvas.getContext("2d"); | |
const hud = document.querySelector("#hud"); | |
const msg = document.querySelector("#msg"); | |
const algosDisplay = document.querySelector("#algos"); | |
const help = document.querySelector("#help"); | |
// VARIABLES | |
// canvas to window size | |
let w = (canvas.width = window.innerWidth); | |
let h = (canvas.height = window.innerHeight); | |
// time-frame | |
let t = 0; | |
// for the animations | |
let stagger = 1; | |
let speed = 5; | |
// for repeats | |
let interval; | |
let regen; | |
let autoChange = 30; | |
let manual = false; | |
// hud messages | |
let silent = false; | |
let helpView = false; | |
let algoTimer; | |
let msgTimer; | |
// algorithms list | |
const ALGOS = [ | |
"epic-rays", | |
"abstractions", | |
"medusa", | |
"chillout", | |
"swirls", | |
"mirage", | |
"majestic", | |
"wormhole", | |
"irradiate", | |
"entropy", | |
"tripping", | |
"progression", | |
"aperture", | |
"upholstery", | |
"unfocused", | |
"rotunda", | |
"crayon-funnel", | |
"big-bangs", | |
"nazca", | |
"clutch", | |
"torus", | |
"shapeshifter", | |
"smooth", | |
"encoded", | |
"concentric", | |
"glow", | |
"blends", | |
"matter", | |
"seeds", | |
"onion", | |
"spheral", | |
"snakes-ladders", | |
"cornucopia", | |
"cornucopia2", | |
"crosshatch", | |
"networks", | |
"spikral", | |
"fruits", | |
"zentangles", | |
"typobrush", | |
"veils", | |
"harmonie", | |
"portals", | |
"sandala", | |
"ghostly-shapes", | |
"psycho-rainbow", | |
"hallucinate", | |
"hive", | |
"boxes", | |
"digital-art" | |
]; | |
// stores the last played algorithms | |
let LAST_ALGOS = []; | |
// choose a new algorithm that is not on the last x played | |
function chooseAlgos() { | |
let picks = ALGOS.filter((algo) => !LAST_ALGOS.includes(algo)); | |
let choose = picks[random(0, picks.length)]; | |
LAST_ALGOS.push(choose); | |
if (LAST_ALGOS.length > 20) LAST_ALGOS.shift(); | |
// setup the chosen algorithm | |
switch (choose) { | |
case "epic-rays": | |
displayAlgos("EPIC RAYS"); | |
ctx.save(); | |
runningAlgo = new EpicRays(); | |
runningAlgo.draw(); | |
break; | |
case "abstractions": | |
displayAlgos("ABSTRACTIONS"); | |
ctx.save(); | |
runningAlgo = new Abstractions(); | |
runningAlgo.draw(); | |
break; | |
case "medusa": | |
displayAlgos("MEDUSA"); | |
ctx.save(); | |
runningAlgo = new Medusa(); | |
runningAlgo.draw(); | |
break; | |
case "chillout": | |
displayAlgos("CHILL OUT"); | |
ctx.save(); | |
runningAlgo = new Chillout(); | |
runningAlgo.draw(); | |
break; | |
case "swirls": | |
displayAlgos("SWIRLS"); | |
ctx.save(); | |
runningAlgo = new Swirls(); | |
runningAlgo.draw(); | |
break; | |
case "mirage": | |
displayAlgos("MIRAGE"); | |
ctx.save(); | |
runningAlgo = new Mirage(); | |
runningAlgo.draw(); | |
break; | |
case "majestic": | |
displayAlgos("MAJESTIC"); | |
ctx.save(); | |
runningAlgo = new Majestic(); | |
runningAlgo.draw(); | |
break; | |
case "wormhole": | |
displayAlgos("WORMHOLE"); | |
ctx.save(); | |
runningAlgo = new Wormhole(); | |
runningAlgo.draw(); | |
break; | |
case "irradiate": | |
displayAlgos("IRRADIATE"); | |
ctx.save(); | |
runningAlgo = new Irradiate(); | |
runningAlgo.draw(); | |
break; | |
case "entropy": | |
displayAlgos("ENTROPY"); | |
ctx.save(); | |
runningAlgo = new Entropy(); | |
runningAlgo.draw(); | |
break; | |
case "tripping": | |
displayAlgos("TRIPPING"); | |
ctx.save(); | |
runningAlgo = new Tripping(); | |
runningAlgo.draw(); | |
break; | |
case "progression": | |
displayAlgos("PROGRESSION"); | |
ctx.save(); | |
runningAlgo = new Progression(); | |
runningAlgo.draw(); | |
break; | |
case "aperture": | |
displayAlgos("APERTURE"); | |
ctx.save(); | |
runningAlgo = new Aperture(); | |
runningAlgo.draw(); | |
break; | |
case "upholstery": | |
displayAlgos("UPHOLSTERY"); | |
ctx.save(); | |
runningAlgo = new Upholstery(); | |
runningAlgo.draw(); | |
break; | |
case "unfocused": | |
displayAlgos("UNFOCUSED"); | |
ctx.save(); | |
runningAlgo = new Unfocused(); | |
runningAlgo.draw(); | |
break; | |
case "rotunda": | |
displayAlgos("ROTUNDA"); | |
ctx.save(); | |
runningAlgo = new Rotunda(); | |
runningAlgo.draw(); | |
break; | |
case "crayon-funnel": | |
displayAlgos("CRAYON FUNNEL"); | |
ctx.save(); | |
runningAlgo = new CrayonFunnel(); | |
runningAlgo.draw(); | |
break; | |
case "big-bangs": | |
displayAlgos("BIG BANGS"); | |
ctx.save(); | |
runningAlgo = new BigBangs(); | |
runningAlgo.draw(); | |
break; | |
case "nazca": | |
displayAlgos("NAZCA"); | |
ctx.save(); | |
runningAlgo = new Nazca(); | |
runningAlgo.draw(); | |
break; | |
case "clutch": | |
displayAlgos("CLUTCH"); | |
ctx.save(); | |
runningAlgo = new Clutch(); | |
runningAlgo.draw(); | |
break; | |
case "torus": | |
displayAlgos("TORUS"); | |
ctx.save(); | |
runningAlgo = new Torus(); | |
runningAlgo.draw(); | |
break; | |
case "shapeshifter": | |
displayAlgos("SHAPESHIFTER"); | |
ctx.save(); | |
runningAlgo = new Shapeshifter(); | |
runningAlgo.draw(); | |
break; | |
case "smooth": | |
displayAlgos("SMOOTH"); | |
ctx.save(); | |
runningAlgo = new Smooth(); | |
runningAlgo.draw(); | |
break; | |
case "encoded": | |
displayAlgos("ENCODED"); | |
ctx.save(); | |
runningAlgo = new Encoded(); | |
runningAlgo.draw(); | |
break; | |
case "concentric": | |
displayAlgos("CONCENTRIC"); | |
ctx.save(); | |
runningAlgo = new Concentric(); | |
runningAlgo.draw(); | |
break; | |
case "glow": | |
displayAlgos("GLOW"); | |
ctx.save(); | |
runningAlgo = new Glow(); | |
runningAlgo.draw(); | |
break; | |
case "blends": | |
displayAlgos("BLENDS"); | |
ctx.save(); | |
runningAlgo = new Blends(); | |
runningAlgo.draw(); | |
break; | |
case "matter": | |
displayAlgos("MATTER"); | |
ctx.save(); | |
runningAlgo = new Matter(); | |
runningAlgo.draw(); | |
break; | |
case "seeds": | |
displayAlgos("SEEDS"); | |
ctx.save(); | |
runningAlgo = new Seeds(); | |
runningAlgo.draw(); | |
break; | |
case "onion": | |
displayAlgos("ONION"); | |
ctx.save(); | |
runningAlgo = new Onion(); | |
runningAlgo.draw(); | |
break; | |
case "spheral": | |
displayAlgos("SPHERAL"); | |
ctx.save(); | |
runningAlgo = new Spheral(); | |
runningAlgo.draw(); | |
break; | |
case "snakes-ladders": | |
displayAlgos("SNAKES 'N LADDERS"); | |
ctx.save(); | |
runningAlgo = new SnakesLadders(); | |
runningAlgo.draw(); | |
break; | |
case "cornucopia": | |
displayAlgos("CORNUCOPIA"); | |
ctx.save(); | |
runningAlgo = new Cornucopia(); | |
runningAlgo.draw(); | |
break; | |
case "cornucopia2": | |
displayAlgos("CORNUCOPIA 2"); | |
ctx.save(); | |
runningAlgo = new Cornucopia2(); | |
runningAlgo.draw(); | |
break; | |
case "crosshatch": | |
displayAlgos("CROSSHATCH"); | |
ctx.save(); | |
runningAlgo = new Crosshatch(); | |
runningAlgo.draw(); | |
break; | |
case "networks": | |
displayAlgos("NETWORKS"); | |
ctx.save(); | |
runningAlgo = new Networks(); | |
runningAlgo.draw(); | |
break; | |
case "spikral": | |
displayAlgos("SPIKRAL"); | |
ctx.save(); | |
runningAlgo = new Spikral(); | |
runningAlgo.draw(); | |
break; | |
case "fruits": | |
displayAlgos("FRUITS"); | |
ctx.save(); | |
runningAlgo = new Fruits(); | |
runningAlgo.draw(); | |
break; | |
case "zentangles": | |
displayAlgos("ZENTANGLES"); | |
ctx.save(); | |
runningAlgo = new Zentangles(); | |
runningAlgo.draw(); | |
break; | |
case "typobrush": | |
displayAlgos("TYPO BRUSH"); | |
ctx.save(); | |
runningAlgo = new Typobrush(); | |
runningAlgo.draw(); | |
break; | |
case "veils": | |
displayAlgos("VEILS"); | |
ctx.save(); | |
runningAlgo = new Veils(); | |
runningAlgo.draw(); | |
break; | |
case "harmonie": | |
displayAlgos("HARMONIE"); | |
ctx.save(); | |
runningAlgo = new Harmonie(); | |
runningAlgo.draw(); | |
break; | |
case "portals": | |
displayAlgos("PORTALS"); | |
ctx.save(); | |
runningAlgo = new Portals(); | |
runningAlgo.draw(); | |
break; | |
case "sandala": | |
displayAlgos("SANDALA"); | |
ctx.save(); | |
runningAlgo = new Sandala(); | |
runningAlgo.draw(); | |
break; | |
case "ghostly-shapes": | |
displayAlgos("GHOSTLY SHAPES"); | |
ctx.save(); | |
runningAlgo = new GhostlyShapes(); | |
runningAlgo.draw(); | |
break; | |
case "psycho-rainbow": | |
displayAlgos("PSYCHO RAINBOW"); | |
ctx.save(); | |
runningAlgo = new PsychoRainbow(); | |
runningAlgo.draw(); | |
break; | |
case "hallucinate": | |
displayAlgos("HALLUCINATE"); | |
ctx.save(); | |
runningAlgo = new Hallucinate(); | |
runningAlgo.draw(); | |
break; | |
case "hive": | |
displayAlgos("THE HIVE"); | |
ctx.save(); | |
runningAlgo = new Hive(); | |
runningAlgo.draw(); | |
break; | |
case "boxes": | |
displayAlgos("BOXES"); | |
ctx.save(); | |
runningAlgo = new Boxes(); | |
runningAlgo.draw(); | |
break; | |
case "digital-art": | |
displayAlgos("DIGITAL ART"); | |
ctx.save(); | |
runningAlgo = new DigitalArt(); | |
runningAlgo.draw(); | |
break; | |
} | |
} | |
// ALGORITHMS / SPIRALS CLASSES | |
class EpicRays { | |
constructor() { | |
this.pointAx = random(0, w); | |
this.pointAy = random(0, h); | |
this.pointBx = random(0, w); | |
this.pointBy = random(0, h); | |
this.pointCx = random(0, w); | |
this.pointCy = random(0, h); | |
this.rotations = [ | |
1, | |
2, | |
3, | |
4, | |
7, | |
8, | |
11, | |
13, | |
14, | |
16, | |
17, | |
19, | |
21, | |
22, | |
23, | |
26, | |
28, | |
29, | |
31, | |
32, | |
33, | |
34, | |
37, | |
38, | |
39, | |
41, | |
43 | |
]; | |
this.rotate = this.rotations[random(0, this.rotations.length)]; | |
ctx.strokeStyle = randomColor(40, 255, 0.25, 0.5); | |
speed = 3; | |
this.draw = () => { | |
if (t % speed === 0) { | |
stagger = stagger % 4; | |
if (stagger === 0) { | |
ctx.beginPath(); | |
ctx.moveTo(w / 2, h / 2); | |
ctx.lineTo(this.pointAx, this.pointAy); | |
ctx.stroke(); | |
} | |
if (stagger === 1) { | |
ctx.beginPath(); | |
ctx.moveTo(this.pointAx, this.pointAy); | |
ctx.lineTo(this.pointBx, this.pointBy); | |
ctx.stroke(); | |
} | |
if (stagger === 2) { | |
ctx.beginPath(); | |
ctx.moveTo(this.pointBx, this.pointBy); | |
ctx.lineTo(this.pointCx, this.pointCy); | |
ctx.stroke(); | |
} | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate((this.rotate * Math.PI) / 180); | |
ctx.translate(-w / 2, -h / 2); | |
stagger++; | |
t++; | |
if (t % (speed * 300) === 0) { | |
ctx.strokeStyle = randomColor(40, 255, 0.25, 0.5); | |
this.pointAx = random(0, w); | |
this.pointAy = random(0, h); | |
this.pointBx = random(0, w); | |
this.pointBy = random(0, h); | |
this.pointCx = random(0, w); | |
this.pointCy = random(0, h); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Abstractions { | |
constructor() { | |
this.pointAx = random(0, w); | |
this.pointAy = random(0, h); | |
this.pointCpAx = random(0, w); | |
this.pointCpAy = random(0, h); | |
this.pointBx = random(0, w); | |
this.pointBy = random(0, h); | |
this.pointCpBx = random(0, w); | |
this.pointCpBy = random(0, h); | |
this.pointCx = random(0, w); | |
this.pointCy = random(0, h); | |
this.pointCpCx = random(0, w); | |
this.pointCpCy = random(0, h); | |
this.rotations = [ | |
1, | |
2, | |
3, | |
4, | |
7, | |
8, | |
11, | |
13, | |
14, | |
16, | |
17, | |
19, | |
21, | |
22, | |
23, | |
26, | |
28, | |
29, | |
31, | |
32, | |
33, | |
34, | |
37, | |
38, | |
39, | |
41, | |
43 | |
]; | |
this.rotate = this.rotations[random(0, this.rotations.length)]; | |
speed = 3; | |
ctx.shadowColor = ctx.strokeStyle = randomColor(0, 255, 0.25, 0.45); | |
ctx.shadowBlur = 3; | |
this.draw = () => { | |
if (t % speed === 0) { | |
stagger = stagger % 4; | |
if (stagger === 0) { | |
ctx.beginPath(); | |
ctx.moveTo(this.pointCx, this.pointCy); | |
ctx.quadraticCurveTo( | |
this.pointCpAx, | |
this.pointCpAy, | |
this.pointAx, | |
this.pointAy | |
); | |
ctx.stroke(); | |
} | |
if (stagger === 1) { | |
ctx.beginPath(); | |
ctx.moveTo(this.pointAx, this.pointAy); | |
ctx.quadraticCurveTo( | |
this.pointCpBx, | |
this.pointCpBy, | |
this.pointBx, | |
this.pointBy | |
); | |
ctx.stroke(); | |
} | |
if (stagger === 2) { | |
ctx.beginPath(); | |
ctx.moveTo(this.pointBx, this.pointBy); | |
ctx.quadraticCurveTo( | |
this.pointCpCx, | |
this.pointCpCy, | |
this.pointCx, | |
this.pointCy | |
); | |
ctx.stroke(); | |
} | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate((this.rotate * Math.PI) / 180); | |
ctx.translate(-w / 2, -h / 2); | |
stagger++; | |
t++; | |
if (t % (speed * 180) === 0) { | |
ctx.shadowColor = ctx.strokeStyle = randomColor(0, 255, 0.25, 0.45); | |
this.pointAx = random(0, w); | |
this.pointAy = random(0, h); | |
this.pointCpAx = random(0, w); | |
this.pointCpAy = random(0, h); | |
this.pointBx = random(0, w); | |
this.pointBy = random(0, h); | |
this.pointCpBx = random(0, w); | |
this.pointCpBy = random(0, h); | |
this.pointCx = random(0, w); | |
this.pointCy = random(0, h); | |
this.pointCpCx = random(0, w); | |
this.pointCpCy = random(0, h); | |
this.rotate = this.rotations[random(0, this.rotations.length)]; | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Medusa { | |
constructor() { | |
this.pointAx = random(0, w); | |
this.pointAy = random(0, h); | |
this.pointCpAx = random(0, w); | |
this.pointCpAy = random(0, h); | |
this.pointBx = random(0, w); | |
this.pointBy = random(0, h); | |
this.pointCpBx = random(0, w); | |
this.pointCpBy = random(0, h); | |
this.pointCx = random(0, w); | |
this.pointCy = random(0, h); | |
this.pointCpCx = random(0, w); | |
this.pointCpCy = random(0, h); | |
this.rotate = random(1, 19); | |
ctx.strokeStyle = randomColor(0, 185, 0.3, 0.65); | |
speed = 3; | |
ctx.globalCompositeOperation = "overlay"; | |
this.draw = () => { | |
if (t % speed === 0) { | |
stagger = stagger % 4; | |
if (stagger === 0) { | |
ctx.beginPath(); | |
ctx.moveTo(this.pointCpCx, this.pointCpCy); | |
ctx.quadraticCurveTo( | |
this.pointCpAx, | |
this.pointCpAy, | |
this.pointAx++, | |
this.pointAy-- | |
); | |
ctx.stroke(); | |
} | |
if (stagger === 1) { | |
ctx.beginPath(); | |
ctx.moveTo(this.pointCpAx, this.pointCpAy); | |
ctx.quadraticCurveTo( | |
this.pointCpBx, | |
this.pointCpBy++, | |
this.pointBx, | |
this.pointBy | |
); | |
ctx.stroke(); | |
} | |
if (stagger === 2) { | |
ctx.beginPath(); | |
ctx.moveTo(this.pointCpBx, this.pointCpBy); | |
ctx.quadraticCurveTo( | |
this.pointCpCx--, | |
this.pointCpCy, | |
this.pointCx, | |
this.pointCy | |
); | |
ctx.stroke(); | |
} | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate((this.rotate++ * Math.PI) / 180); | |
ctx.translate(-w / 2, -h / 2); | |
stagger++; | |
t++; | |
if (t % (speed * 450) === 0) { | |
ctx.clearRect(-w, -h, 3 * w, 3 * h); | |
ctx.strokeStyle = randomColor(0, 185, 0.3, 0.65); | |
this.pointAx = random(0, w); | |
this.pointAy = random(0, h); | |
this.pointCpAx = random(0, w); | |
this.pointCpAy = random(0, h); | |
this.pointBx = random(0, w); | |
this.pointBy = random(0, h); | |
this.pointCpBx = random(0, w); | |
this.pointCpBy = random(0, h); | |
this.pointCx = random(0, w); | |
this.pointCy = random(0, h); | |
this.pointCpCx = random(0, w); | |
this.pointCpCy = random(0, h); | |
this.rotate = random(1, 19); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Chillout { | |
constructor() { | |
this.x1 = random(0, w); | |
this.y1 = random(0, h); | |
this.x2 = random(0, w); | |
this.y2 = random(0, h); | |
this.x3 = random(0, w); | |
this.y3 = random(0, h); | |
this.rotate = random(1, 10); | |
ctx.lineWidth = random(1, 5); | |
ctx.strokeStyle = randomColor(0, 255, 0.4, 1); | |
ctx.filter = "saturate(17.5%)"; | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.moveTo(this.x3, this.y3); | |
ctx.quadraticCurveTo(this.x2, this.y2, this.x1, this.y1); | |
ctx.stroke(); | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(this.rotate); | |
ctx.translate(-w / 2, -h / 2); | |
} | |
t++; | |
if (t % (speed * 80) === 0) { | |
this.x1 = random(0, w); | |
this.y1 = random(0, h); | |
this.x2 = random(0, w); | |
this.y2 = random(0, h); | |
this.x3 = random(0, w); | |
this.y3 = random(0, h); | |
ctx.beginPath(); | |
ctx.lineWidth = random(1, 5); | |
ctx.strokeStyle = randomColor(0, 255, 0.4, 1); | |
this.rotate = random(1, 10); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Swirls { | |
constructor() { | |
this.x1 = random(0, w); | |
this.y1 = random(0, h); | |
this.x2 = random(0, w); | |
this.y2 = random(0, h); | |
this.x3 = random(0, w); | |
this.y3 = random(0, h); | |
this.rotate = random(1, 10); | |
ctx.strokeStyle = randomColor(0, 255, 0.4, 0.7); | |
ctx.lineWidth = 0.1; | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.moveTo(this.x3, this.y3); | |
ctx.quadraticCurveTo(this.x2, this.y2, this.x1, this.y1); | |
ctx.stroke(); | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(this.rotate); | |
ctx.translate(-w / 2, -h / 2); | |
} | |
t++; | |
if (t % (speed * 240) === 0) { | |
this.x1 = random(0, w); | |
this.y1 = random(0, h); | |
this.x2 = random(0, w); | |
this.y2 = random(0, h); | |
this.x3 = random(0, w); | |
this.y3 = random(0, h); | |
ctx.beginPath(); | |
ctx.strokeStyle = randomColor(0, 255, 0.4, 0.7); | |
this.rotate = random(1, 10); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Mirage { | |
constructor() { | |
this.width = random(100, w); | |
this.height = random(100, h); | |
this.ul = random(10, 300); | |
this.ur = random(10, 300); | |
this.ll = random(10, 300); | |
this.lr = random(10, 300); | |
this.rotate = random(1, 50); | |
ctx.fillStyle = randomColor(0, 255, 0.01, 0.05); | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.roundRect( | |
w / 2 - this.width / 2, | |
h / 2 - this.height / 2, | |
this.width, | |
this.height, | |
{ | |
upperLeft: this.ul, | |
upperRight: this.ur, | |
lowerLeft: this.ll, | |
lowerRight: this.lr | |
}, | |
true, | |
false | |
); | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(this.rotate); | |
ctx.translate(-w / 2, -h / 2); | |
t++; | |
if (t % (speed * 200) === 0) { | |
ctx.fillRect(-w, -h, 3 * w, 3 * h); | |
this.width = random(100, w); | |
this.height = random(100, h); | |
this.ul = random(10, 300); | |
this.ur = random(10, 300); | |
this.ll = random(10, 300); | |
this.lr = random(10, 300); | |
this.rotate = random(1, 50); | |
ctx.fillStyle = randomColor(0, 255, 0.01, 0.05); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Majestic { | |
constructor() { | |
this.x = random(0, w); | |
this.y = random(0, h); | |
this.width = random(30, w); | |
this.height = random(30, h); | |
this.ul = random(10, w); | |
this.ur = random(10, h); | |
this.ll = random(10, h); | |
this.lr = random(10, w); | |
this.rotate = random(1, 359); | |
ctx.strokeStyle = randomColor(); | |
ctx.fillStyle = randomColor(0, 255, 0.01, 0.05); | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.roundRect( | |
this.x, | |
this.y, | |
this.width, | |
this.height, | |
{ | |
upperLeft: this.ul, | |
upperRight: this.ur, | |
lowerLeft: this.ll, | |
lowerRight: this.lr | |
}, | |
true, | |
true | |
); | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate((this.rotate * Math.PI) / 180); | |
ctx.translate(-w / 2, -h / 2); | |
t++; | |
if (t % (speed * 180) === 0) { | |
ctx.fillRect(-w, -h, 3 * w, 3 * h); | |
this.width = random(30, w); | |
this.height = random(30, h); | |
this.x = random(0, w); | |
this.y = random(0, h); | |
this.ul = random(10, w); | |
this.ur = random(10, h); | |
this.ll = random(10, h); | |
this.lr = random(10, w); | |
this.rotate = random(1, 359); | |
ctx.strokeStyle = randomColor(); | |
ctx.fillStyle = randomColor(0, 255, 0.01, 0.05); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Wormhole { | |
constructor() { | |
this.x = random(50, w - 50); | |
this.y = random(50, h - 50); | |
this.width = random(30, w); | |
this.height = random(30, h); | |
this.ul = random(10, 50); | |
this.ur = random(10, 50); | |
this.ll = random(10, 50); | |
this.lr = random(10, 50); | |
this.rotate = random(1, 44); | |
ctx.strokeStyle = randomColor(0, 255, 0.2, 0.5); | |
ctx.fillStyle = randomColor(0, 255, 0.01, 0.01); | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.roundRect( | |
this.x, | |
this.y, | |
this.width, | |
this.height, | |
{ | |
upperLeft: this.ul, | |
upperRight: this.ur, | |
lowerLeft: this.ll, | |
lowerRight: this.lr | |
}, | |
true, | |
true | |
); | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(this.rotate); | |
ctx.translate(-w / 2, -h / 2); | |
this.width++; | |
this.height++; | |
this.ul++; | |
this.ur++; | |
t++; | |
if (t % (speed * 360) === 0) { | |
this.width = random(30, w); | |
this.height = random(30, h); | |
this.x = random(50, w - 50); | |
this.y = random(50, h - 50); | |
this.ul = random(10, 50); | |
this.ur = random(10, 50); | |
this.ll = random(10, 50); | |
this.lr = random(10, 50); | |
this.rotate = random(1, 44); | |
ctx.strokeStyle = randomColor(0, 255, 0.2, 0.5); | |
ctx.fillStyle = randomColor(0, 255, 0.01, 0.01); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Irradiate { | |
constructor() { | |
this.width = random(50, w / 2); | |
this.height = random(50, h / 2); | |
this.rotate = random(1, 181); | |
this.ul = random(10, Math.min(w, h)); | |
this.ur = random(10, Math.min(w, h)); | |
this.ll = random(10, Math.min(w, h)); | |
this.lr = random(10, Math.min(w, h)); | |
ctx.strokeStyle = randomColor(0, 255, 0.33); | |
ctx.globalCompositeOperation = "hard-light"; | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.roundRect( | |
w / 2 - this.width / 2, | |
h / 2 - this.height / 2, | |
this.width, | |
this.height, | |
{ | |
upperLeft: this.ul, | |
upperRight: this.ur, | |
lowerLeft: this.ll, | |
lowerRight: this.lr | |
} | |
); | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(this.rotate); | |
ctx.translate(-w / 2, -h / 2); | |
t++; | |
if (t % (speed * 150) === 0) { | |
ctx.beginPath(); | |
this.width = random(50, w / 2); | |
this.height = random(50, h / 2); | |
this.rotate = random(1, 181); | |
this.ul = random(10, Math.min(w, h)); | |
this.ur = random(10, Math.min(w, h)); | |
this.ll = random(10, Math.min(w, h)); | |
this.lr = random(10, Math.min(w, h)); | |
ctx.strokeStyle = randomColor(0, 255, 0.33); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Entropy { | |
constructor() { | |
this.width = random(50, w); | |
this.height = random(50, h); | |
this.rotate = random(1, 181); | |
this.ul = random(10, Math.min(w, h)); | |
this.ur = random(10, Math.min(w, h)); | |
this.ll = random(10, Math.min(w, h)); | |
this.lr = random(10, Math.min(w, h)); | |
ctx.strokeStyle = randomColor(0, 255, 0.75); | |
ctx.globalCompositeOperation = "overlay"; | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.roundRect(0, 0, this.width++, this.height++, { | |
upperLeft: this.ul--, | |
upperRight: this.ur--, | |
lowerLeft: this.ll--, | |
lowerRight: this.lr-- | |
}); | |
ctx.roundRect(w, h, this.height, this.width, { | |
upperLeft: this.lr, | |
upperRight: this.ll, | |
lowerLeft: this.ur, | |
lowerRight: this.ul | |
}); | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(this.rotate); | |
ctx.translate(-w / 2, -h / 2); | |
t++; | |
if (t % (speed * 500) === 0) { | |
ctx.beginPath(); | |
this.width = random(50, w); | |
this.height = random(50, h); | |
this.rotate = random(1, 181); | |
this.ul = random(10, Math.min(w, h)); | |
this.ur = random(10, Math.min(w, h)); | |
this.ll = random(10, Math.min(w, h)); | |
this.lr = random(10, Math.min(w, h)); | |
ctx.strokeStyle = randomColor(0, 255, 0.75); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Tripping { | |
constructor() { | |
this.x1 = random(0, w); | |
this.y1 = random(0, h); | |
this.x2 = random(0, w); | |
this.y2 = random(0, h); | |
this.width = random(50, w); | |
this.height = random(50, h); | |
this.rotate = random(1, 360); | |
this.ul = random(10, Math.max(w, h)); | |
this.ur = random(10, Math.max(w, h)); | |
this.ll = random(10, Math.max(w, h)); | |
this.lr = random(10, Math.max(w, h)); | |
ctx.strokeStyle = randomColor(0, 255, 0.25, 0.5); | |
ctx.lineWidth = 0.5; | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.roundRect(this.x1++, this.y1++, this.width++, this.height++, { | |
upperLeft: this.ul--, | |
upperRight: this.ur--, | |
lowerLeft: this.ll--, | |
lowerRight: this.lr-- | |
}); | |
ctx.roundRect(this.x2--, this.y2--, this.height, this.width, { | |
upperLeft: this.lr, | |
upperRight: this.ll, | |
lowerLeft: this.ur, | |
lowerRight: this.ul | |
}); | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(this.rotate); | |
ctx.translate(-w / 2, -h / 2); | |
t++; | |
if (t % (speed * 500) === 0) { | |
ctx.beginPath(); | |
ctx.clearRect(-w, -h, 3 * w, 3 * h); | |
this.x1 = random(0, w); | |
this.y1 = random(0, h); | |
this.x2 = random(0, w); | |
this.y2 = random(0, h); | |
this.width = random(50, w); | |
this.height = random(50, h); | |
this.rotate = random(1, 360); | |
this.ul = random(10, Math.max(w, h)); | |
this.ur = random(10, Math.max(w, h)); | |
this.ll = random(10, Math.max(w, h)); | |
this.lr = random(10, Math.max(w, h)); | |
ctx.strokeStyle = randomColor(0, 255, 0.25, 0.5); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Progression { | |
constructor() { | |
this.width = random(40, w); | |
this.height = random(40, h); | |
this.round = random(1, 350); | |
this.rotate = random(1, 180); | |
ctx.fillStyle = randomColor(0, 255, 0.01, 0.03); | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.roundRect( | |
w / 2, | |
h / 2, | |
this.width, | |
this.height, | |
{ | |
upperLeft: this.round, | |
upperRight: this.round, | |
lowerLeft: this.round, | |
lowerRight: this.round | |
}, | |
true, | |
false | |
); | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate((this.rotate * Math.PI) / 180); | |
ctx.translate(-w / 2, -h / 2); | |
t++; | |
if (t % (speed * 180) === 0) { | |
this.width = random(40, w); | |
this.height = random(40, h); | |
this.round = random(1, 350); | |
this.rotate = random(1, 180); | |
ctx.beginPath(); | |
ctx.fillStyle = randomColor(0, 255, 0.01, 0.03); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Aperture { | |
constructor() { | |
this.x = w / 2; | |
this.y = random(100, h - 100); | |
this.width = random(100, w - 100); | |
this.height = random(100, h - 100); | |
this.round = random(5, 100); | |
this.white = true; | |
this.rotate = random(1, 70); | |
this.incX = Math.random(); | |
this.incH = Math.random(); | |
ctx.strokeStyle = "white"; | |
ctx.fillStyle = "black"; | |
ctx.globalAlpha = 0.75; | |
ctx.lineWidth = 4; | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.roundRect( | |
this.x, | |
this.y, | |
this.width, | |
this.height, | |
{ | |
upperLeft: this.round, | |
upperRight: this.round, | |
lowerLeft: this.round, | |
lowerRight: this.round | |
}, | |
true | |
); | |
} | |
this.x += this.incX; | |
this.height += this.incH; | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(this.rotate); | |
ctx.translate(-w / 2, -h / 2); | |
t++; | |
if (t % (speed * 300) === 0) { | |
ctx.beginPath(); | |
if (this.white) { | |
ctx.strokeStyle = "black"; | |
ctx.fillStyle = "white"; | |
} else { | |
ctx.strokeStyle = "white"; | |
ctx.fillStyle = "black"; | |
} | |
this.white = !this.white; | |
this.x = w / 2; | |
this.y = random(100, h - 100); | |
this.rotate = random(1, 70); | |
this.width = random(100, w - 100); | |
this.height = random(100, h - 100); | |
this.round = random(5, 100); | |
this.incX = Math.random(); | |
this.incH = Math.random(); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Upholstery { | |
constructor() { | |
this.x1 = random(0, w); | |
this.y1 = random(0, h); | |
this.x2 = random(0, w); | |
this.y2 = random(0, h); | |
this.rotate = random(1, 55); | |
this.dash1 = random(1, 15); | |
this.dash2 = random(20, 40); | |
this.dash3 = random(1, 50); | |
ctx.strokeStyle = randomColor(50, 255, 1, 1); | |
ctx.setLineDash([this.dash1, this.dash2, this.dash3]); | |
ctx.globalCompositeOperation = "overlay"; | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.moveTo(this.x1, this.y1); | |
ctx.lineTo(this.x2, this.y2); | |
ctx.stroke(); | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(this.rotate); | |
ctx.translate(-w / 2, -h / 2); | |
t++; | |
if (t % (speed * 120) === 0) { | |
this.dash1 = random(1, 15); | |
this.dash2 = random(20, 40); | |
this.dash3 = random(1, 50); | |
ctx.setLineDash([this.dash1, this.dash2, this.dash3]); | |
this.x1 = random(0, w); | |
this.y1 = random(0, h); | |
this.x2 = random(0, w); | |
this.y2 = random(0, h); | |
ctx.beginPath(); | |
ctx.strokeStyle = randomColor(50, 255, 1, 1); | |
this.rotate = random(1, 55); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Unfocused { | |
constructor() { | |
this.x1 = random(0, w); | |
this.y1 = random(0, h); | |
this.radius1 = random(5, 55); | |
this.x2 = random(0, w); | |
this.y2 = random(0, h); | |
this.radius2 = random(5, 55); | |
this.x3 = random(0, w); | |
this.y3 = random(0, h); | |
this.radius3 = random(5, 55); | |
this.rotate = random(1, 61); | |
ctx.fillStyle = randomColor(10, 255, 0.1, 0.1); | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.beginPath(); | |
ctx.arc(this.x1, this.y1, this.radius1, 0, 2 * Math.PI); | |
ctx.fill(); | |
ctx.beginPath(); | |
ctx.arc(this.x2, this.y2, this.radius2, 0, 2 * Math.PI); | |
ctx.fill(); | |
ctx.beginPath(); | |
ctx.arc(this.x3, this.y3, this.radius3, 0, 2 * Math.PI); | |
ctx.fill(); | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(this.rotate); | |
ctx.translate(-w / 2, -h / 2); | |
t++; | |
if (t % (speed * 20) === 0) { | |
this.x1 = random(0, w); | |
this.y1 = random(0, h); | |
this.radius1 = random(5, 55); | |
this.x2 = random(0, w); | |
this.y2 = random(0, h); | |
this.radius2 = random(5, 55); | |
this.x3 = random(0, w); | |
this.y3 = random(0, h); | |
this.radius3 = random(5, 55); | |
ctx.fillStyle = randomColor(10, 255, 0.1, 0.1); | |
} | |
if (t % (speed * 100) === 0) { | |
this.rotate = random(1, 61); | |
} | |
if (t % (speed * 500) === 0) { | |
ctx.fillStyle = "rgba(0,0,0,0.5)"; | |
ctx.fillRect(-w, -h, 3 * w, 3 * h); | |
ctx.fillStyle = randomColor(10, 255, 0.1, 0.1); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Rotunda { | |
constructor() { | |
this.x1 = random(0, w / 3); | |
this.y1 = random(0, h / 3); | |
this.radius1 = random(5, 150); | |
this.x2 = random(w / 3, w * 0.66); | |
this.y2 = random(w / 3, h * 0.66); | |
this.radius2 = random(5, 150); | |
this.x3 = random(w * 0.66, w); | |
this.y3 = random(h * 0.66, h); | |
this.radius3 = random(5, 150); | |
this.rotate = random(3, 31); | |
ctx.strokeStyle = randomColor(10, 255, 0.25, 0.5); | |
ctx.globalCompositeOperation = "overlay"; | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.beginPath(); | |
ctx.arc(this.x1, this.y1, this.radius1, 0, 2 * Math.PI); | |
ctx.stroke(); | |
ctx.beginPath(); | |
ctx.arc(this.x2, this.y2, this.radius2, 0, 2 * Math.PI); | |
ctx.stroke(); | |
ctx.beginPath(); | |
ctx.arc(this.x3, this.y3, this.radius3, 0, 2 * Math.PI); | |
ctx.stroke(); | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(this.rotate); | |
ctx.translate(-w / 2, -h / 2); | |
t++; | |
if (t % (speed * 150) === 0) { | |
this.x1 = random(0, w / 3); | |
this.y1 = random(0, h / 3); | |
this.radius1 = random(5, 150); | |
this.x2 = random(w / 3, w * 0.66); | |
this.y2 = random(w / 3, h * 0.66); | |
this.radius2 = random(5, 150); | |
this.x3 = random(w * 0.66, w); | |
this.y3 = random(h * 0.66, h); | |
this.radius3 = random(5, 150); | |
this.rotate = random(3, 31); | |
ctx.strokeStyle = randomColor(10, 255, 0.25, 0.5); | |
this.rotate = random(3, 31); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class CrayonFunnel { | |
constructor() { | |
this.x = random(w / 3, w * 0.66); | |
this.y = random(w / 3, h * 0.66); | |
this.inc = random(1, 6); | |
this.radius = random(5, 60); | |
this.rotate = random(1, 150); | |
ctx.strokeStyle = randomColor(0, 255, 1, 1); | |
ctx.lineWidth = 2; | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.beginPath(); | |
ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI); | |
this.radius += this.inc; | |
ctx.stroke(); | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(this.rotate); | |
ctx.translate(-w / 2, -h / 2); | |
t++; | |
if (t % (speed * 180) === 0) { | |
this.x = random(w / 3, w * 0.66); | |
this.y = random(w / 3, h * 0.66); | |
this.radius = random(5, 60); | |
this.inc = random(1, 6); | |
this.rotate = random(1, 150); | |
if (Math.random() < 0.5) { | |
if (Math.random() < 0.5) { | |
ctx.strokeStyle = "white"; | |
} else { | |
ctx.strokeStyle = "black"; | |
} | |
} else { | |
ctx.strokeStyle = randomColor(0, 255, 1, 1); | |
} | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class BigBangs { | |
constructor() { | |
this.r = 1; | |
this.i = random(5, 30); | |
this.a = random(1, 180); | |
ctx.fillStyle = randomColor(0, 255, 0.02, 0.05); | |
ctx.strokeStyle = randomColor(0, 255, 0.5, 1); | |
ctx.globalCompositeOperation = "hard-light"; | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.arc(w / 2, h / 2, this.r, 0, 2 * Math.PI); | |
ctx.fill(); | |
ctx.stroke(); | |
this.r += this.i; | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate((this.a * Math.PI) / 180); | |
ctx.translate(-w / 2, -h / 2); | |
t++; | |
if (this.r > Math.max(w, h)) { | |
ctx.fillStyle = randomColor(0, 255, 0.02, 0.05); | |
ctx.fillRect(-w, -h, 3 * w, 3 * h); | |
this.a = random(1, 180); | |
this.r = 1; | |
this.i = random(5, 30); | |
ctx.beginPath(); | |
ctx.strokeStyle = randomColor(0, 255, 0.5, 1); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Nazca { | |
constructor() { | |
this.r = 1; | |
this.i = random(13, 60); | |
this.a = random(1, 180); | |
this.modes = ["soft-light", "overlay", "color"]; | |
this.cycles = 0; | |
ctx.fillStyle = randomColor(0, 255, 0.15, 0.55); | |
ctx.strokeStyle = randomColor(0, 255, 0.75, 1); | |
ctx.globalCompositeOperation = "soft-light"; | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.arc(w / 2, h / 2, this.r, 0, Math.random() * Math.PI); | |
ctx.fill(); | |
ctx.stroke(); | |
this.r += this.i; | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(-this.a); | |
ctx.translate(-w / 2, -h / 2); | |
t++; | |
if (this.r > Math.max(w, h)) { | |
this.cycles++; | |
if (this.cycles % 10 === 0) { | |
ctx.globalCompositeOperation = this.modes[ | |
random(0, this.modes.length) | |
]; | |
} | |
ctx.lineWidth = random(1, 7); | |
ctx.fillStyle = randomColor(0, 255, 0.15, 0.55); | |
this.a = random(1, 180); | |
this.r = 1; | |
this.i = random(13, 60); | |
ctx.beginPath(); | |
ctx.strokeStyle = randomColor(0, 255, 0.75, 1); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Clutch { | |
constructor() { | |
this.x1 = random(100, w - 100); | |
this.y1 = random(100, h - 100); | |
this.r1 = random(75, 360); | |
this.rotate = random(1, 10); | |
this.true = true; | |
ctx.shadowColor = ctx.strokeStyle = randomColor(0, 255, 0.65); | |
ctx.shadowBlur = 3; | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.beginPath(); | |
ctx.arc( | |
this.x1, | |
this.y1, | |
this.r1, | |
Math.PI / (this.true ? 2 : 3), | |
Math.PI / (this.true ? 3 : 2), | |
this.true | |
); | |
ctx.stroke(); | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(this.rotate); | |
ctx.translate(-w / 2, -h / 2); | |
t++; | |
if (t % (speed * 225) === 0) { | |
this.x1 = random(100, w - 100); | |
this.y1 = random(100, h - 100); | |
this.r1 = random(75, 600); | |
this.true = !this.true; | |
this.rotate = random(1, 10); | |
ctx.shadowColor = ctx.strokeStyle = randomColor(0, 255, 0.65); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Torus { | |
constructor() { | |
this.r1 = random(120, 500); | |
this.x1 = random(this.r1 / 2, w - this.r1 / 2); | |
this.y1 = random(this.r1 / 2, h - this.r1 / 2); | |
this.color1 = randomColor(0, 255, 0.06, 0.16); | |
this.rotate = random(6, 24); | |
ctx.strokeStyle = "black"; | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate((this.rotate * Math.PI) / 180); | |
ctx.beginPath(); | |
ctx.fillStyle = this.color1; | |
ctx.arc(this.x1, this.y1, this.r1, 0, 2 * Math.PI); | |
ctx.stroke(); | |
ctx.fill(); | |
ctx.translate(-w / 2, -h / 2); | |
} | |
t++; | |
if (t % (speed * 60) === 0) { | |
this.r1 = random(120, 500); | |
this.x1 = random(this.r1 / 2, w - this.r1 / 2); | |
this.y1 = random(this.r1 / 2, h - this.r1 / 2); | |
this.color1 = randomColor(0, 255, 0.06, 0.16); | |
this.rotate = random(6, 24); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Shapeshifter { | |
constructor() { | |
this.x1 = random(0, w); | |
this.y1 = random(0, h); | |
this.x2 = random(0, w); | |
this.y2 = random(0, h); | |
this.x3 = random(0, w); | |
this.y3 = random(0, h); | |
this.x4 = random(0, w); | |
this.y4 = random(0, h); | |
this.rotate = (random(4, 87) * Math.PI) / 180; | |
ctx.strokeStyle = randomColor(); | |
ctx.fillStyle = randomColor(0, 255, 0.01, 0.01); | |
ctx.shadowColor = "black"; | |
ctx.shadowBlur = 20; | |
ctx.moveTo(this.x1, this.y1); | |
this.draw = () => { | |
if (t % speed === 0) { | |
stagger = stagger % 4; | |
if (stagger === 0) { | |
ctx.lineTo(this.x2++, this.y2++); | |
ctx.stroke(); | |
} | |
if (stagger === 1) { | |
ctx.lineTo(this.x3--, this.y3++); | |
ctx.stroke(); | |
} | |
if (stagger === 2) { | |
ctx.lineTo(this.x4--, this.y4--); | |
ctx.stroke(); | |
} | |
if (stagger === 3) { | |
ctx.lineTo(this.x1++, this.y1--); | |
ctx.stroke(); | |
} | |
} | |
ctx.fill(); | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(this.rotate); | |
ctx.translate(-w / 2, -h / 2); | |
t++; | |
if (t % (speed * 240) === 0) { | |
ctx.beginPath(); | |
ctx.strokeStyle = randomColor(); | |
ctx.fillStyle = randomColor(0, 255, 0.01, 0.01); | |
this.x1 = random(0, w); | |
this.y1 = random(0, h); | |
this.x2 = random(0, w); | |
this.y2 = random(0, h); | |
this.x3 = random(0, w); | |
this.y3 = random(0, h); | |
this.x4 = random(0, w); | |
this.y4 = random(0, h); | |
this.rotate = (random(4, 87) * Math.PI) / 180; | |
} | |
stagger++; | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Smooth { | |
constructor() { | |
this.size = random(50, 500); | |
this.x = random(0, w); | |
this.y = random(0, h); | |
this.rot = random(1, 11); | |
ctx.fillStyle = randomColor(0, 255, 0.03, 0.08); | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.fillRect(this.x, this.y, this.size, this.size); | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(this.rot); | |
ctx.translate(-w / 2, -h / 2); | |
t++; | |
if (t % (speed * 60) === 0) { | |
this.size = random(50, 500); | |
this.x = random(0, w); | |
this.y = random(0, h); | |
ctx.fillStyle = randomColor(0, 255, 0.03, 0.08); | |
this.rot = random(1, 11); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Glow { | |
constructor() { | |
this.margin1 = random(25, w / 4); | |
this.margin2 = random(25, w / 4); | |
this.color1 = randomColor(0, 255, 0.05, 0.2); | |
this.color2 = randomColor(0, 255, 0.05, 0.2); | |
this.rot = random(1, 60); | |
this.modes = ["color", "source-over", "overlay", "soft-light"]; | |
ctx.strokeStyle = "white"; | |
ctx.globalCompositeOperation = "color"; | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.fillStyle = this.color1; | |
ctx.fillRect(0, 0, w / 2 + this.margin1, h); | |
ctx.fillStyle = this.color2; | |
ctx.fillRect(w / 2 - this.margin2, 0, w, h); | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(this.rot); | |
ctx.translate(-w / 2, -h / 2); | |
t++; | |
if (t % (speed * 60) === 0) { | |
this.margin1 = random(25, w / 4); | |
this.color1 = randomColor(0, 255, 0.05, 0.2); | |
} | |
if (t % (speed * 90) === 0) { | |
this.margin2 = random(25, w / 4); | |
this.color2 = randomColor(0, 255, 0.05, 0.2); | |
} | |
if (t % (speed * 180) === 0) { | |
this.rot = random(1, 60); | |
ctx.globalCompositeOperation = this.modes[random(0, this.modes.length)]; | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Encoded { | |
constructor() { | |
this.letters = ["S", "P", "I", "R", "A", "L"]; | |
this.letter = this.letters[random(0, this.letters.length)]; | |
this.size = random(100, 600); | |
this.rot = (random(1, 360) * Math.PI) / 180; | |
this.x = random(0, w); | |
this.y = random(0, h); | |
this.angles = [10, 12, 15, 18, 20, 24, 36, 45, 72]; | |
this.angle = this.angles[random(0, this.angles.length)]; | |
ctx.shadowColor = ctx.strokeStyle = randomColor(30, 255, 0.2, 0.6); | |
ctx.fillStyle = "rgba(0,0,0,0.2)"; | |
ctx.font = `bold ${this.size}px serif`; | |
ctx.textAlign = "center"; | |
ctx.shadowBlur = 10; | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.strokeText(this.letter, this.x, this.y); | |
ctx.fillText(this.letter, this.x, this.y); | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate((this.angle * Math.PI) / 180); | |
ctx.translate(-w / 2, -h / 2); | |
t++; | |
if (t % (speed * 72) === 0) { | |
this.letter = this.letters[random(0, this.letters.length)]; | |
this.size = random(100, 600); | |
this.rot = (random(1, 360) * Math.PI) / 180; | |
ctx.shadowColor = ctx.strokeStyle = randomColor(30, 255, 0.2, 0.6); | |
ctx.font = `bold ${this.size}px serif`; | |
this.x = random(0, w); | |
this.y = random(0, h); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Concentric { | |
constructor() { | |
this.letters = [ | |
2605, | |
2608, | |
2617, | |
2626, | |
2632, | |
2635, | |
2641, | |
2652, | |
2654, | |
2662, | |
2663, | |
2667, | |
2670, | |
2676, | |
2677, | |
2691, | |
2694, | |
2695, | |
2696, | |
2700 | |
]; | |
this.letter1 = String.fromCharCode( | |
this.letters[random(0, this.letters.length)] | |
); | |
this.letter2 = String.fromCharCode( | |
this.letters[random(0, this.letters.length)] | |
); | |
this.letter3 = String.fromCharCode( | |
this.letters[random(0, this.letters.length)] | |
); | |
this.letter4 = String.fromCharCode( | |
this.letters[random(0, this.letters.length)] | |
); | |
this.size = random(25, 160); | |
this.x = random(0, w); | |
this.y = random(0, h); | |
this.angles = [10, 12, 15, 18, 20, 24, 36, 45, 72]; | |
this.angle = this.angles[random(0, this.angles.length)]; | |
ctx.globalCompositeOperation = "soft-light"; | |
ctx.shadowColor = ctx.strokeStyle = randomColor(); | |
ctx.fillStyle = randomColor(); | |
ctx.font = `bold ${this.size}px serif`; | |
ctx.textAlign = "center"; | |
ctx.shadowBlur = 7; | |
ctx.lineWidth = 5; | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.strokeText( | |
`${this.letter1} ${this.letter2} ${this.letter3} ${this.letter4}`, | |
this.x, | |
this.y | |
); | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(this.angle); | |
ctx.translate(-w / 2, -h / 2); | |
t++; | |
if (t % (speed * 150) === 0) { | |
this.letter1 = String.fromCharCode( | |
this.letters[random(0, this.letters.length)] | |
); | |
this.letter2 = String.fromCharCode( | |
this.letters[random(0, this.letters.length)] | |
); | |
this.letter3 = String.fromCharCode( | |
this.letters[random(0, this.letters.length)] | |
); | |
this.letter4 = String.fromCharCode( | |
this.letters[random(0, this.letters.length)] | |
); | |
this.size = random(25, 160); | |
ctx.fillStyle = randomColor(); | |
ctx.shadowColor = ctx.strokeStyle = randomColor(30, 255, 0.2, 0.6); | |
ctx.font = `bold ${this.size}px serif`; | |
this.x = random(0, w); | |
this.y = random(0, h); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Blends { | |
constructor() { | |
this.x = random(0, w); | |
this.y = random(0, h); | |
this.x2 = random(0, w); | |
this.y2 = random(0, h); | |
this.length = random(30, 250); | |
this.shape1 = () => | |
ctx.fillRect(this.x++, this.y, this.length++, this.length); | |
this.shape2 = () => | |
ctx.arc(this.x2, this.y2++, this.length, 0, 2 * Math.PI); | |
this.shape3 = () => { | |
ctx.moveTo(this.x, this.y); | |
ctx.lineTo(this.x2, this.y2); | |
}; | |
this.currentShape = random(0, 3); | |
this.rotation = random(2, 140); | |
this.color1 = randomColor(0, 255, 0.025, 0.075); | |
this.color2 = randomColor(0, 255, 0.025, 0.075); | |
ctx.lineWidth = 3; | |
ctx.strokeStyle = randomColor(); | |
this.draw = () => { | |
if (t % speed === 0) { | |
if (this.currentShape === 0) { | |
ctx.fillStyle = this.color2; | |
this.shape1(); | |
} else if (this.currentShape === 1) { | |
ctx.fillStyle = this.color1; | |
ctx.beginPath(); | |
this.shape2(); | |
ctx.fill(); | |
} else { | |
ctx.strokeStyle = this.color2; | |
ctx.beginPath(); | |
this.shape3(); | |
ctx.stroke(); | |
} | |
this.currentShape++; | |
if (this.currentShape > 2) this.currentShape = 0; | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate((this.rotation * Math.PI) / 180); | |
ctx.translate(-w / 2, -h / 2); | |
} | |
t++; | |
if (t % (speed * 270) === 0) { | |
this.rotation = random(2, 140); | |
this.x = random(0, w); | |
this.y = random(0, h); | |
this.x2 = random(0, w); | |
this.y2 = random(0, h); | |
this.length = random(30, 250); | |
ctx.beginPath(); | |
this.color1 = randomColor(0, 255, 0.025, 0.075); | |
this.color2 = randomColor(0, 255, 0.025, 0.075); | |
ctx.strokeStyle = randomColor(); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Matter { | |
constructor() { | |
this.x1 = random(0, w); | |
this.y1 = random(0, h); | |
this.radius1 = random(5, 150); | |
this.x2 = random(0, w); | |
this.y2 = random(0, h); | |
this.radius2 = random(5, 150); | |
this.x3 = random(0, w); | |
this.y3 = random(0, h); | |
this.radius3 = random(5, 150); | |
this.rotate = random(10, 101); | |
ctx.fillStyle = randomColor(10, 255, 0.02, 0.07); | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.beginPath(); | |
ctx.arc(this.x1, this.y1, this.radius1, 0, 2 * Math.PI); | |
ctx.fill(); | |
ctx.beginPath(); | |
ctx.arc(this.x2, this.y2, this.radius2, 0, 2 * Math.PI); | |
ctx.fill(); | |
ctx.beginPath(); | |
ctx.arc(this.x3, this.y3, this.radius3, 0, 2 * Math.PI); | |
ctx.fill(); | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate((this.rotate * Math.PI) / 180); | |
ctx.translate(-w / 2, -h / 2); | |
t++; | |
if (t % (speed * 120) === 0) { | |
this.x1 = random(0, w); | |
this.y1 = random(0, h); | |
this.radius1 = random(5, 150); | |
this.x2 = random(0, w); | |
this.y2 = random(0, h); | |
this.radius2 = random(5, 150); | |
this.x3 = random(0, w); | |
this.y3 = random(0, h); | |
this.radius3 = random(5, 150); | |
ctx.fillStyle = randomColor(10, 255, 0.02, 0.07); | |
this.rotate = random(10, 101); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Seeds { | |
constructor() { | |
this.x1 = random(0, w); | |
this.y1 = random(0, h); | |
this.x2 = random(0, w); | |
this.y2 = random(0, h); | |
this.x3 = random(0, w); | |
this.y3 = random(0, h); | |
this.rotate = random(10, 101); | |
ctx.fillStyle = ctx.strokeStyle = ctx.shadowColor = randomColor( | |
40, | |
255, | |
0.65, | |
1 | |
); | |
ctx.shadowBlur = 2; | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.beginPath(); | |
ctx.arc(this.x1++, this.y1--, 5, 0, 0.5 * Math.PI); | |
ctx.stroke(); | |
ctx.fill(); | |
ctx.beginPath(); | |
ctx.arc(this.x2--, this.y2++, 10, 0, 0.5 * Math.PI); | |
ctx.stroke(); | |
ctx.fill(); | |
ctx.beginPath(); | |
ctx.arc(this.x3++, this.y3, 15, 0, 0.5 * Math.PI); | |
ctx.stroke(); | |
ctx.fill(); | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(this.rotate); | |
ctx.translate(-w / 2, -h / 2); | |
t++; | |
if (t % (speed * 360) === 0) { | |
this.x1 = random(0, w); | |
this.y1 = random(0, h); | |
this.x2 = random(0, w); | |
this.y2 = random(0, h); | |
this.x3 = random(0, w); | |
this.y3 = random(0, h); | |
ctx.fillStyle = ctx.strokeStyle = ctx.shadowColor = randomColor( | |
40, | |
255, | |
0.65, | |
1 | |
); | |
this.rotate = random(10, 101); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Onion { | |
constructor() { | |
this.radius = random(45, 500); | |
this.x = random(0, w); | |
this.y = random(0, h); | |
this.angle = random(2, 50); | |
ctx.strokeStyle = "black"; | |
ctx.fillStyle = randomColor(0, 255, 0.005, 0.015); | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.beginPath(); | |
ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI); | |
ctx.stroke(); | |
ctx.fill(); | |
ctx.closePath(); | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate((this.angle / 180) * Math.PI); | |
ctx.translate(-w / 2, -h / 2); | |
t++; | |
if (t % (speed * 135) === 0) { | |
this.radius = random(50, 500); | |
this.x = random(0, w); | |
this.y = random(0, h); | |
ctx.beginPath(); | |
ctx.fillStyle = randomColor(0, 255, 0.005, 0.015); | |
} | |
if (t % (speed * 540) === 0) { | |
this.angle = random(2, 50); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Spheral { | |
constructor() { | |
this.radius = random(50, 350); | |
this.x = random(0, w); | |
this.y = random(0, h); | |
this.angle = random(1, 90); | |
ctx.lineWidth = 2; | |
ctx.strokeStyle = ctx.shadowColor = randomColor(); | |
ctx.shadowBlur = 2; | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.beginPath(); | |
ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI); | |
ctx.stroke(); | |
ctx.closePath(); | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate((this.angle / 180) * Math.PI); | |
ctx.translate(-w / 2, -h / 2); | |
t++; | |
if (t % (speed * 90) === 0) { | |
this.radius = random(50, 350); | |
this.x = random(0, w); | |
this.y = random(0, h); | |
ctx.beginPath(); | |
} | |
if (t % (speed * 360) === 0) { | |
ctx.strokeStyle = ctx.shadowColor = randomColor(); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class SnakesLadders { | |
constructor() { | |
this.div = random(3, 17); | |
this.div2 = random(3, 17); | |
this.colSize = w / this.div; | |
this.rowSize = h / this.div2; | |
this.currCol = 0; | |
this.currRow = 0; | |
this.rotate = random(1, 83); | |
ctx.fillStyle = randomColor(0, 255, 0.15, 0.53); | |
ctx.strokeStyle = ctx.shadowColor = randomColor(0, 255, 0.55, 1); | |
ctx.shadowBlur = 3; | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.strokeRect( | |
this.colSize * this.currCol, | |
this.rowSize * this.currRow, | |
this.colSize, | |
this.rowSize | |
); | |
this.currCol++; | |
if (this.currCol > this.div - 1) { | |
this.currCol = 0; | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(this.rotate); | |
ctx.translate(-w / 2, -h / 2); | |
this.currRow++; | |
if (this.currRow > this.div2 - 1) { | |
this.currRow = 0; | |
} | |
} | |
} | |
t++; | |
if (t % (speed * 720) === 0) { | |
ctx.fillRect(-w, -h, 3 * w, 3 * h); | |
this.rotate = random(1, 83); | |
this.div = random(3, 17); | |
this.div2 = random(3, 17); | |
this.colSize = w / this.div; | |
this.rowSize = h / this.div2; | |
ctx.beginPath(); | |
ctx.fillStyle = randomColor(0, 255, 0.15, 0.53); | |
ctx.strokeStyle = ctx.shadowColor = randomColor(0, 255, 0.55, 1); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Cornucopia { | |
constructor() { | |
this.x = random(0, w); | |
this.y = random(0, h); | |
this.width = random(15, 240); | |
this.height = random(15, 150); | |
this.ul = random(4, 35); | |
this.ur = random(4, 35); | |
this.dl = random(4, 35); | |
this.dr = random(4, 35); | |
this.rotate = random(1, 25); | |
ctx.strokeStyle = randomColor(); | |
ctx.fillStyle = randomColor(0, 255, 0.025, 0.09); | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.roundRect( | |
this.x, | |
this.y, | |
this.width++, | |
this.height--, | |
{ | |
upperLeft: this.ul--, | |
upperRight: this.ur++, | |
lowerLeft: this.dl++, | |
lowerRight: this.dr-- | |
}, | |
true, | |
false | |
); | |
} | |
t++; | |
if (t % (speed * 210) === 0) { | |
ctx.strokeStyle = randomColor(); | |
ctx.fillStyle = randomColor(0, 255, 0.025, 0.09); | |
this.x = random(0, w); | |
this.y = random(0, h); | |
this.rotate = random(1, 25); | |
this.width = random(15, 240); | |
this.height = random(15, 150); | |
this.ul = random(4, 35); | |
this.ur = random(4, 35); | |
this.dl = random(4, 35); | |
this.dr = random(4, 35); | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(this.rotate); | |
ctx.translate(-w / 2, -h / 2); | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Cornucopia2 { | |
constructor() { | |
this.x = random(0, w); | |
this.y = random(0, h); | |
this.width = random(35, 440); | |
this.height = random(35, 350); | |
this.ul = random(4, 135); | |
this.ulc = random(-5, 5); | |
this.ur = random(4, 135); | |
this.urc = random(-5, 5); | |
this.dl = random(4, 135); | |
this.dlc = random(-5, 5); | |
this.dr = random(4, 135); | |
this.drc = random(-5, 5); | |
this.rotate = random(1, 75); | |
ctx.strokeStyle = randomColor(); | |
ctx.fillStyle = randomColor(); | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.roundRect( | |
this.x, | |
this.y, | |
this.width, | |
this.height, | |
{ | |
upperLeft: this.ul, | |
upperRight: this.ur, | |
lowerLeft: this.dl, | |
lowerRight: this.dr | |
}, | |
false, | |
true | |
); | |
this.ul += this.ulc; | |
this.ur += this.urc; | |
this.dl += this.dlc; | |
this.dr += this.drc; | |
} | |
t++; | |
if (t % (speed * 500) === 0) { | |
ctx.strokeStyle = randomColor(); | |
ctx.fillStyle = randomColor(); | |
this.x = random(0, w); | |
this.y = random(0, h); | |
this.width = random(35, 440); | |
this.height = random(35, 350); | |
this.ul = random(4, 135); | |
this.ulc = random(-5, 5); | |
this.urc = random(-5, 5); | |
this.dlc = random(-5, 5); | |
this.drc = random(-5, 5); | |
this.ur = random(4, 135); | |
this.dl = random(4, 135); | |
this.dr = random(4, 135); | |
this.rotate = random(1, 75); | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(this.rotate); | |
ctx.translate(-w / 2, -h / 2); | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Crosshatch { | |
constructor() { | |
this.x = random(0, w / 2); | |
this.y = random(0, h / 2); | |
this.length = random(32, 320); | |
this.rot = random(1, 30); | |
this.dash = random(5, 101); | |
ctx.lineWidth = 3; | |
ctx.strokeStyle = randomColor(); | |
ctx.setLineDash([this.dash, this.dash]); | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.strokeRect(this.x, this.y, this.length, this.length); | |
} | |
t++; | |
if (t % (speed * 120) === 0) { | |
this.x = random(0, w / 2); | |
this.y = random(0, h / 2); | |
this.length = random(32, 320); | |
} | |
if (t % (speed * 360) === 0) { | |
this.rot = random(1, 30); | |
this.dash = random(5, 101); | |
ctx.setLineDash([this.dash, this.dash]); | |
} | |
if (t % (speed * 720) === 0) { | |
ctx.clearRect(-w, -h, 3 * w, 3 * h); | |
ctx.beginPath(); | |
ctx.strokeStyle = randomColor(); | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(this.rot); | |
ctx.translate(-w / 2, -h / 2); | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Networks { | |
constructor() { | |
this.drawAmount = 0.01; | |
this.x = random(0, w); | |
this.y = random(0, h); | |
this.rot = random(1, 71); | |
this.size = random(30, 200); | |
ctx.strokeStyle = randomColor(); | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.arc(this.x, this.y, this.size, 0, this.drawAmount * Math.PI * 2); | |
this.drawAmount += 0.0025; | |
this.size += 0.5; | |
ctx.stroke(); | |
ctx.beginPath(); | |
} | |
t++; | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(this.rot); | |
ctx.translate(-w / 2, -h / 2); | |
if (t % (speed * 480) === 0) { | |
ctx.strokeStyle = randomColor(); | |
this.drawAmount = 0.01; | |
this.x = random(0, w); | |
this.y = random(0, h); | |
this.rot = random(1, 71); | |
this.size = random(30, 200); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Spikral { | |
constructor() { | |
this.fillAmount = (Math.random() + 0.05) * (Math.PI / 2); | |
this.rot = random(1, 22); | |
this.size = random(20, 100); | |
ctx.fillStyle = randomColor(0, 255, 0.25, 1); | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.arc(w / 2, h / 2, this.size, 0, this.fillAmount); | |
this.size *= 1.05; | |
ctx.fill(); | |
ctx.beginPath(); | |
} | |
t++; | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(-this.rot); | |
ctx.translate(-w / 2, -h / 2); | |
if (t % (speed * 150) === 0) { | |
ctx.fillStyle = randomColor(0, 255, 0.25, 1); | |
this.fillAmount = (Math.random() + 0.05) * (Math.PI / 2); | |
this.size = random(20, 100); | |
} | |
if (t % (speed * 1500) === 0) { | |
this.rot = random(1, 22); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Fruits { | |
constructor() { | |
this.row = 0; | |
this.col = 0; | |
this.size = random(15, 105); | |
this.cell = 100; | |
ctx.strokeStyle = "black"; | |
ctx.fillStyle = randomColor(0, 255, 0.1, 0.45); | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.arc( | |
this.col * this.cell - this.cell, | |
this.row * this.cell - this.cell, | |
this.size, | |
0, | |
2 * Math.PI | |
); | |
ctx.stroke(); | |
ctx.fill(); | |
ctx.beginPath(); | |
this.col++; | |
if (this.col * this.cell - this.cell * 2 > w) { | |
this.col = 0; | |
this.row++; | |
} | |
if (this.row * this.cell - this.cell * 2 > h) { | |
ctx.beginPath(); | |
this.col = 0; | |
this.row = 0; | |
this.size = random(15, 105); | |
ctx.beginPath(); | |
ctx.fillStyle = randomColor(0, 255, 0.1, 0.45); | |
} | |
} | |
t++; | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Zentangles { | |
constructor() { | |
this.x = random(0, w); | |
this.xmod = random(-10, 11); | |
this.y = random(0, h); | |
this.ymod = random(-10, 11); | |
this.cpx = random(0, w); | |
this.cpxmod = random(-10, 11); | |
this.cpy = random(0, h); | |
this.cpymod = random(-10, 11); | |
this.rot = random(1, 360); | |
ctx.strokeStyle = randomColor(0, 255, 0.75, 1); | |
ctx.fillStyle = randomColor(0, 255, 0.1, 0.6); | |
ctx.lineWidth = 0.1; | |
ctx.moveTo(this.x, this.y); | |
ctx.fillRect(0, 0, w, h); | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.quadraticCurveTo(this.cpx, this.cpy, this.x, this.y); | |
ctx.stroke(); | |
this.x += this.xmod; | |
if (this.x < 0 || this.x > w) { | |
this.xmod = -this.xmod; | |
} | |
this.y += this.ymod; | |
if (this.y < 0 || this.y > h) { | |
this.ymod = -this.ymod; | |
} | |
this.cpx += this.cpxmod; | |
if (this.cpx < -2 * w || this.cpx > 2 * w) { | |
this.cpxmod = -this.cpxmod; | |
} | |
this.cpy += this.cpymod; | |
if (this.cpy < -2 * h || this.cpy > 2 * h) { | |
this.cpymod = -this.cpymod; | |
} | |
} | |
t++; | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate((this.rot * Math.PI) / 180); | |
ctx.translate(-w / 2, -h / 2); | |
if (t % (speed * 300) === 0) { | |
ctx.fillRect(-w, -h, 3 * w, 3 * h); | |
ctx.beginPath(); | |
this.x = random(0, w); | |
this.xmod = random(-10, 11); | |
this.y = random(0, h); | |
this.ymod = random(-10, 11); | |
ctx.moveTo(this.x, this.y); | |
this.cpx = random(0, w); | |
this.cpxmod = random(-10, 11); | |
this.cpy = random(0, h); | |
this.cpymod = random(-10, 11); | |
this.rot = random(1, 360); | |
ctx.strokeStyle = randomColor(0, 255, 0.75, 1); | |
ctx.fillStyle = randomColor(0, 255, 0.1, 0.6); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Typobrush { | |
constructor() { | |
this.x = random(0, w); | |
this.y = random(0, h); | |
this.letters = [ | |
2703, | |
2705, | |
2709, | |
2713, | |
2715, | |
2716, | |
2718, | |
2719, | |
2720, | |
2721, | |
2722, | |
2725, | |
2726, | |
2731, | |
2732, | |
2735, | |
2738, | |
2739, | |
2741, | |
2742, | |
2743, | |
2745, | |
2748, | |
2750, | |
2751, | |
2752, | |
2753, | |
2760, | |
2764, | |
2768, | |
2784, | |
2791, | |
2792, | |
2795, | |
2796, | |
2797, | |
2798, | |
2799, | |
2800 | |
]; | |
this.letter = String.fromCharCode( | |
this.letters[random(0, this.letters.length)] | |
); | |
this.size = 20; | |
this.sizeInc = random(1, 6); | |
this.rot = random(1, 400); | |
ctx.strokeStyle = randomColor(0, 255, 0.33, 0.33); | |
ctx.fillStyle = "rgba(0, 0, 0, 0.75)"; | |
ctx.textAlign = "center"; | |
ctx.font = `${this.size}px serif`; | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.strokeText(this.letter, this.x, this.y); | |
ctx.font = `${this.size}px serif`; | |
this.size += this.sizeInc; | |
} | |
t++; | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(this.rot); | |
ctx.translate(-w / 2, -h / 2); | |
if (t % (speed * 150) === 0) { | |
this.size = 20; | |
ctx.font = `${this.size}px serif`; | |
this.x = random(0, w); | |
this.y = random(0, h); | |
this.rot = random(1, 400); | |
this.sizeInc = random(1, 6); | |
ctx.strokeStyle = randomColor(0, 255, 0.33, 0.33); | |
} | |
if (t % (speed * 1500) === 0) { | |
ctx.fillRect(-w, -h, 3 * w, 3 * h); | |
this.letter = String.fromCharCode( | |
this.letters[random(0, this.letters.length)] | |
); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Veils { | |
constructor() { | |
this.x = random(0, w); | |
this.y = random(0, h); | |
this.letters = [ | |
2801, | |
2817, | |
2819, | |
2822, | |
2824, | |
2827, | |
2832, | |
2835, | |
2837, | |
2849, | |
2855, | |
2856, | |
2858, | |
2859, | |
2860, | |
2862, | |
2873, | |
2877, | |
2878, | |
2880, | |
2891, | |
2893 | |
]; | |
this.letter = String.fromCharCode( | |
this.letters[random(0, this.letters.length)] | |
); | |
this.rot = 1; | |
ctx.strokeStyle = randomColor(0, 255, 0.5, 0.5); | |
ctx.textAlign = "center"; | |
this.size = random(30, 400); | |
ctx.font = `${this.size}px serif`; | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.strokeText(this.letter, this.x, this.y); | |
this.size += 2; | |
ctx.font = `${this.size}px serif`; | |
} | |
t++; | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(this.rot); | |
ctx.translate(-w / 2, -h / 2); | |
if (t % (speed * 540) === 0) { | |
this.letter = String.fromCharCode( | |
this.letters[random(0, this.letters.length)] | |
); | |
this.size = random(30, 400); | |
ctx.font = `${this.size}px serif`; | |
this.x = random(0, w); | |
this.y = random(0, h); | |
ctx.strokeStyle = randomColor(0, 255, 0.5, 0.5); | |
} | |
if (t % (speed * 1620) === 0) { | |
this.rot++; | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Harmonie { | |
constructor() { | |
this.x = random(0, w); | |
this.y = random(0, h); | |
this.letters = [ | |
2902, | |
2908, | |
2909, | |
2911, | |
2913, | |
2915, | |
2918, | |
2919, | |
2921, | |
2922, | |
2924, | |
2925, | |
2926, | |
2927, | |
2928, | |
2929, | |
2930, | |
2931, | |
2932, | |
2934, | |
2938, | |
2947, | |
2949, | |
2952, | |
2953, | |
2960, | |
2962, | |
2970, | |
2972, | |
2975, | |
2980, | |
2984, | |
2986, | |
2990, | |
2991, | |
2992, | |
2994, | |
2997, | |
2998 | |
]; | |
this.letter1 = String.fromCharCode( | |
this.letters[random(0, this.letters.length)] | |
); | |
this.letter2 = String.fromCharCode( | |
this.letters[random(0, this.letters.length)] | |
); | |
this.size = random(20, 50); | |
this.rot = 23; | |
ctx.strokeStyle = randomColor(); | |
ctx.fillStyle = randomColor(); | |
ctx.textAlign = "center"; | |
ctx.font = `${this.size}px serif`; | |
this.draw = () => { | |
if (t % speed === 0) { | |
if (t % 2) { | |
ctx.strokeText(this.letter1, this.x, this.y); | |
} else { | |
ctx.fillText(this.letter2, this.x, this.y); | |
} | |
ctx.font = `${this.size}px serif`; | |
} | |
t++; | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate((this.rot * Math.PI) / 180); | |
ctx.translate(-w / 2, -h / 2); | |
if (t % (speed * 180) === 0) { | |
this.size = random(20, 50); | |
ctx.font = `${this.size}px serif`; | |
this.x = random(0, w); | |
this.y = random(0, h); | |
this.rot = random(1, 400); | |
ctx.strokeStyle = randomColor(); | |
ctx.fillStyle = randomColor(); | |
} | |
if (t % (speed * 900) === 0) { | |
this.letter1 = String.fromCharCode( | |
this.letters[random(0, this.letters.length)] | |
); | |
this.letter2 = String.fromCharCode( | |
this.letters[random(0, this.letters.length)] | |
); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Portals { | |
constructor() { | |
this.cols = random(3, 13); | |
this.rows = random(3, 13); | |
this.width = random(20, w / this.cols + 3); | |
this.height = random(20, w / this.rows + 3); | |
this.round = random(0, 60); | |
this.rot = random(1, 33); | |
ctx.strokeStyle = randomColor(0, 255, 1, 1); | |
ctx.globalCompositeOperation = "hard-light"; | |
ctx.fillStyle = randomColor(0, 255, 0.4, 0.4); | |
ctx.globalAlpha = 0.5; | |
this.draw = () => { | |
if (t % speed === 0) { | |
for (let row = 0; row <= this.rows; row++) { | |
for (let col = 0; col <= this.cols; col++) { | |
ctx.roundRect( | |
col * (w / this.cols), | |
row * (h / this.rows), | |
this.width, | |
this.height, | |
{ | |
upperLeft: this.round, | |
upperRight: this.round, | |
lowerLeft: this.round, | |
lowerRight: this.round | |
}, | |
true, | |
true | |
); | |
} | |
} | |
} | |
t++; | |
if (t % (speed * 80) === 0) { | |
this.cols = random(3, 13); | |
this.rows = random(3, 13); | |
this.width = random(20, w / 8); | |
this.height = random(20, w / 8); | |
this.round = random(0, 60); | |
this.rot = random(1, 33); | |
ctx.strokeStyle = randomColor(0, 255, 1, 1); | |
ctx.fillStyle = randomColor(0, 255, 0.4, 0.4); | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(this.rot); | |
ctx.translate(-w / 2, -h / 2); | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Sandala { | |
constructor() { | |
this.cols = random(5, 12); | |
this.rows = random(5, 12); | |
this.letters = [ | |
3201, | |
3202, | |
3203, | |
3204, | |
3206, | |
3207, | |
3208, | |
3209, | |
3212, | |
3214, | |
3215, | |
3218, | |
3219, | |
3221, | |
3222, | |
3223, | |
3226, | |
3227, | |
3228, | |
3231, | |
3232, | |
3234, | |
3236, | |
3238, | |
3244, | |
3248, | |
3249, | |
3250, | |
3254, | |
3255, | |
3260, | |
3261, | |
3263, | |
3270, | |
3294, | |
3298 | |
]; | |
this.rot = random(1, 60); | |
ctx.strokeStyle = randomColor(0, 255, 1, 1); | |
ctx.globalCompositeOperation = "soft-light"; | |
this.draw = () => { | |
if (t % speed === 0) { | |
for (let row = 0; row <= this.rows; row++) { | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate((this.rot * Math.PI) / 180); | |
ctx.translate(-w / 2, -h / 2); | |
for (let col = 0; col <= this.cols; col++) { | |
ctx.strokeText( | |
String.fromCharCode(this.letters[random(0, this.letters.length)]), | |
row * (w / this.cols), | |
col * (h / this.rows) | |
); | |
} | |
} | |
} | |
t++; | |
if (t % (speed * 80) === 0) { | |
this.cols = random(5, 12); | |
this.rows = random(5, 12); | |
this.rot = random(1, 60); | |
ctx.strokeStyle = randomColor(0, 255, 1, 1); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class GhostlyShapes { | |
constructor() { | |
this.blends = [ | |
"source-atop", | |
"lighter", | |
"xor", | |
"multiply", | |
"screen", | |
"overlay", | |
"darken", | |
"lighten", | |
"color-dodge", | |
"color-burn", | |
"hard-light", | |
"soft-light", | |
"difference", | |
"exclusion", | |
"hue", | |
"saturation", | |
"color", | |
"luminosity" | |
]; | |
this.blend = this.blends[random(0, this.blends.length)]; | |
this.cornersX = [0, w, w, 0]; | |
this.cornersY = [0, 0, h, h]; | |
this.cornerX = 0; | |
this.cornerY = 0; | |
this.rotation = random(1, 30); | |
this.radius = random(30, w); | |
ctx.fillStyle = randomColor(0, 255, 0.015, 0.05); | |
ctx.globalCompositeOperation = this.blend; | |
this.draw = () => { | |
if (t % speed === 0) { | |
ctx.arc( | |
this.cornersX[this.cornerX], | |
this.cornersY[this.cornerY], | |
this.radius, | |
Math.random(), | |
Math.random() * Math.PI, | |
true | |
); | |
this.cornerX = | |
this.cornerX + 1 >= this.cornersX.length ? 0 : this.cornerX + 1; | |
this.cornerY = | |
this.cornerY + 1 >= this.cornersY.length ? 0 : this.cornerY + 1; | |
ctx.fill(); | |
ctx.beginPath(); | |
} | |
t++; | |
if (t % (speed * 130) === 0) { | |
this.blend = this.blends[random(0, this.blends.length)]; | |
ctx.globalCompositeOperation = this.blend; | |
this.radius = random(30, w); | |
this.rotation = random(1, 30); | |
ctx.beginPath(); | |
ctx.strokeStyle = randomColor(); | |
ctx.fillStyle = randomColor(0, 255, 0.015, 0.05); | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate((this.rotation * Math.PI) / 180); | |
ctx.translate(-w / 2, -h / 2); | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class PsychoRainbow { | |
constructor() { | |
this.blends = ["hard-light", "difference", "color", "luminosity"]; | |
this.blend = this.blends[random(0, this.blends.length)]; | |
this.rows = random(3, 10); | |
this.rot = random(1, 50); | |
this.height = h / this.rows; | |
this.colors = []; | |
for (let i = 0; i <= this.rows; i++) { | |
this.colors.push(randomColor(0, 255, 0.1, 0.5)); | |
} | |
ctx.globalCompositeOperation = this.blend; | |
this.draw = () => { | |
if (t % speed === 0) { | |
for (let i = 0; i <= this.rows; i++) { | |
ctx.fillStyle = this.colors[i]; | |
ctx.fillRect(-w, i * this.height, 3 * w, this.height); | |
} | |
} | |
t++; | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(this.rot); | |
ctx.translate(-w / 2, -h / 2); | |
if (t % (speed * 100) === 0) { | |
this.rows = random(3, 10); | |
this.rot = random(1, 50); | |
this.height = h / this.rows; | |
this.colors = []; | |
for (let i = 0; i <= this.rows; i++) { | |
this.colors.push(randomColor(0, 255, 0.1, 0.5)); | |
} | |
} | |
if (t % (speed * 700) === 0) { | |
this.blend = this.blends[random(0, this.blends.length)]; | |
ctx.globalCompositeOperation = this.blend; | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Hallucinate { | |
constructor() { | |
this.rows = random(3, 17); | |
this.rot = random(1, 180); | |
this.height = h / this.rows; | |
this.colors = []; | |
for (let i = 0; i <= this.rows; i++) { | |
this.colors.push(randomColor()); | |
} | |
ctx.globalCompositeOperation = "soft-light"; | |
this.draw = () => { | |
if (t % speed === 0) { | |
for (let i = 0; i <= this.rows; i++) { | |
ctx.fillStyle = this.colors[i]; | |
ctx.fillRect(-w, i * this.height, 3 * w, this.height); | |
} | |
} | |
t++; | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate(this.rot); | |
ctx.translate(-w / 2, -h / 2); | |
if (t % (speed * 150) === 0) { | |
this.rows = random(3, 17); | |
this.rot = random(1, 180); | |
this.height = h / this.rows; | |
this.colors = []; | |
for (let i = 0; i <= this.rows; i++) { | |
this.colors.push(randomColor()); | |
} | |
} | |
if (t % (speed * 750) === 0) { | |
ctx.clearRect(-w, -h, 3 * w, 3 * h); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Hive { | |
constructor() { | |
this.rows = random(3, 10); | |
this.height = h / this.rows; | |
this.angles = [9, 10, 12, 16, 20, 30, 36, 45, 60]; | |
this.rot = this.angles[random(1, this.angles.length)]; | |
ctx.globalCompositeOperation = "overlay"; | |
ctx.strokeStyle = randomColor(); | |
ctx.shadowColor = randomColor(); | |
ctx.blur = 7; | |
ctx.lineWidth = random(7, 18); | |
this.draw = () => { | |
if (t % speed === 0) { | |
for (let i = 0; i <= this.rows; i++) { | |
ctx.strokeRect( | |
random(0, w), | |
i * this.height, | |
random(0, w), | |
this.height | |
); | |
} | |
} | |
t++; | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate((this.rot * Math.PI) / 180); | |
ctx.translate(-w / 2, -h / 2); | |
if (t % (speed * 125) === 0) { | |
ctx.shadowColor = randomColor(); | |
this.rows = random(3, 10); | |
this.rot = this.angles[random(1, this.angles.length)]; | |
this.height = h / this.rows; | |
ctx.strokeStyle = randomColor(); | |
ctx.globalCompositeOperation = "overlay"; | |
} | |
if (t % (speed * 500) === 0) { | |
ctx.globalCompositeOperation = "difference"; | |
} | |
if (t % (speed * 1500) === 0) { | |
ctx.globalCompositeOperation = "hard-light"; | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class Boxes { | |
constructor() { | |
this.rows = random(3, 17); | |
this.height = h / this.rows; | |
this.cols = random(3, 17); | |
this.width = w / this.cols; | |
this.angles = [15, 20, 24, 30, 36, 45, 48, 72, 80, 90]; | |
this.rot = this.angles[random(0, this.angles.length)]; | |
ctx.strokeStyle = "black"; | |
ctx.fillStyle = randomColor(0, 255, 0.075, 0.075); | |
this.draw = () => { | |
if (t % speed === 0) { | |
for (let i = 0; i <= this.rows; i++) { | |
ctx.fillRect( | |
i * this.width, | |
i * this.height, | |
this.width / 2, | |
this.height / 2 | |
); | |
ctx.strokeRect( | |
i * this.width, | |
i * this.height, | |
this.width / 2, | |
this.height / 2 | |
); | |
} | |
} | |
t++; | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate((this.rot * Math.PI) / 180); | |
ctx.translate(-w / 2, -h / 2); | |
if (t % (speed * 100) === 0) { | |
this.cols = random(3, 17); | |
this.width = w / this.cols; | |
this.rows = random(3, 17); | |
this.height = h / this.rows; | |
} | |
if (t % (speed * 200) === 0) { | |
this.rot = this.angles[random(0, this.angles.length)]; | |
} | |
if (t % (speed * 400) === 0) { | |
ctx.fillStyle = randomColor(0, 255, 0.075, 0.075); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
class DigitalArt { | |
constructor() { | |
this.x = random(75, w - 75); | |
this.y = random(30, h - 30); | |
this.rot = random(3, 40); | |
this.size = random(12, 36); | |
ctx.font = `${this.size}px serif`; | |
ctx.fillStyle = randomColor(); | |
this.draw = () => { | |
if (t % speed === 0) { | |
let letter = t % 2 ? "0" : "1"; | |
if (t % 2) { | |
ctx.font = `${this.size * 2}px serif`; | |
ctx.textAlign = "left"; | |
ctx.textBaseline = "top"; | |
ctx.fillText(letter + "-", w / 2, h / 2); | |
} else { | |
ctx.font = `${this.size * 2}px serif`; | |
ctx.textAlign = "right"; | |
ctx.textBaseline = "bottom"; | |
ctx.fillText(letter + "_", w / 2, h / 2); | |
} | |
ctx.font = `${this.size}px serif`; | |
ctx.fillText(letter, this.x, this.y); | |
} | |
ctx.translate(w / 2, h / 2); | |
ctx.rotate((this.rot * Math.PI) / 180); | |
ctx.translate(-w / 2, -h / 2); | |
t++; | |
if (t % (speed * 90) === 0) { | |
this.x = random(75, w - 75); | |
this.y = random(30, h - 30); | |
this.size = random(12, 36); | |
ctx.font = `${this.size}px serif`; | |
ctx.fillStyle = randomColor(); | |
} | |
if (t % (speed * 450) === 0) { | |
this.rot = random(3, 40); | |
} | |
interval = requestAnimationFrame(this.draw); | |
}; | |
} | |
} | |
// END OF CLASSES | |
// initial setup of canvas settings and listeners | |
function init() { | |
// display some user tips on screen | |
displayMsg("WELCOME"); | |
setTimeout(() => { | |
displayMsg("PRESS H FOR HELP"); | |
}, 10000); | |
setTimeout(() => { | |
displayMsg("TIP: F FOR FULLSCREEN"); | |
}, 20000); | |
// set the basic canvas settings | |
ctx.strokeStyle = randomColor(5, 255, 0.8, 0.8); | |
ctx.fillStyle = randomColor(5, 255, 0.5, 0.5); | |
ctx.imageSmoothingQuality = "high"; | |
ctx.lineWidth = 1; | |
ctx.shadowBlur = 0; | |
ctx.save(); | |
// LISTENERS | |
//change canvas size on window resize | |
window.addEventListener("resize", () => { | |
w = canvas.width = window.innerWidth; | |
h = canvas.height = window.innerHeight; | |
canvas.click(); | |
}); | |
// keystroke listeners | |
window.addEventListener("keyup", (e) => { | |
// spacebar listener creates new spiral | |
if (e.keyCode === 32) { | |
canvas.click(); | |
} | |
// f key for fullscreen | |
if (e.keyCode === 70) { | |
document.body.requestFullscreen(); | |
} | |
// i key increases auto-change time | |
if (e.keyCode === 73) { | |
autoChange += 10; | |
if (autoChange > 300) autoChange = 300; | |
displayMsg(`Auto-change: ${autoChange}secs`); | |
} | |
// d key decreases auto-change time | |
if (e.keyCode === 68) { | |
autoChange -= 10; | |
if (autoChange < 10) autoChange = 10; | |
displayMsg(`Auto-change: ${autoChange}secs`); | |
} | |
// m key toggles manual mode | |
if (e.keyCode === 77) { | |
manual = !manual; | |
displayMsg(manual ? "Manual mode" : "Auto mode"); | |
} | |
// s key silences algorithm change messages | |
if (e.keyCode === 83) { | |
silent = !silent; | |
displayMsg(silent ? "Silent mode" : "Display mode"); | |
algosDisplay.textContent = ""; | |
algosDisplay.style.display = "none"; | |
} | |
// h key toggles help screen view | |
if (e.keyCode === 72) { | |
helpView = !helpView; | |
if (helpView) { | |
help.style.display = "block"; | |
} else { | |
help.style.display = "none"; | |
} | |
} | |
}); | |
// make algorithms auto-change if not in manual mode | |
if (!manual) { | |
regen = setInterval(() => { | |
canvas.click(); | |
}, autoChange * 1000); | |
} | |
} | |
// run init and start a random class spiral | |
init(); | |
chooseAlgos(); | |
// the click listener resets settings and draws a new spiral | |
canvas.addEventListener("click", () => { | |
// clear any timers | |
cancelAnimationFrame(interval); | |
interval = null; | |
clearInterval(regen); | |
t = 0; | |
stagger = 0; | |
// setup new auto-change timer if not in manual mode | |
if (!manual) { | |
regen = setInterval(() => { | |
canvas.click(); | |
}, autoChange * 1000); | |
} | |
// new random speed | |
speed = random(2, 6); | |
// canvas resets | |
ctx.restore(); | |
// picks a transition mode | |
canvas.style.backgroundColor = "transparent"; | |
clearMethod(); | |
ctx.strokeStyle = randomColor(5, 255, 0.8, 0.8); | |
ctx.fillStyle = randomColor(5, 255, 0.5, 0.5); | |
ctx.beginPath(); | |
// selects next algorithm | |
chooseAlgos(); | |
}); | |
// helper function for random nums | |
function random(min, max) { | |
const num = Math.floor(Math.random() * (max - min)) + min; | |
return num; | |
} | |
// helper function for random colors | |
function randomColor(minC = 0, maxC = 255, minA = 1, maxA = minA) { | |
const r = random(minC, maxC); | |
const g = random(minC, maxC); | |
const b = random(minC, maxC); | |
const a = +(Math.random() * (maxA - minA) + minA).toFixed(3); | |
return `rgba(${r}, ${g}, ${b}, ${a})`; | |
} | |
// chooses a transition method when spirals change | |
function clearMethod() { | |
let pick = Math.random(); | |
// clears to black a portion of the screen based on the canvas size and its rotation at the moment | |
if (pick < 0.25) { | |
ctx.clearRect(0, 0, w, h); | |
// makes semi-transparent a portion of the screen based on the canvas size and its rotation at the moment | |
} else if (pick < 0.5) { | |
ctx.fillStyle = "rgba(0, 0, 0, 0.75)"; | |
ctx.fillRect(0, 0, w, h); | |
} else if (pick < 0.75) { | |
// colors a portion of the screen based on the canvas size and its rotation at the moment, with random transparency | |
ctx.fillStyle = randomColor(5, 255, 0.15, 0.9); | |
ctx.fillRect(0, 0, w, h); | |
// completely fills the screen with black | |
} else { | |
canvas.width = canvas.height = 0; | |
canvas.width = w; | |
canvas.height = h; | |
} | |
ctx.strokeStyle = randomColor(5, 255, 0.8, 0.8); | |
} | |
// displays the current algorithm on the screen for a few seconds when changing | |
function displayAlgos(algo) { | |
// only if silent mode is not on | |
if (!silent) { | |
clearTimeout(algoTimer); | |
algosDisplay.textContent = algo; | |
algosDisplay.style.display = "block"; | |
algoTimer = setTimeout(() => { | |
algosDisplay.style.display = "none"; | |
algosDisplay.textContent = ""; | |
}, 5000); | |
} | |
} | |
// displays messages on the screen for a few seconds in response to user actions | |
function displayMsg(message) { | |
clearTimeout(msgTimer); | |
msg.textContent = message; | |
msg.style.display = "block"; | |
msgTimer = setTimeout(() => { | |
msg.style.display = "none"; | |
msg.textContent = ""; | |
}, 7500); | |
} | |
let pointer; | |
canvas.addEventListener("mousemove", () => { | |
if (pointer) { | |
pointer = null; | |
} | |
canvas.style.cursor = "pointer"; | |
pointer = setTimeout(() => { | |
canvas.style.cursor = "none"; | |
}, 5000); | |
}); | |
// MUSIC PLAYER | |
// DOM references | |
const player = document.getElementById("player"); | |
const input = document.getElementById("input"); | |
const label = document.getElementById("click-label"); | |
const playList = document.getElementById("playlist"); | |
const playBtn = document.getElementById("play"); | |
const playIcon = document.getElementById("play-pause-icon"); | |
const stopBtn = document.getElementById("stop"); | |
const prevBtn = document.getElementById("prev"); | |
const nextBtn = document.getElementById("next"); | |
const audio = document.getElementById("audio"); | |
const progress = document.getElementById("progress-percent"); | |
// initial settings | |
let playerShow = true; | |
let trackList = []; | |
let currentSong = 0; | |
let isPlaying = false; | |
let playlistEls; | |
// listener for file input | |
input.addEventListener("change", handleFiles, false); | |
// handles the files and adds them to playlist | |
function handleFiles() { | |
// pause if playing and re-init settings | |
audio.pause(); | |
isPlaying = false; | |
playIcon.name = "play-outline"; | |
playList.innerHTML = ""; | |
currentSong = 0; | |
trackList = []; | |
const files = this.files; | |
// add li for each song, create playlist | |
for (let i = 0; i < files.length; i++) { | |
let listItem = document.createElement("li"); | |
listItem.classList.add("list-item"); | |
listItem.textContent = files[i].name.slice(0, files[i].name.indexOf(".")); | |
playList.appendChild(listItem); | |
let objectURL = window.URL.createObjectURL(files[i]); | |
trackList.push(objectURL); | |
} | |
let song = trackList[currentSong]; | |
audio.src = song; | |
// style and prepare playlist for playback | |
playlistEls = document.getElementsByClassName("list-item"); | |
playlistEls[currentSong].scrollIntoView(); | |
playlistEls[currentSong].style.color = "rgba(255, 165, 0, 0.5)"; | |
} | |
// play or pause current song | |
function playTrack() { | |
// if paused, play | |
if (!isPlaying && playlistEls) { | |
isPlaying = !isPlaying; | |
playIcon.name = "pause-outline"; | |
updatePlaylistStyle(); | |
audio.play(); | |
} else { | |
// if playing, pause | |
if (playlistEls) { | |
isPlaying = !isPlaying; | |
playlistEls[currentSong].style.color = "rgba(255, 165, 0, 0.5)"; | |
playIcon.name = "play-outline"; | |
audio.pause(); | |
} | |
} | |
} | |
// stop the track, rewind it and de-saturate color of li in playlist | |
function stopPlayback() { | |
if (isPlaying) { | |
audio.pause(); | |
audio.currentTime = 0; | |
isPlaying = false; | |
playIcon.name = "play-outline"; | |
[...playlistEls].forEach((el) => (el.style.color = "#555")); | |
playlistEls[currentSong].style.color = "rgba(255, 165, 0, 0.5)"; | |
} else { | |
if (playlistEls) { | |
audio.currentTime = 0; | |
} | |
} | |
} | |
// cue the next track and play it if play is on | |
function playPrev() { | |
if (playlistEls) { | |
audio.pause(); | |
audio.currentTime = 0; | |
progress.value = 0; | |
currentSong--; | |
if (currentSong < 0) currentSong = trackList.length - 1; | |
updatePlaylistStyle(); | |
audio.src = trackList[currentSong]; | |
if (isPlaying) { | |
audio.play(); | |
} else { | |
playlistEls[currentSong].style.color = "rgba(255, 165, 0, 0.5)"; | |
} | |
} | |
} | |
// cue the previous track and play it if play is on | |
function playNext() { | |
if (playlistEls) { | |
audio.pause(); | |
audio.currentTime = 0; | |
progress.value = 0; | |
currentSong++; | |
if (currentSong > trackList.length - 1) currentSong = 0; | |
updatePlaylistStyle(); | |
audio.src = trackList[currentSong]; | |
if (isPlaying) { | |
audio.play(); | |
} else { | |
playlistEls[currentSong].style.color = "rgba(255, 165, 0, 0.5)"; | |
} | |
} | |
} | |
// calculates and displays the current track's progress | |
function displayProgress() { | |
const currentTime = audio.currentTime; | |
const progressPercent = (currentTime / audio.duration) * 100; | |
progress.value = Number.isFinite(progressPercent) | |
? progressPercent.toFixed(2) | |
: "0"; | |
} | |
// skips to the clicked time on the progress bar | |
function scrub(e) { | |
if (playlistEls) { | |
const scrubTime = (e.offsetX / progress.offsetWidth) * audio.duration; | |
audio.currentTime = scrubTime; | |
if (isPlaying) { | |
audio.play(); | |
} | |
} | |
} | |
// helper function for styling the playlist after changes | |
function updatePlaylistStyle() { | |
[...playlistEls].forEach((el) => (el.style.color = "#555")); | |
playlistEls[currentSong].style.color = "orange"; | |
playlistEls[currentSong].scrollIntoView(); | |
} | |
// music player event listeners | |
playBtn.addEventListener("click", playTrack); | |
stopBtn.addEventListener("click", stopPlayback); | |
nextBtn.addEventListener("click", playNext); | |
prevBtn.addEventListener("click", playPrev); | |
audio.addEventListener("timeupdate", displayProgress); | |
audio.addEventListener("ended", playNext); | |
progress.addEventListener("mousedown", () => audio.pause()); | |
progress.addEventListener("mouseup", scrub); | |
window.addEventListener("keyup", hidePlayer); | |
// hide/show the player with the p key | |
function hidePlayer(e) { | |
if (e.keyCode === 80) { | |
if (playerShow) { | |
playerShow = !playerShow; | |
player.style.display = "none"; | |
} else { | |
playerShow = !playerShow; | |
player.style.display = "block"; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@import url("https://fonts.googleapis.com/css2?family=DM+Mono:wght@500&display=swap"); | |
body { | |
background: black; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
margin: 0; | |
font-family: "DM Mono", monospace; | |
letter-spacing: 2px; | |
font-size: 0.75em; | |
color: white; | |
text-shadow: 1px 1px black, -1px -1px black; | |
} | |
#canvas { | |
cursor: pointer; | |
} | |
/* HUD */ | |
#hud { | |
background: transparent; | |
position: absolute; | |
text-align: right; | |
bottom: 2em; | |
right: 2.5em; | |
opacity: 0.7; | |
z-index: 1; | |
} | |
#help { | |
position: absolute; | |
z-index: 2; | |
opacity: 0.9; | |
background: rgba(0, 0, 0, 0.8); | |
padding: 1em; | |
font-family: "Oswald", sans-serif; | |
width: 75vw; | |
height: auto; | |
text-align: center; | |
pointer-events: none; | |
max-width: 600px; | |
display: none; | |
} | |
h1 { | |
margin-bottom: 0; | |
color: orangered; | |
font-size: 2.25em; | |
} | |
h4 { | |
margin-top: 0; | |
color: lightgray; | |
} | |
h3 { | |
margin-top: 0; | |
color: limegreen; | |
font-size: 1.4em; | |
} | |
p { | |
letter-spacing: 0; | |
} | |
.keys { | |
color: orange; | |
} | |
.text { | |
text-align: left; | |
} | |
.help { | |
color: limegreen; | |
font-size: 1.2em; | |
} | |
/* PLAYER */ | |
input[type="file"] { | |
display: none; | |
} | |
#player { | |
background: #111; | |
display: block; | |
position: absolute; | |
top: 0; | |
width: 100vw; | |
overflow: hidden; | |
font-size: 1.15em; | |
font-family: "Oswald", sans-serif; | |
opacity: 0.7; | |
border-bottom-left-radius: 15px; | |
border-bottom-right-radius: 15px; | |
text-shadow: none; | |
} | |
#player:hover { | |
opacity: 1; | |
background: #171717; | |
} | |
#picker { | |
padding: 0 1em 0em 1em; | |
display: flex; | |
justify-content: space-between; | |
} | |
#picker label { | |
background: rgba(59, 136, 253, 0.8); | |
padding: 0.1em 0.5em; | |
margin-top: 0.5em; | |
font-size: 0.7em; | |
letter-spacing: 0.06em; | |
color: whitesmoke; | |
border-radius: 3px; | |
cursor: pointer; | |
align-self: center; | |
transition: all 0.2s; | |
} | |
#picker label:hover { | |
background: rgba(255, 69, 0, 0.6); | |
} | |
#playlist { | |
color: #999; | |
font-size: 0.9em; | |
padding: 0.25em 1em; | |
max-height: 22px; | |
overflow-y: scroll; | |
margin-bottom: 0.1em; | |
margin-left: 0.2em; | |
user-select: none; | |
} | |
#playlist li { | |
margin-top: 4px; | |
border-bottom: 1px dotted rgba(85, 85, 85, 0.4); | |
} | |
.list-item { | |
margin-left: 4px; | |
} | |
#controls { | |
text-align: center; | |
padding-top: 0.5em; | |
align-self: center; | |
} | |
#controls button { | |
color: orange; | |
font-size: 1.15em; | |
background: transparent; | |
border: 1px solid whitesmoke; | |
border-radius: 5px; | |
text-align: center; | |
line-height: 0.5; | |
cursor: pointer; | |
margin-right: 0.2em; | |
transition: all 0.2s; | |
outline: none; | |
} | |
#controls button:hover { | |
border-color: orangered; | |
color: whitesmoke; | |
} | |
progress { | |
margin: 0 auto; | |
width: 80%; | |
cursor: pointer; | |
display: block; | |
padding-bottom: 0.5em; | |
} | |
@media (max-width: 545px) { | |
#picker { | |
display: flex; | |
flex-direction: column; | |
} | |
#click-label { | |
position: absolute; | |
right: 1em; | |
} | |
#playlist { | |
display: inline; | |
text-align: center; | |
margin-bottom: 0; | |
font-size: 0.85em; | |
max-height: 17px; | |
} | |
#controls { | |
margin-top: 0; | |
padding-top: 0.2em; | |
margin-bottom: 5px; | |
} | |
#controls button { | |
font-size: 1em; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment