Skip to content

Instantly share code, notes, and snippets.

@artpi
Last active April 28, 2022 01:19
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save artpi/1eed7ac11eb980d9f7837041d054ef3f to your computer and use it in GitHub Desktop.
Save artpi/1eed7ac11eb980d9f7837041d054ef3f to your computer and use it in GitHub Desktop.
This will animate an "Explosion" whenever you complete a TODO in Roam Research, so you can be productive in style.
// This will animate an "Explosion" whenever you complete a TODO in Roam Research.
// See https://deliber.at/roam for more Roam goodies.
// Put this file under {{[[roam/js]]}} block. I have a page roam/js. Under that, I have {{[[roam/js]]}} and under that the javascript block
document.addEventListener("click", function ( e ) {
const target = e.target;
if (
target.tagName === "INPUT" &&
target.parentElement.className === "check-container"
) {
if (target.type === "checkbox" && target.checked ) {
const position = target.getBoundingClientRect();
setTimeout(() => {
explode( position.x, position.y );
}, 50);
}
}
});
// The animation code below is adapted from https://codepen.io/explosion/pen/zKEovE
const requestedFrames = [];
const explode = (x, y) => {
const colors = [ '#ffc000', '#ff3b3b', '#ff8400' ];
const bubbles = 25;
let particles = [];
let ratio = window.devicePixelRatio;
let c = document.createElement('canvas');
let ctx = c.getContext('2d');
c.style.position = 'absolute';
c.style.left = (x - 100) + 'px';
c.style.top = (y - 100) + 'px';
c.style.pointerEvents = 'none';
c.style.width = 200 + 'px';
c.style.height = 200 + 'px';
c.style.zIndex = 10000;
c.width = 200 * ratio;
c.height = 200 * ratio;
document.body.appendChild(c);
for(var i = 0; i < bubbles; i++) {
particles.push({
x: c.width / 2,
y: c.height / 2,
radius: r(20, 30),
color: colors[Math.floor(Math.random() * colors.length)],
rotation: r(0, 360, true),
speed: r(8, 12),
friction: 0.9,
opacity: r(0, 0.5, true),
yVel: 0,
gravity: 0.1
});
}
render(particles, ctx, c.width, c.height);
setTimeout(() => {
document.body.removeChild(c);
requestedFrames.forEach( frame => cancelAnimationFrame( frame ) );
}, 1000);
}
const render = (particles, ctx, width, height) => {
requestedFrames.push( requestAnimationFrame(() => render(particles, ctx, width, height)) );
ctx.clearRect(0, 0, width, height);
particles.forEach((p, i) => {
p.x += p.speed * Math.cos(p.rotation * Math.PI / 180);
p.y += p.speed * Math.sin(p.rotation * Math.PI / 180);
p.opacity -= 0.01;
p.speed *= p.friction;
p.radius *= p.friction;
p.yVel += p.gravity;
p.y += p.yVel;
if(p.opacity < 0 || p.radius < 0) return;
ctx.beginPath();
ctx.globalAlpha = p.opacity;
ctx.fillStyle = p.color;
ctx.arc(p.x, p.y, p.radius, 0, 2 * Math.PI, false);
ctx.fill();
});
return ctx;
}
const r = (a, b, c) => parseFloat((Math.random() * ((a ? a : 1) - (b ? b : 0)) + (b ? b : 0)).toFixed(c ? c : 0));
@ErikPlachta
Copy link

ErikPlachta commented Feb 20, 2021

@artpi

On the top of Roam, I'm getting the error message below when enabling this JS, and it doesn't work.
#object[TypeError TypeError: undefined is not a function (near '...})...')]

Is there something I'm missing?

@sirwolfgang
Copy link

sirwolfgang commented Feb 20, 2021

The wrapping anonymous function gave an execution error, otherwise works great!

Edit: @ErikPlachta Remove ( function () { and } )() at the head and tail respectively

@ottsch
Copy link

ottsch commented Feb 20, 2021

Yes I'm having the same problem with self executing anonymous functions in Roam sometimes but not reliably

@ErikPlachta
Copy link

The wrapping anonymous function gave an execution error, otherwise works great!

Edit: @ErikPlachta Remove ( function () { and } )() at the head and tail respectively

Thank you @sirwolfgang ✅💣 Working 👍

@sicorace
Copy link

it doesn't work if the block has some references in it. can you confirm the bug?

@artpi
Copy link
Author

artpi commented Mar 10, 2021

I made the following changes:

Now the script should explode todos also in references, etc.

it doesn't work if the block has some references in it. can you confirm the bug?

It should now, it was indeed a bug.

@sicorace
Copy link

UUUHHHH thanks!

@QingYangLinguist
Copy link

Somehow I only got an explosion when I un-complete the task. Does anyone have the same problem? Thanks!

@sicorace
Copy link

it happened to me too, I had to reload the browser

@dvargas92495
Copy link

Hey @artpi, how would you feel if I merged this in with the todo-trigger extension?

@artpi
Copy link
Author

artpi commented Apr 26, 2022

@dvargas92495 , yes, please do! I find it impossible to maintain this and I bet it will be easier to keep working if part of the larger project

@dvargas92495
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment