window.addEventListener('load', function(){ const canvas = document.getElementById('canvas1'); const ctx = canvas.getContext('2d'); canvas.width = 900; canvas.height = 900; // canvas settings ctx.lineCap = 'round'; ctx.shadowColor = 'rgba(0,0,0,0.7)'; ctx.shadowOffsetX = 10; ctx.shadowOffsetY = 5; ctx.shadowBlur = 10; const canvas2 = document.getElementById('canvas2'); const ctx2 = canvas2.getContext('2d'); canvas2.width = window.innerWidth; canvas2.height = window.innerHeight; class Fractal { constructor(canvasWidth, canvasHeight){ this.canvasWidth = canvasWidth; this.canvasHeight = canvasHeight; this.size = this.canvasWidth < this.canvasHeight ? this.canvasHeight * 0.3 : this.canvasHeight * 0.3; this.maxLevel = 5; this.scale = 0.8; this.branches = Math.random() * 3 + 1; this.spread = Math.random() * 1 - 0.5; this.color = 'hsl(' + Math.random() * 360 + ', 100%, 50%)'; this.lineWidth = 6; this.sides = Math.floor(Math.random() * 4 + 3); this.skew1 = 1; this.skew2 = 1; this.center = 0; } #drawBranch(level, context){ if (level > this.maxLevel) return; context.beginPath(); context.moveTo(0,0); context.lineTo(this.size, 0); context.stroke(); context.save(); context.translate(this.size * 0.1, 0); context.scale(this.scale, this.scale); context.save(); context.rotate(this.spread * this.skew1); this.#drawBranch(level + 1, context); context.restore(); context.restore(); context.save(); context.translate(this.size * 0.5, 0); context.scale(this.scale * 0.4, this.scale * 0.4); context.save(); context.rotate(this.spread * this.skew1 * 1.5); this.#drawBranch(level + 1, context); context.restore(); context.restore(); context.save(); context.translate(this.size * 0.6, 0); context.scale(this.scale * 0.3, this.scale * 0.3); context.save(); context.rotate(this.spread * 0.5 * (this.skew1 * 2)); this.#drawBranch(level + 1, context); context.restore(); context.restore(); context.beginPath(); context.arc(this.size * 1.1,0,this.size * 0.09, 0, Math.PI * 2); context.fill(); } draw(context){ context.clearRect(0, 0, this.canvasWidth, this.canvasHeight); context.strokeStyle = this.color; context.fillStyle = this.color; context.lineWidth = this.lineWidth; context.save(); context.translate(this.canvasWidth/2, this.canvasHeight/2); for (let i = 0; i < this.sides; i++){ context.rotate((Math.PI * 2)/this.sides); this.#drawBranch(0, context); } context.restore(); } } class Rain { constructor(canvasWidth, canvasHeight, image, ctx){ this.canvasWidth = canvasWidth; this.canvasHeight = canvasHeight; this.numberOfParticles = 10; this.particles = []; this.image = image; this.ctx = ctx; this.initialize() } initialize(){ for (let i = 0; i < this.numberOfParticles; i++){ this.particles.push(new Particle(this.canvasWidth, this.canvasHeight, this.image)) } } run(){ this.particles.forEach(particle => { particle.draw(this.ctx); particle.update(); }); } } class Particle { constructor(canvasWidth, canvasHeight, image){ this.canvasWidth = canvasWidth; this.canvasHeight = canvasHeight; this.image = image; this.sizeModifier = Math.random() * 0.4 + 0.1; this.width = this.image.width * this.sizeModifier; this.height = this.image.height * this.sizeModifier; this.x = Math.random() * this.canvasWidth; this.y = Math.random() * this.canvasHeight; this.speed = Math.random() * 1 + 1; this.image = image; this.angle = 0; this.va = Math.random() * 0.05 - 0.025; } update(){ this.angle += this.va; if (this.y < -this.height) { this.y = this.canvasHeight + this.height; this.x = Math.random() * (this.canvasWidth - this.width); this.angle = 0; } else this.y -= this.speed; } draw(context){ context.save(); context.translate(this.x, this.y ); context.rotate(this.angle); context.drawImage(this.image, -this.width/2, -this.height/2, this.width, this.height) context.restore(); } } const fractal = new Fractal(canvas.width, canvas.height); fractal.draw(ctx); const fractalImage = new Image(); fractalImage.src = canvas.toDataURL(); fractalImage.onload = function(){ const rain = new Rain(canvas2.width, canvas2.height, fractalImage, ctx2); rain.initialize(); function animate(){ ctx2.clearRect(0, 0, canvas2.width, canvas2.height); rain.run(); requestAnimationFrame(animate); } animate(); } })