Skip to content

Instantly share code, notes, and snippets.

@tridungle
Created December 18, 2020 10:08
Show Gist options
  • Save tridungle/c2690c2b0ca5aafc1937ce8d9e1dd5d7 to your computer and use it in GitHub Desktop.
Save tridungle/c2690c2b0ca5aafc1937ce8d9e1dd5d7 to your computer and use it in GitHub Desktop.
Attractor - MatterJS
<div id="wrapper-canvas"></div>
<!-- Codepen -->
<div class="content">
<h1 class="title">
Codepen.io
</h1>
<h2 class="subtitle">
Demo or it didn't happen.
</h2>
</div>
<div class="more-pens">
<a target="_blank" href="https://www.instagram.com/p__l__a__s__m/" class="white-mode white-mode--highlight">DISCOVER MOSAICA STUDIO</a>
<a target="_blank" href="https://codepen.io/plasm/" class="white-mode">VIEW OTHER PENS</a>
<a target="_blank" href="https://codepen.io/collection/nZpPbz/" class="white-mode">VIEW OTHER PARTICLES</a>
</div>
var canvas = $("#wrapper-canvas").get(0);
var dimensions = {
width: $(window).width(),
height: $(window).height()
};
Matter.use('matter-attractors');
Matter.use('matter-wrap');
function runMatter(){
// module aliases
var Engine = Matter.Engine,
Events = Matter.Events,
Runner = Matter.Runner,
Render = Matter.Render,
World = Matter.World,
Body = Matter.Body,
Mouse = Matter.Mouse,
Common = Matter.Common,
Composite = Matter.Composite,
Composites = Matter.Composites,
Bodies = Matter.Bodies;
// create engine
var engine = Engine.create();
engine.world.gravity.y = 0
engine.world.gravity.x = 0
engine.world.gravity.scale = 0.1
// create renderer
var render = Render.create({
element: canvas,
engine: engine,
options: {
showVelocity: false,
width: dimensions.width,
height: dimensions.height,
wireframes: false,
background: 'rgb(240,240,240)'
}
});
// create runner
var runner = Runner.create();
// Runner.run(runner, engine);
// Render.run(render);
// create demo scene
var world = engine.world;
world.gravity.scale = 0;
// create a body with an attractor
var attractiveBody = Bodies.circle(
render.options.width / 2,
render.options.height / 2,
(Math.max(dimensions.width / 4, dimensions.height / 4)) / 2,
{
render: {
fillStyle: `rgb(240,240,240)`,
strokeStyle: `rgb(240,240,240)`,
lineWidth: 0
},
isStatic: true,
plugin: {
attractors: [
function(bodyA, bodyB) {
return {
x: (bodyA.position.x - bodyB.position.x) * 1e-6,
y: (bodyA.position.y - bodyB.position.y) * 1e-6,
};
}
]
}
});
World.add(world, attractiveBody);
// add some bodies that to be attracted
for (var i = 0; i < 60; i += 1) {
let x = Common.random(0, render.options.width);
let y = Common.random(0, render.options.height);
let s = Common.random() > 0.6 ? Common.random(10, 80) : Common.random(4, 60);
let poligonNumber= Common.random(3, 6);
var body = Bodies.polygon(
x,y,
poligonNumber,
s,
{
mass: s / 20,
friction: 0,
frictionAir: 0.02,
angle: Math.round(Math.random() * 360),
render: {
fillStyle: '#FFFFFF',
strokeStyle: `#DDDDDD`,
lineWidth: 2
}
}
);
World.add(world, body);
let r = Common.random(0,1)
var circle = Bodies.circle(x, y, Common.random(2, 8), {
mass: 0.1,
friction: 0,
frictionAir: 0.01,
render: {
fillStyle: r > 0.3 ? `#FF2D6A` : `rgb(240,240,240)`,
strokeStyle: `#E9202E`,
lineWidth: 2
}
});
World.add(world, circle);
var circle = Bodies.circle(x, y, Common.random(2, 20), {
mass: 6,
friction: 0,
frictionAir: 0,
render: {
fillStyle: r > 0.3 ? `#4267F8` : `rgb(240,240,240)`,
strokeStyle: `#3257E8`,
lineWidth: 4
}
});
World.add(world, circle);
var circle = Bodies.circle(x, y, Common.random(2, 30), {
mass: 0.2,
friction: 0.6,
frictionAir: 0.8,
render: {
fillStyle: `rgb(240,240,240)`,
strokeStyle: `#FFFFFF`,
lineWidth: 3}
});
World.add(world, circle);
}
// add mouse control
var mouse = Mouse.create(render.canvas);
Events.on(engine, 'afterUpdate', function() {
if (!mouse.position.x) return;
// smoothly move the attractor body towards the mouse
Body.translate(attractiveBody, {
x: (mouse.position.x - attractiveBody.position.x) * 0.12,
y: (mouse.position.y - attractiveBody.position.y) * 0.12
});
});
// return a context for MatterDemo to control
let data = {
engine: engine,
runner: runner,
render: render,
canvas: render.canvas,
stop: function() {
Matter.Render.stop(render);
Matter.Runner.stop(runner);
},
play: function(){
Matter.Runner.run(runner, engine);
Matter.Render.run(render);
}
};
Matter.Runner.run(runner, engine);
Matter.Render.run(render);
return data;
}
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
function setWindowSize(){
let dimensions = {};
dimensions.width = $(window).width();
dimensions.height = $(window).height();
m.render.canvas.width = $(window).width();
m.render.canvas.height = $(window).height();
return dimensions;
}
let m = runMatter()
setWindowSize()
$(window).resize(debounce(setWindowSize, 250))
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.12.0/matter.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/matter-wrap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/matter-attractors.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
=transform($prop)
-webkit-transform: $prop
-moz-transform: $prop
-ms-transform: $prop
-o-transform: $prop
transform: $prop
body
padding: 0
margin: 0
@import url('https://fonts.googleapis.com/css?family=Catamaran:300,400,500,600,700')
#wrapper-canvas
display: block
width: 100%
height: 100%
background: #FFFFFF
.more-pens
position: fixed
right: 20px
bottom: 20px
z-index: 10
font-family: 'Catamaran', sans-serif
font-size: 12px
a.white-mode
&:link,
&:visited,
&:active
font-family: 'Catamaran', sans-serif
font-size: 12px
text-decoration: none
background: #212121
padding: 8px 18px
color: #f7f7f7
border-radius: 20px
margin: 0 4px
&--highlight
&:link,
&:visited,
&:active
background: #293FE9
&:hover
background: #edf3f8
color: #212121
body
margin: 0
padding: 0
overflow: hidden
width: 100%
height: 100%
.content
+transform(translateY(-50%))
z-index: 10
position: absolute
left: 0
top: 50%
padding: 0 90px
text-align: left
pointer-events: none
.title
font-family: 'Catamaran', sans-serif
pointer-events: none
font-weight: 700
font-size: 70px
line-height: 1
margin-top: 14px
color: #212121
display: block
pointer-events: none
span
color: #EC456C
.subtitle
font-family: 'Catamaran', sans-serif
pointer-events: none
font-weight: 300
font-size: 24px
line-height: 1
margin-top: 0
color: #212121
display: block
pointer-events: none
span
color: #EC456C
.button
&:link,
&:visited,
&:hover,
&:active
-webkit-transition: all .3s cubic-bezier(.69,0,.185,1)
transition: all .3s cubic-bezier(.69,0,.185,1)
border-radius: 30px
font-family: 'Catamaran', sans-serif
font-size: 21px
font-style: normal
font-weight: 300
text-align: center
text-rendering: optimizeLegibility
padding: 18px 60px
line-height: 1
color: #90e5fb
margin: 20px auto 0
display: inline-block
background: #222222
text-decoration: none
box-shadow: 0 0 30px rgba(#90e5fb, 1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment