A Matter.Js experiment where some particles keep on falling. Letters can be interacted with using mouse.
A Pen by Manoj Bahuguna on CodePen.
A Matter.Js experiment where some particles keep on falling. Letters can be interacted with using mouse.
A Pen by Manoj Bahuguna on CodePen.
<div id="headerEffectCanvas"></div> |
var svgB = 'data:image/svg+xml;utf8,<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="70px" height="80px" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 541.3 640.7" enable-background="new 0 0 541.3 640.7" xml:space="preserve"> <linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="146.1052" y1="392.6462" x2="539.4364" y2="-0.685"> <stop offset="0" style="stop-color:#0EFFCF"/> <stop offset="1" style="stop-color:#28CAFF"/> </linearGradient> <path fill="url(#SVGID_1_)" d="M521.2,178.3L521.2,178.3C521.2,79.8,441.4,0,342.9,0H0v284.1v72.5v284.1h363 c98.5,0,178.3-79.8,178.3-178.3v0c0-58-47.8-109.5-90.6-142C493.5,287.8,521.2,236.3,521.2,178.3z"/> </svg> '; | |
// module aliases | |
var Engine = Matter.Engine, | |
Render = Matter.Render, | |
World = Matter.World, | |
Bodies = Matter.Bodies, | |
Body = Matter.Body, | |
Composites = Matter.Composites, | |
Composite = Matter.Composite, | |
Constraint = Matter.Constraint, | |
Common = Matter.Common, | |
Mouse = Matter.Mouse, | |
MouseConstraint = Matter.MouseConstraint; | |
// create an engine | |
var engine = Engine.create(); | |
engine.world.gravity.scale = 0.0009; | |
var world = engine.world; | |
var canvasContainer = document.getElementById('headerEffectCanvas'); | |
// create a renderer | |
var render = Render.create({ | |
element: canvasContainer, | |
engine: engine, | |
options: { | |
width: canvasContainer.clientWidth, | |
height: canvasContainer.clientHeight, | |
wireframes: false, | |
background: '' | |
} | |
}); | |
var particles = []; | |
var updateParticles = function(){ | |
var particleOptions = { | |
// count: render.canvas.width*0.05, | |
count: (render.canvas.width*render.canvas.height*0.00005) + 30, | |
size: {min: render.canvas.width*0.003, max: render.canvas.width*0.013}, | |
bounce: 1.1, | |
// frictionAir: , | |
color: '#ff357a' | |
}; | |
for (var i = 0; i < particleOptions.count; i++) { | |
var x = Matter.Common.random(render.canvas.width/5, render.canvas.width/1.2); | |
var y = Matter.Common.random(-render.canvas.height , render.canvas.height/3); | |
var size = Matter.Common.random(particleOptions.size.min, particleOptions.size.max); | |
var p = Bodies.rectangle(x, y, size, size, { | |
restitution: particleOptions.bounce, | |
render: { fillStyle: particleOptions.color }, | |
frictionAir: Common.random(0.03, 0.2) | |
}); | |
// Matter.Body.setVelocity(p, { x: 0, y: Matter.Common.random(1, 10) }); | |
particles.push(p); | |
} | |
}; | |
var letters = []; | |
var updateLetters = function(){ | |
var letterOptions = { | |
width: render.canvas.width/11.3, | |
height: render.canvas.width/10, | |
stiffness: 1.2 | |
}; | |
console.log(letterOptions.width, letterOptions.height); | |
var letterB = Bodies.rectangle( | |
render.canvas.width/3, | |
render.canvas.height/2, | |
letterOptions.width, | |
letterOptions.height, | |
{ | |
friction: 0, | |
chamfer: { | |
radius: [0, letterOptions.width/3, letterOptions.width/3, 0] | |
}, | |
render: { | |
sprite: { | |
texture: svgB, | |
xScale: letterOptions.width*0.015, | |
yScale: letterOptions.width*0.015 | |
} | |
} | |
} | |
); | |
var ropeB = Composite.create(); | |
Composite.add( | |
ropeB, | |
Constraint.create({ | |
bodyB: letterB, | |
pointB: { x: 0, y: -letterOptions.height/2 }, | |
pointA: { x: render.canvas.width/3, y: render.canvas.height/2 - letterOptions.height/2 }, | |
length: 5, | |
stiffness: letterOptions.stiffness, | |
render: { | |
visible: false | |
} | |
}) | |
); | |
var letterA = Bodies.fromVertices( | |
render.canvas.width/2, | |
render.canvas.height/2, | |
[ | |
{x: 0, y: -letterOptions.height/2}, | |
{x: letterOptions.width/1.5, y: letterOptions.height/2}, | |
{x: -letterOptions.width/1.5, y: letterOptions.height/2} | |
], | |
{friction: 0} | |
); | |
var ropeA = Composite.create(); | |
Composite.add( | |
ropeA, | |
Constraint.create({ | |
bodyB: letterA, | |
pointB: { x: 0, y: -letterOptions.height/1.55 }, | |
pointA: { x: render.canvas.width/2, y: render.canvas.height/2 - letterOptions.height/2 }, | |
stiffness: letterOptions.stiffness, | |
length: 5, | |
render: { | |
visible: false | |
} | |
}) | |
); | |
var letterD = Bodies.rectangle( | |
render.canvas.width/1.5, | |
render.canvas.height/2, | |
letterOptions.width, | |
letterOptions.height, | |
{ | |
friction: 0, | |
chamfer: { | |
radius: [0, letterOptions.width/1.9, letterOptions.width/1.9, 0] | |
} | |
} | |
); | |
var ropeD = Composite.create(); | |
Composite.add( | |
ropeD, | |
Constraint.create({ | |
bodyB: letterD, | |
pointB: { x: 0, y: -letterOptions.height/2 }, | |
pointA: { x: render.canvas.width/1.5, y: render.canvas.height/2 - letterOptions.height/2 }, | |
stiffness: letterOptions.stiffness, | |
length: 5, | |
render: { | |
visible: false | |
} | |
}) | |
); | |
var gradientB = render.context.createLinearGradient( | |
letterB.bounds.min.x, | |
letterB.bounds.max.y, | |
letterB.bounds.max.x, | |
letterB.bounds.min.y | |
); | |
gradientB.addColorStop(0, "#0effcf"); | |
gradientB.addColorStop(1, "#28caff"); | |
var gradientA = render.context.createLinearGradient( | |
letterA.bounds.min.x, | |
letterA.bounds.max.y, | |
letterA.bounds.max.x, | |
letterA.bounds.min.y | |
); | |
gradientA.addColorStop(0, "#7c17a4"); | |
gradientA.addColorStop(1, "#c443e4"); | |
var gradientD = render.context.createLinearGradient( | |
letterD.bounds.min.x, | |
letterD.bounds.max.y, | |
letterD.bounds.max.x, | |
letterD.bounds.min.y | |
); | |
gradientD.addColorStop(0, "#fe239b"); | |
gradientD.addColorStop(1, "#ffe31f"); | |
letterB.render.fillStyle = gradientB; | |
letterA.render.fillStyle = gradientA; | |
letterD.render.fillStyle = gradientD; | |
letters.push(letterB); | |
letters.push(ropeB); | |
letters.push(letterA); | |
letters.push(ropeA); | |
letters.push(letterD); | |
letters.push(ropeD); | |
}; | |
var updateMouse = function() { | |
// add mouse control | |
var mouse = Mouse.create(render.canvas), | |
mouseConstraint = MouseConstraint.create(engine, { | |
mouse: mouse, | |
constraint: { | |
stiffness: 0.01, | |
render: { | |
visible: false | |
} | |
} | |
}); | |
World.add(world, mouseConstraint); | |
// keep the mouse in sync with rendering | |
render.mouse = mouse; | |
} | |
var addToWorld = function() { | |
if(!canvasContainer.clientWidth || !canvasContainer.clientHeight) return; | |
// add all of the bodies to the world | |
particles.length = 0; | |
letters.length = 0; | |
updateParticles(); | |
World.add(world, particles); | |
updateLetters(); | |
World.add(world, letters); | |
updateMouse(); | |
}; | |
addToWorld(); | |
var clearWorld = function() { | |
World.clear(world); | |
}; | |
var reset = function() { | |
clearWorld(); | |
addToWorld(); | |
}; | |
window.addEventListener('resize', function(){ | |
render.options.width = render.canvas.width = canvasContainer.clientWidth, | |
render.options.height = render.canvas.height = canvasContainer.clientHeight; | |
reset(); | |
}); | |
// run the engine | |
Engine.run(engine); | |
// run the renderer | |
Render.run(render); | |
Matter.Events.on(render, "afterRender", function(e) { | |
particles.forEach(function(p) { | |
if (p.position.y > render.canvas.height) { | |
// Matter.Body.setVelocity(p, { x: 0, y: Matter.Common.random(1, 30) }); | |
var x = Matter.Common.random(render.canvas.width/5, render.canvas.width/1.2); | |
var y = Matter.Common.random(-render.canvas.height , 0); | |
Matter.Body.setPosition(p, { x: x, y: y }); | |
} | |
}); | |
}); |
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.12.0/matter.min.js"></script> |
html, body { | |
margin: 0; | |
width: 100%; | |
height: 100%; | |
} | |
#headerEffectCanvas { | |
width: 100%; | |
height: 100%; | |
overflow: hidden; | |
background-color: #48006b; | |
} |