Copy link to clipboard
Copied
Hello everyone,
I'm creating a slider animation, and I need an expression to move an object of a certain value (defined by a slider name A) and this, every X secondes (Slider Name B), and do it Z Time (slider C)
Don't know if this is clear, but here is an example.
Slider A = 50;
Slider B = 2; (use as seconds)
Slider C = 4 (nb of repetition)
I want my object to move from 0 to 50 (slider A value), then make a pause (Slider B, so 2s pause) Then go 50 to 100, then another pause (Slider B, 2s) then 100 to 150 etc.. Z Time (Slider C Value)
I linked a video to show you what a want to do (done with keyframe tho)
Tried many things, but don't find a solution. Do you have idea to help me please ? Is there a way to convert pure Javascript code to AE Expression ?
Regards,
Something like this should work:
dist = effect("Slider A")("Slider")
moveTime = effect("Slider B")("Slider")
holdTime = moveTime;
numMoves = effect("Slider C")("Slider");
period = moveTime + holdTime;
n = Math.floor(time/period);
if (n < numMoves){
t = time%period;
x = n*dist + ease(t,0,moveTime,0,dist);
}else{
x = numMoves*dist;
}
value + [x,0]
You could tie holdTime to a different slider if you want it to be different from the move time.
Try changing this:
strtTime = time - thisLayer.inPoint - delay;
to this:
strtTime = Math.max(time - thisLayer.inPoint - delay,0);
Copy link to clipboard
Copied
Math.round(time%Slider B)*Slider A
Slider C is superfluous. You simply split the layer into two segments - one with teh expression, the other without.
Mylenium
Copy link to clipboard
Copied
By far the easiest solution would be to set a starting keyframe, then move down the timeline to where you want the animation to start and set a second keyframe with the same values, then move down the timeline to where you want the layer to move and move the layer. You now have two keyframes, the first and second are identical and the third is where the layer will move the first time.
Now add a simple loopOut("offset") expression. You can then easily control the easing with a value graph and get s timeline that looks like this:
To stop the animation at a certain point pre-compose, add time remapping, set a keyframe where you want the animation to stop, then delete the last time remapping keyframe.
If you want an expression with sliders you'll have to set up an accumulator. I don't have time to work that out right now. Maybe Dan Ebberts will step in. He could write it without opening AE.
Copy link to clipboard
Copied
Something like this should work:
dist = effect("Slider A")("Slider")
moveTime = effect("Slider B")("Slider")
holdTime = moveTime;
numMoves = effect("Slider C")("Slider");
period = moveTime + holdTime;
n = Math.floor(time/period);
if (n < numMoves){
t = time%period;
x = n*dist + ease(t,0,moveTime,0,dist);
}else{
x = numMoves*dist;
}
value + [x,0]
You could tie holdTime to a different slider if you want it to be different from the move time.
Copy link to clipboard
Copied
Thank you, Dan.
I am turning that into an animation preset and trying to fancy it up with a delay and also an overshoot and decay. If I throw in a delay slider and offset time by the delay and the layer in-point I'm getting jumps in position. I can't figure out how to prevent moves before the delay. Any clues would be appreciated. Here's my expression and a screenshot with a timeline marker at the layer inPoint.
dist = effect("Distance")("Slider");
delay = effect("Start Delay")("Slider") * thisComp.frameDuration;
moveTime = effect("Move Frames")("Slider") * thisComp.frameDuration;
holdTime = effect("Hold Frames")("Slider") * thisComp.frameDuration;
numMoves = effect("Number of moves")("Slider");
strtTime = time - thisLayer.inPoint - delay;
period = moveTime + holdTime;
n = Math.floor(strtTime/period);
if (n < numMoves){
t = strtTime%period;
x = n * dist + easeOut(t,0, moveTime, 0, dist);
}else{
x = numMoves * dist;
}
value + [x,0]
I can't figure out how to prevent movement before the delay.
Copy link to clipboard
Copied
Try changing this:
strtTime = time - thisLayer.inPoint - delay;
to this:
strtTime = Math.max(time - thisLayer.inPoint - delay,0);
Copy link to clipboard
Copied
Perfect.
Thank you, Dan.
Copy link to clipboard
Copied
Thank you so much for your help !!
This is exactly what I wanted ! Will read this code and learn from this.
Regards