Toggle navigation
Sign Up
Log In
Explore
Works
Folders
Tools
Collections
Artists
Groups
Groups
Topics
Tasks
Tasks
Jobs
Teams
Jobs
Recommendation
More Effects...
JS
/* [Book Ref] Physics for JavaScript::Games, Animation, && Simulations w/ HTML5 Canvas -by Dev Ramtal, Adrian Dobre */ window.requestAnimFrame = (function(){ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function( callback ){ window.setTimeout(callback, 1000 / 60); }; })(); var show = false; document.getElementById('btn').addEventListener('click',function(){ show = !show; }, false); (function () { var c = document.getElementById('canv'); var $ = c.getContext('2d'); var w = c.width = window.innerWidth; var h = c.height = window.innerHeight; var w2 = w / 2; var h2 = h / 2; var cos = Math.cos, sin = Math.sin, abs = Math.abs, π = Math.PI, _fl = Math.floor, rnd = Math.random, dtr = π / 180; var cam = { focus: 300, pos: { x: 0, y: 0, z: 0 }, rot : { x: 0, y: 0, z: 0 }, View: function (tar) { var rt = tar; rt = this.Rot(rt); rt = this.Trans(rt); rt = this.Persp(rt); return rt; }, Rot: function (tar) { var xr = this.rot.x * dtr, yr = this.rot.y * dtr, zr = this.rot.z * dtr, rt = tar; rt = coords.rot.x(xr, rt); rt = coords.rot.y(yr, rt); rt = coords.rot.z(zr, rt); return rt; }, Trans: function (tar) { var x = this.pos.x, y = this.pos.y, z = this.pos.z; return { x: tar.x - x, y: tar.y - y, z: tar.z - z }; }, Persp: function (pos) { var pov = (this.focus - this.pos.z) || 0.00001, x = pos.x, y = pos.y, z = pos.z; var pov_z = pov - z; if (pov_z < 0) { return null; } var s = (pov / pov_z); var pov_X = x * s; var pov_Y = y * s; var pov_Z = z * s; if (pov_X < -w2 || pov_X > w2) { return null; } if (pov_Y < -h2 || pov_Y > h2) { return null; } if (pov_Z < -pov_z || pov_Z > this.z) { return null; } return { x: pov_X, y: pov_Y, z: pov_Z, w: z }; } }; var Part = function (x, y, z, obj) { obj || (obj = {}); this.x = x || 0; this.y = y || 0; this.z = z || 0; this.size = obj.size || 5; this.color = obj.color || 'hsla(357, 95%, 45%, 1)'; this.alpha = obj.alpha || 1; }; Part.prototype = { const: Part, draw: function ($, cam) { var v = cam.View(this); if (!v) { return; } v.r = this.size; var a = abs(v.z / v.w); $.save(); $.beginPath(); $.arc(v.x, v.y, v.r * a, 0, π * 2, false); $.fillStyle = this.color; $.globalCompositeOperation = 'lighter'; $.globalAlpha = this.alpha * a; $.fill(); $.closePath(); $.restore(); } }; function Spark(x, y, z, obj) { obj || (obj = {}); Part.apply(this, arguments); this.time = 0; this.lifespan = obj.lifespan || 1000; this.alphaOne = obj.alpha || 1; this.alpha = obj.alpha || 1; this.vel = obj.velocity || { x: 0, y: 0, z: 0 }; this.end = false; this.r = range(0, 254) | 0; this.g = range(0, 254) | 0; this.b = range(0, 254) | 0; } Spark.prototype = new Part(); Spark.prototype.draw = function ($, cam) { var v = cam.View(this); if (!v) { return; } v.r = this.size; var a = abs(v.z / v.w); var r = this.r; var g = this.g; var b = this.b; var grd = $.createRadialGradient(v.x, v.y, 0, v.x, v.y, v.r * a); grd.addColorStop(0, 'rgba(255, 255, 255, 1)'); grd.addColorStop(1, 'rgba(' + r + ',' + g + ',' + b + ', 0)'); $.save(); $.beginPath(); $.arc(v.x, v.y, v.r * a, 0, π * 2, false); $.fillStyle = grd; $.globalCompositeOperation = 'lighter'; $.globalAlpha = this.alpha * a; $.fill(); $.closePath(); $.restore(); }; Spark.prototype.upd = function (deltaT) { if (this.end) { return; } this.x += this.vel.x; this.y += this.vel.y; this.z += this.vel.z; this.time += deltaT; this.size += 0.2; var o = this.alphaOne; this.alpha = o - (o * (this.time / this.lifespan)); if (this.lifespan <= this.time) { this.end = true; } }; function Emitter(x, y, z, opt) { opt || (opt = {}); Part.apply(this, arguments); this.parts = []; this.maxPart = opt.maxPart || 500; } Emitter.prototype = new Part(); Emitter.prototype.maxPart = 1; Emitter.prototype.parts = null; Emitter.prototype.int = 10; Emitter.prototype.time = 0; Emitter.prototype.start = function () { var it = this; var curr =+new Date(); var updT = 0; (function run() { var pres =+ new Date(); var delta = pres - curr; it.time += delta; it.upd(delta); if (it.time - updT > it.int) { updT = it.time; it.emit(); } curr = pres; it.wipe(); window.requestAnimationFrame(run); }()); }; Emitter.prototype.draw = function ($, cam) { Part.prototype.draw.apply(this, arguments); for (var i = 0, l = this.parts.length; i < l; i++) { this.parts[i].draw($, cam); } }; Emitter.prototype.emit = function () { if (this.parts.length >= this.maxPart) { return; } var x = this.x; var y = this.y; var z = this.z; for (var i = 0; i < 5; i++) { var p = new Spark(x, y, z, { size : 5, velocity: { x: range(-0.5, 0.5), y: range(-0.5, 0.5), z: range(-0.2, 0.2) } }); this.parts.push(p); } }; Emitter.prototype.upd = function (deltaT) { for (var i = 0, l = this.parts.length; i < l; i++) { this.parts[i].upd(deltaT); } }; Emitter.prototype.wipe = function () { var newParts = []; for (var i = 0, l = this.parts.length; i < l; i++) { var p = this.parts[i]; if (!p.end) { newParts.push(p); } } this.parts = newParts; }; function spline() { this.a = []; this.b = []; this.c = []; this.d = []; this.num = 0; } spline.prototype = { const: spline, num: 0, a: null, b: null, c: null, d: null, go: function (sp) { var tmp; var arr = []; var i; this.num = sp.length - 1; var num = this.num; var a = this.a; var b = this.b; var c = this.c; var d = this.d; for(i = 0; i <= num; i++) { a[i] = sp[i]; } c[0] = c[num] = 0.0; for(i = 1; i < num; i++) { c[i] = 3.0 * (a[i - 1] - 2.0 * a[i] + a[i + 1]); } arr[0] = 0.0; for(i = 1; i < num; i++) { tmp = 4.0 - arr[i - 1]; c[i] = (c[i] - c[i - 1]) / tmp; arr[i] = 1.0 / tmp; } for(i = num - 1; i > 0; i--) { c[i] = c[i] - c[i + 1] * arr[i]; } b[num] = d[num] = 0.0; for (i = 0; i < num; i++) { d[i] = (c[i + 1] - c[i]) / 3.0; b[i] = a[i + 1] - a[i] - c[i] - d[i]; } }, calc: function (t) { var n = _fl(t); var dt; var num = this.num; var a = this.a; var b = this.b; var c = this.c; var d = this.d; if (n < 0) { n = 0; } else if (n >= num) { n = num - 1; } dt = t - n; return a[n] + (b[n] + (c[n] + d[n] * dt) * dt ) * dt; } }; var coords = { rot: { x: function (rad, pos) { return { x: pos.x, y: pos.y * cos(rad) + pos.z * sin(rad), z: pos.y * -sin(rad) + pos.z * cos(rad) }; }, y: function (rad, pos) { return { x: pos.x * cos(rad) + pos.z * -sin(rad), y: pos.y, z: pos.x * sin(rad) + pos.z * cos(rad) }; }, z: function (rad, pos) { return { x: pos.x * cos(rad) + pos.y * sin(rad), y: pos.x * -sin(rad) + pos.y * cos(rad), z: pos.z }; } } }; function tween(x, a, b) { var e = (1.0 - cos(x * π)) * 0.5; return b * e + a * (1.0 - e); } function range(min, max) { var len = max - min; var r = rnd() * len; return min + r; } var arrX = [], arrY = [], arrZ = []; for (var i = 0; i < 30; i++) { arrX.push(range(-200, 200)); arrY.push(range(-200, 200)); arrZ.push(range(-200, -20)); } function draw(x, y, z) { var sX = new spline(); var sY = new spline(); var sZ = new spline(); var t = 0; var l = x.length - 1; sX.go(x); sY.go(y); sZ.go(z); var parts = []; for (var _n = 0; _n <= l; _n += 0.02) { var p = new Part(sX.calc(_n), sY.calc(_n), sZ.calc(_n), { size : .989, color: 'hsla(240, 98%, 89%, 1)' }); parts.push(p); } var emitter = new Emitter(sX.calc(0), sY.calc(0), sZ.calc(0), { size : 15, color: 'hsla(221, 95%, 45%, 0.40)' }); emitter.start(); var bg = new Image(); bg.src = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/131045/colorful-space-background.jpg'; (function run() { t += 0.001; if (t > 1) { t = 0; } cam.rot.x += 0.09; $.save(); $.beginPath(); $.drawImage(bg, 0, 0, w, h); $.translate(w / 2, h / 2); if (show) { for (var i = 0, p; p = parts[i]; i++) { p.draw($, cam); } } var pos = tween(t, 0, l); emitter.x = sX.calc(pos); emitter.y = sY.calc(pos); emitter.z = sZ.calc(pos); emitter.draw($, cam); $.restore(); window.requestAnimFrame(run); }()); } draw(arrX, arrY, arrZ); }());
CSS
@import url(https://fonts.googleapis.com/css?family=Ubuntu:400,700); body{ overflow:hidden; width:100%; margin:0; padding:0; font-family: 'Ubuntu', sans-serif; font-size:1.2em; } button { position: absolute; left: 0; bottom: 0; border:none; padding:.8em; border-radius:2px; background:hsla(221, 95%, 45%, 0.05); box-shadow:2px -2px 2px 2px hsla(221, 95%, 55%, 0.1); color:hsla(221, 95%, 75%, 0.95); font-weight:bold; } canvas{ width:100%; height:100vh; }
HTML
Show Spline Curve
Join Effecthub.com
Working with Global Gaming Artists and Developers!
Login
Sign Up
Or Login with Your Email Address:
Email
Password
Remember
Or Sign Up with Your Email Address:
Your Email
This field must contain a valid email
Set Password
Password should be at least 1 character
Stay informed via email