Published
Edited
Jun 27, 2022
2 stars
Insert cell
Insert cell
Insert cell
{
let ctx = DOM.context2d(width, width, 1);
let canvas = ctx.canvas;
let engine=Matter.Engine.create({positionIterations:100,velocityIterations:100,constraintIterations:100}), world=engine.world, runner=Matter.Runner.create({delta:1})
world.gravity.y=0
Matter.Composite.add(world,bodies(ctx))
Matter.Runner.start(runner,engine)
Matter.Events.on(engine, "beforeUpdate", () => {
Matter.Composite.allBodies(world).forEach(body => {
let distance = Matter.Vector.sub({x:width/2,y:width/2}, body.position);
body._vx = ((body._vx || 0) + distance.x * 0.03) * 0.2;
body._vy = ((body._vY || 0) + distance.y * 0.03) * 0.2;
Matter.Body.setVelocity(body, {x: body._vx, y: body._vy});
Matter.Body.setAngle(body, 0);
});
});

let i=0, increment=0.001, intervalo=[2010,2019], frame=0, sizeVarying=false
ctx.textBaseline = "top";
while (frame<2000){

frame++
ctx.fillStyle="white"
ctx.fillRect(0,0,width,width)

ctx.font="48px Arial"
ctx.fillStyle="black"
ctx.fillText(Math.round(intervalo[0]+(intervalo[1]-intervalo[0])*i), 0.85*width, 0.85*width)
let allBodies=Matter.Composite.allBodies(world)

allBodies.forEach(body=>{
ctx.font=(body.value[Math.floor(i*(body.value.length-1))]*(1-(i*(body.value.length-1))%1)+body.value[Math.floor(i*(body.value.length-1))+1]*((i*(body.value.length-1))%1))+"px Fira Sans Condensed"
ctx.fillStyle = body.color
//ctx.save()
//ctx.translate(body.position.x, body.position.y)
//ctx.rotate(body.angle)
//ctx.translate(-body.position.x, -body.position.y)
ctx.fillText(body.name, body.vertices[0].x, body.vertices[0].y)
//ctx.restore()
//Matter.Body.applyForce(body,Matter.Vector.create(width/2,width/2),Matter.Vector.create(-0.001,-0.001))
Matter.Body.scale(body,ctx.measureText(body.name).width/(body.bounds.max.x-body.bounds.min.x),(ctx.measureText(body.name).fontBoundingBoxAscent+ctx.measureText(body.name).fontBoundingBoxDescent)/(body.bounds.max.y-body.bounds.min.y))
if (drawOutlines){
ctx.beginPath()
for (let v of body.vertices)
ctx.lineTo(v.x,v.y)
ctx.closePath()
ctx.stroke()
}
//if (engine.timing.timestamp>20000)
// body.isStatic=true
})

if(allBodies.map(body=>Math.abs(body.velocity.x)+Math.abs(body.velocity.y)).reduce((acc,val)=>acc+val)<30&&frame>10)
sizeVarying=true
if (i<1-increment&&sizeVarying)
i+=increment
yield canvas
}
}
Insert cell
bodies = function (ctx){
return palavras.map(d=>{
ctx.font = d.value[0]+"px Arial"
let body = Matter.Bodies.rectangle(-width+2*width*Math.random(),-width+2*width*Math.random(),ctx.measureText(d.name).width,ctx.measureText(d.name).fontBoundingBoxAscent+ctx.measureText(d.name).fontBoundingBoxDescent)
body.name = d.name
body.value = d.value
body.color = d3.schemeCategory10[Math.floor(Math.random() * d3.schemeCategory10.length)]
body.slop=0
return body
})
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more