Toggle navigation
Sign Up
Log In
Explore
Works
Folders
Tools
Collections
Artists
Groups
Groups
Topics
Tasks
Tasks
Jobs
Teams
Jobs
Recommendation
More Effects...
JS
var RENDERER = { WATCH_INTERVAL : 300, PARTICLE_COUNT : 150, OFFSET_Y : 0.1, OFFSET_COUNT : 10, init : function(){ this.setParameters(); this.reconstructMethods(); this.setup(); this.bindEvent(); this.render(); }, setParameters : function(){ this.$window = $(window); this.$container = $('#jsi-parallax-container'); this.$backwardCanvas = $('
'); this.$forwardCanvas = $('
'); this.backwardContext = this.$backwardCanvas.appendTo(this.$container).get(0).getContext('2d'); this.forwardContext = this.$forwardCanvas.appendTo(this.$container).get(0).getContext('2d'); this.forwardTerrains = []; this.backwardTerrains = []; this.particles = []; this.watchIds = []; }, reconstructMethods : function(){ this.watchWindowSize = this.watchWindowSize.bind(this); this.jdugeToStopResize = this.jdugeToStopResize.bind(this); this.watchMouse = this.watchMouse.bind(this); this.render = this.render.bind(this); }, setup : function(){ this.forwardTerrains.length = 0; this.backwardTerrains.length = 0; this.particles.length = 0; this.watchIds.length = 0; this.width = this.$container.width(); this.height = this.$container.height(); this.offsetX = {base : this.width / 2, source : this.width / 2, destination : this.width / 2}; this.offsetY = {base : 0, source : 0, destination : 0}; this.offsetCount = 0; this.$backwardCanvas.attr({width : this.width, height : this.height}); this.$forwardCanvas.attr({width : this.width, height : this.height}); this.createElements(); }, createElements : function(){ this.forwardTerrains.push(new TERRAIN(this, 0, 1)); this.forwardTerrains.push(new TERRAIN(this, 0, -1)); this.backwardTerrains.push(new TERRAIN(this, 1, 1)); this.backwardTerrains.push(new TERRAIN(this, 1, -1)); for(var i = 0, count = this.PARTICLE_COUNT * this.width * this.height / 500 / 500; i < count; i++){ this.particles.push(new PARTICLE(this)); } }, watchWindowSize : function(){ this.clearTimer(); this.tmpWidth = this.$window.width(); this.tmpHeight = this.$window.height(); this.watchIds.push(setTimeout(this.jdugeToStopResize, this.WATCH_INTERVAL)); }, clearTimer : function(){ while(this.watchIds.length > 0){ clearTimeout(this.watchIds.pop()); } }, jdugeToStopResize : function(){ var width = this.$window.width(), height = this.$window.height(), stopped = (width == this.tmpWidth && height == this.tmpHeight); this.tmpWidth = width; this.tmpHeight = height; if(stopped){ this.setup(); } }, watchMouse : function(event){ this.offsetX.source = this.offsetX.base; this.offsetX.destination = event.clientX - this.$container.offset().left + this.$window.scrollLeft(); this.offsetY.source = this.offsetY.base; this.offsetY.destination = -(event.clientY - this.$container.offset().top + this.$window.scrollTop() - this.height / 2) * this.OFFSET_Y; this.offsetCount = 0; }, getRandomValue : function(min, max){ return min + (max - min) * Math.random(); }, bindEvent : function(){ this.$window.on('resize', this.watchWindowSize); this.$container.on('mousemove', this.watchMouse); }, render : function(){ requestAnimationFrame(this.render); var gradient = this.backwardContext.createLinearGradient(0, 0, this.width, 0), offsetX = this.offsetX.base / this.width; gradient.addColorStop(0, 'hsl(210, 50%, ' + (30 - 10 * offsetX) + '%)'); gradient.addColorStop(0.5, 'hsl(210, 50%, ' + (60 - 20 * offsetX) + '%)'); gradient.addColorStop(1, 'hsl(210, 50%, ' + (30 - 10 * offsetX) + '%)'); this.backwardContext.fillStyle = gradient; this.backwardContext.fillRect(0, 0, this.width, this.height); for(var i = 0, count = this.backwardTerrains.length; i < count; i++){ this.backwardTerrains[i].render(this.backwardContext, offsetX, this.offsetY.base); } this.particles.sort(function(particle1, particle2){ return particle2.z - particle1.z; }); this.forwardContext.save(); this.forwardContext.clearRect(0, 0, this.width, this.height); this.forwardContext.globalCompositeOperation = 'lighter'; for(var i = 0, count = this.particles.length; i < count; i++){ this.particles[i].render(this.forwardContext, offsetX); } this.forwardContext.restore(); for(var i = 0, count = this.forwardTerrains.length; i < count; i++){ this.forwardTerrains[i].render(this.forwardContext, offsetX, this.offsetY.base); } if(this.offsetCount < this.OFFSET_COUNT){ this.offsetCount++; } this.offsetX.base = this.offsetX.source + (this.offsetX.destination - this.offsetX.source) * this.offsetCount / this.OFFSET_COUNT; this.offsetY.base = this.offsetY.source + (this.offsetY.destination - this.offsetY.source) * this.offsetCount / this.OFFSET_COUNT; } }; var TERRAIN = function(renderer, index, offset){ this.renderer = renderer; this.index = index; this.offset = offset; this.init(); }; TERRAIN.prototype = { DISPLACEMENT : 80, DELTA_DESPLACEMENT : 0.6, TICK : 2, init : function(){ this.vertices = this.createVertices(); this.count = this.vertices.length; }, createVertices : function(base){ var power = Math.pow(2, Math.ceil(Math.log(this.renderer.width / this.TICK + 1) / Math.log(2))), displacement = this.renderer.height / this.renderer.getRandomValue(4, 8), vertices = []; vertices[0] = base ? base : (this.renderer.height * (0.5 + this.renderer.getRandomValue(0.05, 0.3) * (1 - 0.7 * this.index) * this.offset)); vertices[power] = this.renderer.height * (0.5 + this.renderer.getRandomValue(0.05, 0.3) * (1 - 0.7 * this.index) * this.offset); for(var i = 1; i < power; i *= 2) { var offset = power / i / 2; for(var j = offset; j < power; j += offset * 2) { vertices[j] = ((vertices[j - offset] + vertices[j + offset]) / 2) + Math.floor(displacement * (1 - Math.random())) * this.offset; } displacement *= this.DELTA_DESPLACEMENT; } return vertices.slice(1); }, render : function(context, offsetX, offsetY){ offsetY *= (this.index == 0) ? 2 : 1; this.vertices = this.vertices.slice(2 - this.index); if(this.vertices.length < this.count){ this.vertices = this.vertices.concat(this.createVertices(this.vertices[this.vertices.length - 1])); } var base = this.renderer.height / 2 * (1 + this.offset), gradient = context.createLinearGradient(0, 0, 0, this.renderer.height); gradient.addColorStop(0, 'hsl(0, 0%, ' + (5 + 15 * offsetX) + '%)'); gradient.addColorStop(0.5, 'hsl(0, 0%, ' + (20 + 30 * offsetX) + '%)'); gradient.addColorStop(1, 'hsl(0, 0%, ' + (5 + 15 * offsetX) + '%)'); context.fillStyle = (this.index == 0) ? 'hsl(0, 0%, 0%)' : gradient; context.beginPath(); context.moveTo(0, base); for(var i = 0, count = this.vertices.length; i < count; i++){ context.lineTo(this.TICK * i, this.vertices[i] + offsetY); } context.lineTo(this.renderer.width, base); context.closePath(); context.fill(); } }; var PARTICLE = function(renderer){ this.renderer = renderer; this.init(false); }; PARTICLE.prototype = { RADIUS : 15, VELOCITY_X : 1, VELOCITY_Y : 2, init : function(toReset){ this.x = this.renderer.getRandomValue(0, this.renderer.width * 2); this.y = toReset ? this.renderer.height : this.renderer.getRandomValue(0, this.renderer.height); this.z = this.renderer.getRandomValue(0, 1); this.radius = this.RADIUS * (1 - this.z / 2); this.vx = (this.z - 2) * this.VELOCITY_X / 2; this.vy = (this.z - 2) * this.VELOCITY_Y / 2; var saturation = 80 * (1 - this.z / 2); this.gradient = this.renderer.forwardContext.createRadialGradient(0, 0, 0, 0, 0, this.radius); this.gradient.addColorStop(0, 'hsla(220, ' + saturation + '%, 100%, 1)'); this.gradient.addColorStop(0.3, 'hsla(220, ' + saturation + '%, 80%, 1)'); this.gradient.addColorStop(0.4, 'hsla(220, ' + saturation + '%, 60%, 1)'); this.gradient.addColorStop(0.6, 'hsla(220, ' + saturation + '%, 40%, 0.7)'); this.gradient.addColorStop(1, 'hsla(220, ' + saturation + '%, 40%, 0)'); }, render : function(context, offsetX){ context.fillStyle = this.gradient; context.save(); context.translate(this.x, this.y); context.beginPath(); context.arc(0, 0, this.radius, 0, Math.PI * 2, false); context.fill(); context.restore(); this.x += this.vx * (1 + offsetX * 5); this.y += this.vy; if(this.x < -this.radius || this.y < -this.radius){ this.init(true); } } }; $(function(){ RENDERER.init(); });
CSS
html, body{ width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden; } .container{ width: 100%; height: 100%; margin: 0; padding: 0; position: relative; background-color: #FFFFFF; } .container > canvas{ position: absolute; top: 0; left: 0; }
HTML
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