html5新特性之canvas动画

直接贴代码
HTML:
<canvas id="canvas" width="1349" height="404"> </canvas>

CSS:
html{height:100%;background-image:-webkit-radial-gradient(ellipse farthest-corner at center top,#000d4d 0,#000105 100%);background-image:radial-gradient(ellipse farthest-corner at center top,#000d4d 0,#000105 100%);cursor:url('http://testtp5.xyz/wp-content/uploads/2018/05/bitbug_favicon.ico'),auto}
body{width:100%;height:100%;margin:0;overflow:hidden}
canvas{top:0;left:0;width:100%;height:100%;z-index:1;position:absolute}


JS:
$(document).ready(function()
{
	// 画布
	var o = document.getElementsByTagName("body")[0];
	var num = 200;
	var w = window.innerWidth;
	var h = o.offsetHeight;
	var max = 100;
	var _x = 0;
	var _y = 0;
	var _z = 150;
	var dtr = function(d) {
	  return d * Math.PI / 180;
	};

	var rnd = function() {
	  return Math.sin(Math.floor(Math.random() * 360) * Math.PI / 180);
	};
	var dist = function(p1, p2, p3) {
	  return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2) + Math.pow(p2.z - p1.z, 2));
	};

	var cam = {
	  obj: {
		x: _x,
		y: _y,
		z: _z
	  },
	  dest: {
		x: 0,
		y: 0,
		z: 1
	  },
	  dist: {
		x: 0,
		y: 0,
		z: 200
	  },
	  ang: {
		cplane: 0,
		splane: 0,
		ctheta: 0,
		stheta: 0
	  },
	  zoom: 1,
	  disp: {
		x: w / 2,
		y: h / 2,
		z: 0
	  },
	  upd: function() {
		cam.dist.x = cam.dest.x - cam.obj.x;
		cam.dist.y = cam.dest.y - cam.obj.y;
		cam.dist.z = cam.dest.z - cam.obj.z;
		cam.ang.cplane = -cam.dist.z / Math.sqrt(cam.dist.x * cam.dist.x + cam.dist.z * cam.dist.z);
		cam.ang.splane = cam.dist.x / Math.sqrt(cam.dist.x * cam.dist.x + cam.dist.z * cam.dist.z);
		cam.ang.ctheta = Math.sqrt(cam.dist.x * cam.dist.x + cam.dist.z * cam.dist.z) / Math.sqrt(cam.dist.x * cam.dist.x + cam.dist.y * cam.dist.y + cam.dist.z * cam.dist.z);
		cam.ang.stheta = -cam.dist.y / Math.sqrt(cam.dist.x * cam.dist.x + cam.dist.y * cam.dist.y + cam.dist.z * cam.dist.z);
	  }
	};

	//canvas画布
	
	var trans = {
	  parts: {
		sz: function(p, sz) {
		  return {
			x: p.x * sz.x,
			y: p.y * sz.y,
			z: p.z * sz.z
		  };
		},
		rot: {
		  x: function(p, rot) {
			return {
			  x: p.x,
			  y: p.y * Math.cos(dtr(rot.x)) - p.z * Math.sin(dtr(rot.x)),
			  z: p.y * Math.sin(dtr(rot.x)) + p.z * Math.cos(dtr(rot.x))
			};
		  },
		  y: function(p, rot) {
			return {
			  x: p.x * Math.cos(dtr(rot.y)) + p.z * Math.sin(dtr(rot.y)),
			  y: p.y,
			  z: -p.x * Math.sin(dtr(rot.y)) + p.z * Math.cos(dtr(rot.y))
			};
		  },
		  z: function(p, rot) {
			return {
			  x: p.x * Math.cos(dtr(rot.z)) - p.y * Math.sin(dtr(rot.z)),
			  y: p.x * Math.sin(dtr(rot.z)) + p.y * Math.cos(dtr(rot.z)),
			  z: p.z
			};
		  }
		},
		pos: function(p, pos) {
		  return {
			x: p.x + pos.x,
			y: p.y + pos.y,
			z: p.z + pos.z
		  };
		}
	  },
	  pov: {
		plane: function(p) {
		  return {
			x: p.x * cam.ang.cplane + p.z * cam.ang.splane,
			y: p.y,
			z: p.x * -cam.ang.splane + p.z * cam.ang.cplane
		  };
		},
		theta: function(p) {
		  return {
			x: p.x,
			y: p.y * cam.ang.ctheta - p.z * cam.ang.stheta,
			z: p.y * cam.ang.stheta + p.z * cam.ang.ctheta
		  };
		},
		set: function(p) {
		  return {
			x: p.x - cam.obj.x,
			y: p.y - cam.obj.y,
			z: p.z - cam.obj.z
		  };
		}
	  },
	  persp: function(p) {
		return {
		  x: p.x * cam.dist.z / p.z * cam.zoom,
		  y: p.y * cam.dist.z / p.z * cam.zoom,
		  z: p.z * cam.zoom,
		  p: cam.dist.z / p.z
		};
	  },
	  disp: function(p, disp) {
		return {
		  x: p.x + disp.x,
		  y: -p.y + disp.y,
		  z: p.z + disp.z,
		  p: p.p
		};
	  },
	  steps: function(_obj_, sz, rot, pos, disp) {
		var _args = trans.parts.sz(_obj_, sz);
		_args = trans.parts.rot.x(_args, rot);
		_args = trans.parts.rot.y(_args, rot);
		_args = trans.parts.rot.z(_args, rot);
		_args = trans.parts.pos(_args, pos);
		_args = trans.pov.plane(_args);
		_args = trans.pov.theta(_args);
		_args = trans.pov.set(_args);
		_args = trans.persp(_args);
		_args = trans.disp(_args, disp);
		return _args;
	  }
	};

	
	
	
	(function() {
	  "use strict";
	  var threeD = function(param) {
		this.transIn = {};
		this.transOut = {};
		this.transIn.vtx = (param.vtx);
		this.transIn.sz = (param.sz);
		this.transIn.rot = (param.rot);
		this.transIn.pos = (param.pos);
	  };

	  threeD.prototype.vupd = function() {
		this.transOut = trans.steps(

		  this.transIn.vtx,
		  this.transIn.sz,
		  this.transIn.rot,
		  this.transIn.pos,
		  cam.disp
		);
	  };

	  var Build = function() {
		this.vel = 0.04;
		this.lim = 360;
		this.diff = 200;
		this.initPos = 100;
		this.toX = _x;
		this.toY = _y;
		this.go();
	  };

	  Build.prototype.go = function() {
		this.canvas = document.getElementById("canvas");
		this.canvas.width = window.innerWidth;
		this.canvas.height = o.offsetHeight;
		this.$ = canvas.getContext("2d");
		this.$.globalCompositeOperation = 'source-over';
		this.varr = [];
		this.dist = [];
		this.calc = [];

		for (var i = 0, len = num; i < len; i++) {
		  this.add();
		}

		this.rotObj = {
		  x: 0,
		  y: 0,
		  z: 0
		};
		this.objSz = {
		  x: w / 5,
		  y: h / 5,
		  z: w / 5
		};
	  };

	  Build.prototype.add = function() {
		this.varr.push(new threeD({
		  vtx: {
			x: rnd(),
			y: rnd(),
			z: rnd()
		  },
		  sz: {
			x: 0,
			y: 0,
			z: 0
		  },
		  rot: {
			x: 20,
			y: -20,
			z: 0
		  },
		  pos: {
			x: this.diff * Math.sin(360 * Math.random() * Math.PI / 180),
			y: this.diff * Math.sin(360 * Math.random() * Math.PI / 180),
			z: this.diff * Math.sin(360 * Math.random() * Math.PI / 180)
		  }
		}));
		this.calc.push({
		  x: 360 * Math.random(),
		  y: 360 * Math.random(),
		  z: 360 * Math.random()
		});
	  };

	  Build.prototype.upd = function() {
		cam.obj.x += (this.toX - cam.obj.x) * 0.05;
		cam.obj.y += (this.toY - cam.obj.y) * 0.05;
	  };

	  Build.prototype.draw = function() {
		this.$.clearRect(0, 0, this.canvas.width, this.canvas.height);
		cam.upd();
		this.rotObj.x += 0.1;
		this.rotObj.y += 0.1;
		this.rotObj.z += 0.1;

		for (var i = 0; i < this.varr.length; i++) {
		  for (var val in this.calc[i]) {
			if (this.calc[i].hasOwnProperty(val)) {
			  this.calc[i][val] += this.vel;
			  if (this.calc[i][val] > this.lim) this.calc[i][val] = 0;
			}
		  }

		  this.varr[i].transIn.pos = {
			x: this.diff * Math.cos(this.calc[i].x * Math.PI / 180),
			y: this.diff * Math.sin(this.calc[i].y * Math.PI / 180),
			z: this.diff * Math.sin(this.calc[i].z * Math.PI / 180)
		  };
		  this.varr[i].transIn.rot = this.rotObj;
		  this.varr[i].transIn.sz = this.objSz;
		  this.varr[i].vupd();
		  if (this.varr[i].transOut.p < 0) continue;
		  var g = this.$.createRadialGradient(this.varr[i].transOut.x, this.varr[i].transOut.y, this.varr[i].transOut.p, this.varr[i].transOut.x, this.varr[i].transOut.y, this.varr[i].transOut.p * 2);
		  this.$.globalCompositeOperation = 'lighter';
		  g.addColorStop(0, 'hsla(255, 255%, 255%, 1)');
		  g.addColorStop(.5, 'hsla(' + (i + 2) + ',85%, 40%,1)');
		  g.addColorStop(1, 'hsla(' + (i) + ',85%, 40%,.5)');
		  this.$.fillStyle = g;
		  this.$.beginPath();
		  this.$.arc(this.varr[i].transOut.x, this.varr[i].transOut.y, this.varr[i].transOut.p * 2, 0, Math.PI * 2, false);
		  this.$.fill();
		  this.$.closePath();
		}
	  };
	  Build.prototype.anim = function() {
		window.requestAnimationFrame = (function() {
		  return window.requestAnimationFrame ||
			function(callback, element) {
			  window.setTimeout(callback, 1000 / 60);
			};
		})();
		var anim = function() {
		  this.upd();
		  this.draw();
		  window.requestAnimationFrame(anim);
		}.bind(this);
		window.requestAnimationFrame(anim);
	  };

	  Build.prototype.run = function() {
		this.anim();

		window.addEventListener('mousemove', function(e) {
		  this.toX = (e.clientX - this.canvas.width / 2) * -0.8;
		  this.toY = (e.clientY - this.canvas.height / 2) * 0.8;
		}.bind(this));
		window.addEventListener('touchmove', function(e) {
		  e.preventDefault();
		  this.toX = (e.touches[0].clientX - this.canvas.width / 2) * -0.8;
		  this.toY = (e.touches[0].clientY - this.canvas.height / 2) * 0.8;
		}.bind(this));
		window.addEventListener('mousedown', function(e) {
		  for (var i = 0; i < 100; i++) {
			this.add();
		  }
		}.bind(this));
		window.addEventListener('touchstart', function(e) {
		  e.preventDefault();
		  for (var i = 0; i < 100; i++) {
			this.add();
		  }
		}.bind(this));
	  };
	  var app = new Build();
	  app.run();
	})();
	window.addEventListener('resize', function() {
	  canvas.width = w = window.innerWidth;
	  canvas.height = h = window.innerHeight;
	}, false);
	
});
	



猜你喜欢

转载自blog.csdn.net/qq_34886247/article/details/80701775