Looking at creating a shake animation on user pressing ENTER #1746
-
The goal is to create an effect similar to Discord's error handling animation 👇 I gave it a shot with this snippet:
But seeing two things:
It's likely the above could be refactored to a cleaner state, any tips/suggestions would be greatly appreciated btw, this is what the animation looks like with the above code snippet (not exactly a clean animation so I'm working towards that): |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
Consider this: const { x, y } = useSpring({
from: { x: 0, y: 0 },
to: shakeState.shake ? { x: 1, y: 1 } : { x: 0, y: 0 },
onRest: () => {
if(shakeState.shake){
setShakeState((shakeState) => ({
...shakeState,
shake: false,
}));
}
});
const xInterpolate = x.to(
[0, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 1],
[shakeXStart, shakeXEnd, shakeXStart, shakeXEnd, shakeXStart, shakeXEnd, shakeXStart, shakeXEnd],
);
const yInterpolate = y.to(
[0, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 1],
[shakeYStart, shakeYEnd, shakeYStart, shakeYEnd, shakeYStart, shakeYEnd, shakeYStart, shakeYEnd],
);
// Update state when ready to shake
useEffect(() => {
if (errorState.shakeId && errorState.shakeId !== shakeState.id) {
setShakeState({
id: errorState.shakeId,
shake: true,
});
}
}, [shakeState, errorState.shakeId]);
// component with transform using translate3d
<animated.div
className='command_hub_container'
style={{ x: xInterpolate, y: yInterpolate }}
/> disclaimer, i'm not a 100% the shorthands work with interpolation, although afaik they do However, I would challenge here as to why you need to use const [{ x, y }, api] = useSpring(() => ({
from: { x: 0, y: 0 },
}));
const xInterpolate = x.to(
[0, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 1],
[shakeXStart, shakeXEnd, shakeXStart, shakeXEnd, shakeXStart, shakeXEnd, shakeXStart, shakeXEnd],
);
const yInterpolate = y.to(
[0, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 1],
[shakeYStart, shakeYEnd, shakeYStart, shakeYEnd, shakeYStart, shakeYEnd, shakeYStart, shakeYEnd],
);
// Update state when ready to shake
useEffect(() => {
if (errorState.shakeId && errorState.shakeId !== shakeState.id) {
api.start({
from: { x: 0, y: 0 }, // this line here may be omitable, i'd see if it is for cleaner code.
to: { x: 1, y: 1 }
})
}
}, [shakeState, errorState.shakeId]);
// component with transform using translate3d
<animated.div
className='command_hub_container'
style={{ x: xInterpolate, y: yInterpolate }}
/> You could of course inline those interpolations if you prefer. You might also end up not needing the |
Beta Was this translation helpful? Give feedback.
-
Short answer, for non-interpolation: const Flicker = () => {
const [props, api] = useSpring(() => ({
from: { x: 0 },
}));
return (
<div>
<animated.div style={props}>Flicker</animated.div>
<button
onClick={() => {
api.start({
to: [
{ x: -10 },
{ x: 10 },
{ x: -10 },
{ x: 10 },
{ x: -10 },
{ x: 10 },
{ x: -10 },
{ x: 10 },
{ x: 0 },
],
config: {
duration: 50,
},
});
}}
>
Flicker
</button>
</div>
);
}; |
Beta Was this translation helpful? Give feedback.
Consider this: