Save a time value

Moderators: Disciple, zlovatt

byronnash
Posts: 321
Joined: July 7th, 2004, 2:30 pm
Location: Charlotte, NC
Contact:

I'm trying to store the value of the time when an event happens. For instance, when a layer's position X goes past a certain point, I'd like to know what the time was and store it in a variable. Is there a way to do this?
Dan Ebberts
Posts: 320
Joined: June 26th, 2004, 10:01 am
Location: Folsom, CA
Contact:

You'd have to write an expression that loops through the timeline frame by frame to check for the event.

Or else, you could write a script to find the event and leave the time in a slider value - something like that anyway.

Dan
byronnash
Posts: 321
Joined: July 7th, 2004, 2:30 pm
Location: Charlotte, NC
Contact:

This is what I have so far.

Code: Select all

indexTime = index-1;
v1 = thisComp.layer("master").position.valueAtTime(indexTime);

s = v1[0];
distance = thisComp.layer("master").position[0] - v1[0];

if (distance > 100){
s =  thisComp.layer("master").position[0];
}
[s,position[1]]

It's sort of rough and it doesn't do exactly what I want yet. I'm mainly trying to figure out this one step. I tried using a while loop but I couln't get that to work. I have a pretty good understanding of JavaScript I think but I get at a loss sometimes when trying to deal with it being constantly evaluated.
davestewart
Posts: 114
Joined: March 10th, 2005, 5:50 am
Location: London, UK
Contact:

What's your goal byron?
byronnash
Posts: 321
Joined: July 7th, 2004, 2:30 pm
Location: Charlotte, NC
Contact:

My goal is to animate a null around the screen "dropping" objects every X pixels. I want to have an animating precomp that is evenly spaced along an object motion path regardless of the speed it travels. It would be ideal to have the precomp object "recycle" after it's done animating and go to the next spot on the path. I guess it's sort of an advanced motion trail thing. I had a solution that I've used before that uses the layer index to derive a position along a motion path, but the objects compress and expand as the master object changes speed.
davestewart
Posts: 114
Joined: March 10th, 2005, 5:50 am
Location: London, UK
Contact:

This code works on a left / right / left wiggly path...
You need a comp with 2 layers: travelling and falling.

Every time the travelling layer goes over 300 px it executes the code ONCE, until it then goes under 300px ... then it waits for the next time it goes over.

Code: Select all

var comp		= app.project.activeItem
var travelling	= comp.layers.byName('travelling')
var falling		= comp.layers.byName('falling')
var flag		= false
var xLimit		= 300

for(var t = 0; t<comp.duration; t+=comp.frameDuration){
	var x = travelling.position.valueAtTime(t,true)[0]
	if(x>xLimit){
		if(flag==false){
			flag=true
			alert([t,x])
			/*
			your code here
			*/
			}
		}
	else{
		flag = false
		}
	}
Should give you some ideas anyway...
Last edited by davestewart on April 3rd, 2006, 7:41 am, edited 2 times in total.
davestewart
Posts: 114
Joined: March 10th, 2005, 5:50 am
Location: London, UK
Contact:

Just realized that this is in the expressions conference... sorry!
byronnash
Posts: 321
Joined: July 7th, 2004, 2:30 pm
Location: Charlotte, NC
Contact:

That's alright, It's still helpful.
Dan Ebberts
Posts: 320
Joined: June 26th, 2004, 10:01 am
Location: Folsom, CA
Contact:

OK - give this a try. In a fresh comp, create a null and name it "template". Animate it tracing out your path over a fixed period (say 4 seconds). Use roving keyframes so the speed is constant. Add a slider (range 0 to 100) to "template" and name the slider "travel".

Now add the layers that you want to deposit along the path (above "template" in the layer stack).

Add this postion expression to the new layers:

tempStart = 0; //start time of template motion
tempEnd = 4.0; //end time of template motion

t = thisComp.layer("template");
travel = t.effect("travel")("Slider")/100;
myTravel = Math.min(travel,index/(thisComp.numLayers - 1))
t.position.valueAtTime(linear(myTravel,tempStart,tempEnd));


Animate the "travel" slider. It may not be exactly what you're looking for, but it might give you some ideas.

Dan
byronnash
Posts: 321
Joined: July 7th, 2004, 2:30 pm
Location: Charlotte, NC
Contact:

Thanks Dan. I had a similar approach that I have used in the past. It looks something like this.

I have a layer called "Master" that is animated. It also has a slider on it called "Compression"

Slave Position

Code: Select all

c = thisComp.layer("master").effect("compression")("Slider");

thisComp.layer("master").transform.position.valueAtTime(index/c)
Slave Opacity

Code: Select all

c = thisComp.layer("master").effect("compression")("Slider");
thisTime = index/c;
if (time >= thisTime){
100
} 

I may end up scripting a solution using Dave's code up there. You'll see it on this forum if I can get around to it.
byronnash
Posts: 321
Joined: July 7th, 2004, 2:30 pm
Location: Charlotte, NC
Contact:

I've taken this one step further now. I have added a scale animation starting at the first frame of the comp. Then add this expression to the scale property:

Code: Select all

c = thisComp.layer("master").effect("compression")("Slider");
thisTime = index/c;
transform.scale.valueAtTime(time - thisTime)
Image
As you can see, the "compression" is animated at the end. I'm still wanting to get them evenly spaced without having to force my master into roving keyframes.
Dan Ebberts
Posts: 320
Joined: June 26th, 2004, 10:01 am
Location: Folsom, CA
Contact:

I think a combination of what you have here and the method I described will solve your spacing problem. The key is to use roving keyframes just to trace out the path, but then you use the travel slider to control the speed and direction of your leader and the depositing of the followers. The timing of the resulting animation is completely independent of the animation used to create the path. Maybe you understood that already, but I just wanted to make sure.

Dan
byronnash
Posts: 321
Joined: July 7th, 2004, 2:30 pm
Location: Charlotte, NC
Contact:

Thanks Dan, I went back and tried your approach again and I'm getting better results. The first time I was using it wrong so I had a bad output. Your solution is very insightful. I've tried to get a handle on it and adapt it to to what I'm striving for.

This is my Opacity Expression

Code: Select all

tempStart = 0; //start time of template motion
tempEnd = 4.0; //end time of template motion

t = thisComp.layer("template");
travel = t.effect("travel")("Slider")/100;
myTravel = Math.min(travel,index/(thisComp.numLayers - 1));
result = 100;
if (myTravel >= travel){
result = 0;
}
result
My slave layer is an animated pre-comp so I am trying to use an expression on the Time Remap to offset the precomp start time. Here's my code:

Code: Select all

tempStart = 0; //start time of template motion
tempEnd = 4.0; //end time of template motion

t = thisComp.layer("template");
travel = t.effect("travel")("Slider")/100;
myTravel = Math.min(travel,index/(thisComp.numLayers - 1));
result = timeRemap.valueAtTime(time-(linear(myTravel, tempStart, tempEnd)+travel));
if (myTravel >= travel){
result = 0;
}
result
The opacity is working as intended and for the most part the Time Remap is too. I am getting some strange deviation however. when my "travel" slider changes speeds I think. I'm a bit stumped on why it's getting the offset correct on some layers but not others.

Thanks for lending your expertise.
Dan Ebberts
Posts: 320
Joined: June 26th, 2004, 10:01 am
Location: Folsom, CA
Contact:

How is the time offset supposed to work?

Dan
byronnash
Posts: 321
Joined: July 7th, 2004, 2:30 pm
Location: Charlotte, NC
Contact:

My precomp animation starts at frame one. I have a time remap on each slave layer in the main comp. I want to just offset the time remap animation to start when the layer stops in it's final position. I though I had it figured out with

Code: Select all

result = timeRemap.valueAtTime(time-(linear(myTravel, tempStart, tempEnd)+travel)); 
I'm taking the valueAtTime of the remap and trying to shift it to a later time. From what I saw in your equations, the myTravel variable changes until it gets to it's spot on the curve. It's working on the beginning and end layers but get's thrown off some in the middle. I'm sure it's something about how I'm figuring the offset time

Code: Select all

time-(linear(myTravel, tempStart, tempEnd)+travel
Post Reply