0% found this document useful (0 votes)
8 views3 pages

Control Token Animation in Macro

Uploaded by

Gabriel Leander
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views3 pages

Control Token Animation in Macro

Uploaded by

Gabriel Leander
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd

Hi! I’m modifying a macro and ran into a problem.

I want only the token to spin,


not the entire animation underneath it. Is that possible?

// === Levitation (self / controlled token) ===


// Requires Sequencer + JB2A

const token = [Link][0];


if (!token) { [Link]("Select your token first."); return; }

const GROUP = `levitating_${[Link]}`; // used for cleanup

// Dialog with Release button


const dialogEditor = new Dialog({
title: `Levitation`,
content: ``,
buttons: {
Release: {
label: `Release`,
callback: () => { effectUpdate({ Release: true }); }
},
},
default: "close",
close: () => {}
});
[Link](true);

// Start effects on the controlled token


new Sequence()
.thenDo(() => {

new Sequence()

.animation()
.delay(75)
.on(token)
.opacity(0) // NOTE: makes the token invisible; remove this line if you
want the token visible

// Wind stream (below token)


.effect()
.fadeIn(500)
.fadeOut(500)
.file("jb2a.wind_stream.[Link]")
.atLocation(token)
.rotate(90)
.attachTo(token, { bindAlpha: false })
.filter("ColorMatrix", { brightness: 1.15 })
.name(GROUP)
.scaleToObject(0.70)
.belowTokens()
.persist()

// ===== Looping centered smoke puffs (below token) =====


// Grey 0
.effect()
.file("[Link].0")
.attachTo(token, { bindAlpha: false })
.belowTokens()
.scaleToObject(2.15, { considerTokenScale: true })
.opacity(0.4)
.randomRotation()
.fadeIn(250)
.fadeOut(450)
.repeats(9999, 700, 1100) // continuous loop
.name(GROUP)
.zIndex(0.05)

// Grey 1
.effect()
.file("[Link].1")
.attachTo(token, { bindAlpha: false })
.belowTokens()
.scaleToObject(2.10, { considerTokenScale: true })
.opacity(0.4)
.randomRotation()
.fadeIn(250)
.fadeOut(450)
.repeats(9999, 800, 1200)
.name(GROUP)
.zIndex(0.05)

// Grey 2
.effect()
.file("[Link].2")
.attachTo(token, { bindAlpha: false })
.belowTokens()
.scaleToObject(2.20, { considerTokenScale: true })
.opacity(0.2)
.randomRotation()
.fadeIn(250)
.fadeOut(450)
.repeats(9999, 600, 1000)
.name(GROUP)
.zIndex(0.05)

// Token float & sway


.effect()
.from(token)
.fadeIn(500)
.fadeOut(500)
.attachTo(token, { bindAlpha: false })

.animateProperty("sprite", "position.y", { from: 0, to: -0.6, duration: 2000,


gridUnits: true, ease: "easeOutCubic" })

.loopProperty("sprite", "rotation", { from: -10, to: 10, duration: 1100,


pingPong: true, ease: "easeInOutSine" })
.loopProperty("sprite", "position.x", { from: -[Link]/9, to:
[Link]/9, duration: 2000, pingPong: true, ease: "easeInOutSine" })
.loopProperty("sprite", "position.y", { from: -[Link]/9, to:
[Link]/9, duration: 3000, pingPong: true, ease: "easeInOutSine" })
.name(GROUP)
.persist()

.play();

})
.play();
// --- Release helper ---
function effectUpdate(data) {
new Sequence()
.animation()
.delay(75)
.fadeIn(500)
.fadeOut(500)
.on(token)
.opacity(0.50) // set your preferred final opacity (use 1 for fully visible)
.wait(50)
.thenDo(() => {
[Link]({ name: GROUP });
})
.play();
}

Common questions

Powered by AI

The Dialog component provides an interface for user interaction, allowing users to release the levitation effect by clicking the "Release" button. It enhances interaction by providing a user-driven control within the animation, making the script more dynamic and interactive. By offering a direct way to trigger specific functions, it enables users to manage the animation effects initiated on the token .

To achieve this, you need to adjust the part of the code responsible for animating the token separately from the other effects. The current script already specifies different behaviors for different elements of the animation, with the token being animated by changing its rotation and position over time. Ensure that the loop property `.loopProperty("sprite", "rotation", { from: -10, to: 10, duration: 1100, pingPong: true, ease: "easeInOutSine" })` is correctly applied solely to the token to isolate its spinning motion .

The principle of easing is used in the animation script to refine the motion dynamics and create more naturalistic animations. Functions like `easeOutCubic` and `easeInOutSine` manipulate the rate of property changes, allowing for smooth acceleration or deceleration. This tweaking results in more fluid, lifelike movement, as opposed to linear, robotic motions, enhancing the realism and aesthetic quality of the animation .

Attaching effects below tokens establishes a visual hierarchy that maintains the token as the focal point of the animation. This positioning ensures that effects like the wind stream and smoke puffs visually support and enhance the token's animation without overtaking its prominence. By appropriately layering visuals, it creates a coherent and aesthetically pleasing composition that guides viewer attention and emphasizes the primary animated element .

The `fadeIn` and `fadeOut` animations are applied to the wind stream and smoke puff effects to create a smooth transition effect, enhancing the visual appeal. These transitions provide a sense of motion and fluidity, avoiding abrupt changes that can be disorienting or visually jarring for the viewers. This aligns with the typical practice in animations to use transitions for a more seamless and engaging experience .

The use of `randomRotation` attributes in the animation introduces variability and unpredictability, which enhances the viewer's experience by preventing the animation from appearing mechanical or overly repetitive. By adding randomness to the rotation of smoke effects, it creates a sense of natural disorder and complexity akin to real-life visual experiences, thereby enriching the overall perceived authenticity of the animation .

The script includes multiple overlapping smoke puffs with different timing intervals to craft nuanced, rich animation dynamics. This approach prevents synchronization, averting mechanical, repetitive patterns, and simulates the natural variability seen in real-world smoke behavior. By altering the timing intervals, each puff emerges and dissipates independently, creating a more organic and complex visual effect .

The `opacity` setting in the animation script adjusts the transparency of the animation components, playing a crucial role in determining their visibility and emphasis. For instance, varying opacity levels allow certain elements like the smoke puffs to blend seamlessly with the background, ensuring they support rather than distract from the main token. This creates a layered depth and helps in focusing viewer attention strategically .

The implementation of cleanup functionality using a group identifier, `GROUP`, to manage animation effects demonstrates the principle of manageability and modularity in coding. By grouping effects and managing their lifecycle, the script is easier to maintain, reduces memory leaks, and ensures that resources are freed correctly when effects are no longer needed. This approach aligns with programming best practices for resource management .

Including continuous loops for smoke puff effects enhances the realism and aesthetic of the animation by mimicking natural, environmental dynamics. The looping creates an ongoing, ambient effect that suggests activity and liveliness, aligning with natural phenomena like smoke or mist that do not abruptly start or stop. This decision thereby contributes significantly to the immersive quality of the animation, reinforcing the visual storytelling aspect .

You might also like