烟花 光影

 WEB烟花效果——Canvas实现 - 朱雀桥边 - 博客园 https://www.cnblogs.com/visualiz/p/fireworks.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
	</body>
	<style>
		body {
			background-color: #000000;
			margin: 0px;
			overflow: hidden;
		}
	</style>
	<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
	<script>
		var SCREEN_WIDTH = window.innerWidth,
			SCREEN_HEIGHT = window.innerHeight,
			mousePos = {
				x: 400,
				y: 300
			},
			// create canvas
			canvas = document.createElement("canvas"),
			context = canvas.getContext("2d"),
			particles = [],
			rockets = [],
			MAX_PARTICLES = 400,
			colorCode = 0;

		// init
		$(document).ready(function() {
			document.body.appendChild(canvas);
			canvas.width = SCREEN_WIDTH;
			canvas.height = SCREEN_HEIGHT;
			setInterval(launch, 800);
			setInterval(loop, 1000 / 50);
		});

		// update mouse position
		$(document).mousemove(function(e) {
			e.preventDefault();
			mousePos = {
				x: e.clientX,
				y: e.clientY
			};
		});

		// launch more rockets!!!
		$(document).mousedown(function(e) {
			for (var i = 0; i < 5; i++) {
				launchFrom((Math.random() * SCREEN_WIDTH * 2) / 3 + SCREEN_WIDTH / 6);
			}
		});

		function launch() {
			launchFrom(mousePos.x);
		}

		function launchFrom(x) {
			if (rockets.length < 10) {
				var rocket = new Rocket(x);
				rocket.explosionColor = Math.floor((Math.random() * 360) / 10) * 10;
				rocket.vel.y = Math.random() * -3 - 4;
				rocket.vel.x = Math.random() * 6 - 3;
				rocket.size = 8;
				rocket.shrink = 0.999;
				rocket.gravity = 0.01;
				rockets.push(rocket);
			}
		}

		function loop() {
			// update screen size
			if (SCREEN_WIDTH != window.innerWidth) {
				canvas.width = SCREEN_WIDTH = window.innerWidth;
			}
			if (SCREEN_HEIGHT != window.innerHeight) {
				canvas.height = SCREEN_HEIGHT = window.innerHeight;
			}

			// clear canvas
			context.fillStyle = "rgba(0, 0, 0, 0.05)";
			context.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);

			var existingRockets = [];

			for (var i = 0; i < rockets.length; i++) {
				// update and render
				rockets[i].update();
				rockets[i].render(context);

				// calculate distance with Pythagoras
				var distance = Math.sqrt(
					Math.pow(mousePos.x - rockets[i].pos.x, 2) +
					Math.pow(mousePos.y - rockets[i].pos.y, 2)
				);

				// random chance of 1% if rockets is above the middle
				var randomChance =
					rockets[i].pos.y < (SCREEN_HEIGHT * 2) / 3 ?
					Math.random() * 100 <= 1 :
					false;

				/* Explosion rules
		 - 80% of screen
		 - going down
		 - close to the mouse
		 - 1% chance of random explosion
		 */
				if (
					rockets[i].pos.y < SCREEN_HEIGHT / 5 ||
					rockets[i].vel.y >= 0 ||
					distance < 50 ||
					randomChance
				) {
					rockets[i].explode();
				} else {
					existingRockets.push(rockets[i]);
				}
			}

			rockets = existingRockets;

			var existingParticles = [];

			for (var i = 0; i < particles.length; i++) {
				particles[i].update();

				// render and save particles that can be rendered
				if (particles[i].exists()) {
					particles[i].render(context);
					existingParticles.push(particles[i]);
				}
			}

			// update array with existing particles - old particles should be garbage collected
			particles = existingParticles;

			while (particles.length > MAX_PARTICLES) {
				particles.shift();
			}
		}

		function Particle(pos) {
			this.pos = {
				x: pos ? pos.x : 0,
				y: pos ? pos.y : 0
			};
			this.vel = {
				x: 0,
				y: 0
			};
			this.shrink = 0.97;
			this.size = 2;

			this.resistance = 1;
			this.gravity = 0;

			this.flick = false;

			this.alpha = 1;
			this.fade = 0;
			this.color = 0;
		}

		Particle.prototype.update = function() {
			// apply resistance
			this.vel.x *= this.resistance;
			this.vel.y *= this.resistance;

			// gravity down
			this.vel.y += this.gravity;

			// update position based on speed
			this.pos.x += this.vel.x;
			this.pos.y += this.vel.y;

			// shrink
			this.size *= this.shrink;

			// fade out
			this.alpha -= this.fade;
		};

		Particle.prototype.render = function(c) {
			if (!this.exists()) {
				return;
			}

			c.save();

			c.globalCompositeOperation = "lighter";

			var x = this.pos.x,
				y = this.pos.y,
				r = this.size / 2;

			var gradient = c.createRadialGradient(x, y, 0.1, x, y, r);
			gradient.addColorStop(0.1, "rgba(255,255,255," + this.alpha + ")");
			gradient.addColorStop(
				0.8,
				"hsla(" + this.color + ", 100%, 50%, " + this.alpha + ")"
			);
			gradient.addColorStop(1, "hsla(" + this.color + ", 100%, 50%, 0.1)");

			c.fillStyle = gradient;

			c.beginPath();
			c.arc(
				this.pos.x,
				this.pos.y,
				this.flick ? Math.random() * this.size : this.size,
				0,
				Math.PI * 2,
				true
			);

			c.closePath();
			c.fill();

			c.restore();
		};

		Particle.prototype.exists = function() {
			return this.alpha >= 0.1 && this.size >= 1;
		};

		function Rocket(x) {
			Particle.apply(this, [{
				x: x,
				y: SCREEN_HEIGHT
			}]);

			this.explosionColor = 0;
		}

		Rocket.prototype = new Particle();
		Rocket.prototype.constructor = Rocket;

		Rocket.prototype.explode = function() {
			var count = Math.random() * 10 + 80;

			for (var i = 0; i < count; i++) {
				var particle = new Particle(this.pos);
				var angle = Math.random() * Math.PI * 2;

				// emulate 3D effect by using cosine and put more particles in the middle
				var speed = Math.cos((Math.random() * Math.PI) / 2) * 15;

				particle.vel.x = Math.cos(angle) * speed;
				particle.vel.y = Math.sin(angle) * speed;

				particle.size = 10;

				particle.gravity = 0.2;
				particle.resistance = 0.92;
				particle.shrink = Math.random() * 0.05 + 0.93;

				particle.flick = true;
				particle.color = this.explosionColor;

				particles.push(particle);
			}
		};

		Rocket.prototype.render = function(c) {
			if (!this.exists()) {
				return;
			}

			c.save();

			c.globalCompositeOperation = "lighter";

			var x = this.pos.x,
				y = this.pos.y,
				r = this.size / 2;

			var gradient = c.createRadialGradient(x, y, 0.1, x, y, r);
			gradient.addColorStop(0.1, "rgba(255, 255, 255 ," + this.alpha + ")");
			gradient.addColorStop(1, "rgba(0, 0, 0, " + this.alpha + ")");

			c.fillStyle = gradient;

			c.beginPath();
			c.arc(
				this.pos.x,
				this.pos.y,
				this.flick ? (Math.random() * this.size) / 2 + this.size / 2 : this.size,
				0,
				Math.PI * 2,
				true
			);
			c.closePath();
			c.fill();

			c.restore();
		};
	</script>
</html>

  

 

 

 

WEB烟花效果——Canvas实现 - 朱雀桥边 - 博客园 https://www.cnblogs.com/visualiz/p/fireworks.html

 

 JavaScript动画基础:canvas绘制简单动画 - aTeacher - 博客园 https://www.cnblogs.com/cs-whut/p/13292760.html

CSS 奇技淫巧 | 妙用 drop-shadow 实现线条光影效果 - 掘金 https://juejin.cn/post/7016521320183644173

 

CSS 幻术 | 有关光影效果的黑魔法-技术圈 https://jishuin.proginn.com/p/763bfbd5b459

 

posted @ 2021-12-15 20:44  papering  阅读(59)  评论(0编辑  收藏  举报