Framer Motion: Animation Will not Loop - javascript

I'm trying to loop an animation with the Framer Motion library after a small delay. The animation itself will play when it's mounted, on the webpage refresh, however does not repeat.
Iv'e looked through the docs and this seems to be similar syntax.
const AnimateTrial = {
initial: {
opacity: 0,
x: -100,
y: -35,
scale: 0.9,
},
animate: (i) => {
const delay = 5 + i * 0.5;
return {
opacity: 1,
x: -10,
y: -35,
transition: {
opacity: { delay, duration: 1.5 },
x: { delay, duration: 1.5},
repeatType: "Infinity",
repeatDelay: 5,
},
};
}
Does anyone have an idea? Everything works minus bottom two lines!

The properties inside your transition object are not right. Use repeat in place of repeatType, Write it something like this
transition={{ repeat: Infinity, repeatDelay: 5 }}
If you check the docs repeateType property accepts only "loop" "reverse" "mirror" and not "Infinity".

Related

Stop animation at specific frame?

I'm making a game with Phaser, and I need to have an animation for the health bar going down dynamically stop on a frame, and I couldn't find any clear documentation on the stopOnFrame() method, or the this.anims.getFrame(index) method, both of which woulden't work. I believe that stopOnFrame accepts a frame object, not a frame number but I coulden't figure out how to get that specific frame, as the getFrame() method returned undefined. If there's something I'm missing, my ideal solution looks something like this:
this.hpBar.play({key: 'damageAnimation', startFrame: this.hp})
this.hpBar.stopOnFrame(this.hpBar.getFrame(this.hp - amountOfDamage))
Thanks for any suggestions, cheers!
PS: I know there's some more nuance to how I would use the animations in forwards and reverse to properly create this effect, the example is purely for demonstration.
Two points, you would have to pass a Phaser.Textures.Frame to the stopOnFrame function, and as far as I know the function getFrame doesn't exist (atleast on the phaser sprite GameObject, as shown in your code).
You can use the function getFrameAt on the Animation object, the index has to be here only a valid integer, in the range from 0 - to max frame of the animation.
(btw.: here is the link to the documenation of the stopOnFrame function)
Info: the frame index-count, is based on the frames of the specific animation, not the frame in the spritesheet. (In this example the sprite frame index of the kick is 12, but in the kick animation the index for that specific frame is 2)
Here a Demo:
document.body.style = 'margin:0;';
var config = {
type: Phaser.AUTO,
width: 536,
height: 183,
scene: {
preload,
create
}
};
function preload(){
this.load.spritesheet('brawler',
'http://labs.phaser.io/assets/animations/brawler48x48.png',
{ frameWidth: 48, frameHeight: 48 }
);
this.load.image('brawler-sheet',
'http://labs.phaser.io/assets/animations/brawler48x48.png');
}
function create () {
this.add.text(10,10, 'Click, to Stop on kick (third frame)')
.setScale(1.5)
.setOrigin(0)
.setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
this.anims.create({
key: 'kick',
frames: this.anims.generateFrameNumbers('brawler',
{ frames: [ 10, 11, 12, 13, 10 ] }),
frameRate: 8,
repeat: -1,
repeatDelay: 0
});
this.add.image(140, 20, 'brawler-sheet')
.setOrigin(0)
const cody = this.add.sprite(100, 90);
cody.setScale(3);
cody.play('kick');
this.input.on('pointerdown', () => {
cody.stopOnFrame(cody.anims.currentAnim.getFrameAt(2))
});
}
new Phaser.Game(config);
<script src="//cdn.jsdelivr.net/npm/phaser#3.55.2/dist/phaser.js"></script>
But for a simple healt-bar, I would use a phaser tween, not an animation, like this you can set the value more precise, you can easily update the max-health and "animation" is easy.
Here a demo how I would do it (two visula alternatives):
(I would opt for the second version, if you have some nice heart images or so, I could find a better image for the demo)
document.body.style = 'margin:0;';
var config = {
type: Phaser.AUTO,
width: 536,
height: 183,
scene: {
create,
preload
},
banner: false
};
function preload ()
{
this.load.image('mushroom',
'https://labs.phaser.io/assets/sprites/mushroom16x16.png');
}
let healthMax = 32*5
function create () {
this.add.text(10,10, 'Click, to animate healthbar')
.setScale(1.5)
.setOrigin(0)
.setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
this.healthbarBG = this.add.rectangle(10, 50, 32*5, 10, 0xffffff)
.setOrigin(0);
this.healthbar = this.add.rectangle(12, 52, healthMax - 4, 10 - 4, 0xff0000)
.setOrigin(0);
this.add.text(10, 75, 'Or abit more flashy')
.setOrigin(0)
.setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
let tilespriteBG = this.add.tileSprite(10, 100, 16*5, 16, 'mushroom')
.setOrigin(0)
.setScale(2);
tilespriteBG.setTint(0x2a2a2a)
let tilesprite = this.add.tileSprite(10, 100, 16*5, 16, 'mushroom')
.setOrigin(0)
.setScale(2);
this.input.on('pointerdown', () => {
// remove 50% health
let newHealthWidth = healthMax * .5;
this.tweens.add({
targets: this.healthbar,
width: newHealthWidth,
duration: 750,
ease: 'Power2',
/* this two following properties must be remove, just for demo
yoyo: true,
repeat:-1*/
});
this.tweens.add({
targets: tilesprite,
width: { to: 16 * 5 * .5, from: 16 * 5},
duration: 750,
/* this two following properties must be remove, just for demo
yoyo:true,
repeat:-1*/
});
})
}
new Phaser.Game(config);
<script src="//cdn.jsdelivr.net/npm/phaser#3.55.2/dist/phaser.js"></script>
modifying the ease and/or the duration property (and others), you can make the animation suitable (and spicy) for the most usecases.

framer motion is not transitioning when switched between keyframe animations

I have 2 keyframe animation variants and when I switch between them I want it to happen with the transition. How can I make it transition all the props when switched from one keyframe animation to another (currently it happens instantly)?
const variants = {
...,
horizontalWiggle: {
x: ["40px", "80px"],
y: [0, 0],
transition: { duration: 0.5, yoyo: Infinity }
},
verticalWiggle: {
x: [0, 0],
y: ["8px", "40px"],
transition: { duration: 0.5, yoyo: Infinity }
}
}
Using with framer motion as so:
<motion.div
className="wiggle"
variants={variations}
initial="init"
animate={vertical ? "verticalWiggle" : "horizontalWiggle"}
/>
Link to the sandbox: https://codesandbox.io/s/long-surf-405lho?file=/src/App.js
You have two options:
You should not specify 0 for axis which you do not want to animate. That way there will be no instant jump and will be smooth animation between variants.
The idea is start new animation (new variant) from last position of previous variant. Another words: you need to stop old animation and start new animation from the same value (the same keyframe). That way there also will be no instant jump.
Full example here:
NOTE: if you need to animate between variants - you could create one more variant with animation from STATE-1 to STATE-2.
Like here:
Short Example:
const variations = {
...
horizontalWiggle: {
x: [0, 40, 80, 0],
transition: { duration: 1, repeat: Infinity }
},
verticalWiggle: {
y: ["0px", "20px", "40px", "0px"],
transition: { duration: 1, repeat: Infinity }
}
};

GSAP timeline with repeat is breaking the draggable ease flow

I see that using the "repeat:-1" in timeline is breaking the draggable behavior ease flow.
https://codepen.io/GreenSock/pen/WNedayo?editors=1111
If use "repeat:-1" to loop the animation in above code pen code. observe that drag ease is breaking.
.to("#Handle", {
duration: 100,
x: 1000,
repeat:-1,
ease: "none"
});
You need to put repeat in right place:
handle.t1 = gsap.timeline({
repeat: -1,
onStart() {
console.log('start');
},
onComplete() {
console.log('complete');
}
})
.to("#Handle", {
duration: 100,
x: 1000,
ease: "none"
});

GSAP + PaperJS position animation

I am trying to integrate it into an existing Paper.js application to replace the original .tweenTo function (http://paperjs.org/reference/tween/). The only issue I am facing so far is the "chaining" of the position or point property animations:
https://codepen.io/yevsim/pen/GRmPBZB
paper.install(window)
paper.setup(canvas);
const text = new PointText({
point: new Point(100, 100),
fontFamily: "sans-serif",
fontWeight: "bold",
fontSize: 48,
fillColor: 'black'
});
text.content = 'Move me';
const timeline = gsap.timeline();
timeline.to(text.point, { duration: 1, x: '+=100' });
timeline.to(text.point, { delay: 1, duration: 1, x: '+=100' });
For the reason unknown to me, it moves the text back to its original position before doing the second animation (i.e. instead of going from 100 -> 200 -> 300, it goes 100 -> 200 -> 100 -> 200). Chaining other properties animation e.g. width, height, color, opacity works as expected. I tried to play with replacing point with position, combining them together, but nothing worked for me.
I'm not really sure why but this will work if you store text.point into a variable and use this variable instead of a reference to the actual object when creating your timeline.
Based on your code, here a corrected version:
const text = new PointText({
point: new Point(100, 100),
fontFamily: 'sans-serif',
fontWeight: 'bold',
fontSize: 48,
fillColor: 'black',
content: 'Move me'
});
// Use a variable to reference the property to animate.
const point = text.point;
const timeline = gsap.timeline();
timeline.to(point, { duration: 1, x: '+=100' });
timeline.to(point, { delay: 1, duration: 1, x: '+=100' });

Noty example with velocity - velocity() undefined

I am trying to use this example from Noty's site: http://ned.im/noty/animations.bouncejs.html
I have installed noty.js and its CSS counter part. And I also have downloaded velocity.js and have it linked properly in my site. I know it is linked properly because I can use JQuery to select an element and perform a function on it that is provided by velocity:
$("table").velocity("fadeOut", {
duration: 3500
});
The example that is provided on the noty site though uses a call formatted like this:
new Noty({
text: 'NOTY - animating with velocity!',
animation: {
open: function () {
var n = this;
Velocity(n.barDom, {
left: 450,
scaleY: 2
}, {
duration: 0
});
Velocity(n.barDom, {
left: 0,
scaleY: 1
}, {
easing: [ 8, 8 ]
});
},
It calls it by using Velocity(... when I put this code into my page it errors and using the chrome F12 it says it is undefined. What am I missing from the example? The example for bounce works but I don't like the movement as much.
With the help of the developer we found an issue with the declaration on his site. Velocity doesn't work the way it is called in the question. It needs to be declared with $.Velocity with the current version of NOTY & Velocity
new Noty({
text: 'NOTY - animating with velocity!',
animation: {
open: function () {
var n = this;
$.Velocity(n.barDom, {
left: 450,
scaleY: 2
}, {
duration: 0
});
$.Velocity(n.barDom, {
left: 0,
scaleY: 1
}, {
easing: [ 8, 8 ]
});
},

Categories

Resources