PDA

View Full Version : problem with jsfl script for ease in and out


animatorgeek
07-05-2006, 05:38 PM
I'm having trouble with a jsfl script I'm trying to make. It's meant to allow the user to select a frame and create a motion tween there, then create a keyframe , ease out the right side, and ease in the left side (thus creating an ease-in/ease-out). I'm running into a problem, though, because after it creates the tween it doesn't seem to update the position of the symbol. I create the new keyframe and it's the same as the one next one to the left. I grabbed these commands straight from the history, and they obviously work when I do them manually, so I'm nbot sure what the problem is. Is there some sort of command that forces Flash to update the position of tweens?

I'm attempting this in MX 2004. I haven't tried it in version 8.

Anyway, here's the code:

var cur_timeline = fl.getDocumentDOM().getTimeline();

// create a motion tween here
cur_timeline.setFrameProperty('tweenType', 'motion');

// get the current selection
var cur_selection = cur_timeline.getSelectedFrames();
var original_selection = [];

// save the current selection so we can restore it at the end
for(i = 0; i < cur_selection.length; i++)
original_selection[i] = cur_selection[i];

// Collapse the selection to only create one keyframe in each location

for (sel_index = 0; sel_index < cur_selection.length; sel_index += 3)
{
// Make the selection one frame long at the endpoint
cur_selection[sel_index + 1] = cur_selection[sel_index + 2] - 1;
}

// Set the new selection
cur_timeline.setSelectedFrames(cur_selection);

// create a keyframe here
cur_timeline.convertToKeyframes();

// set the easing of the right half to be 100% out
cur_timeline.setFrameProperty('tweenEasing', 100);

// Move all the selections back one frame

for (sel_index = 0; sel_index < cur_selection.length; sel_index += 3)
{
cur_selection[sel_index + 1]--; // decrement the start of the selection
if(cur_selection[sel_index + 1] < 0) // and correct it if it was reduced too low
cur_selection[sel_index + 1] = 0;

// Make the selection one frame long at the endpoint
cur_selection[sel_index + 2]--; // decrement the start of the selection
if(cur_selection[sel_index + 2] < 0) // and correct it if it was reduced too low
cur_selection[sel_index + 2] = 0;
}

// Set the new selection
cur_timeline.setSelectedFrames(cur_selection);

// Now set the ease on the left half of the tween to 100% in
cur_timeline.setFrameProperty('tweenEasing', -100);

// set back to the original selection
cur_timeline.setSelectedFrames(original_selection) ;

mooska
07-06-2006, 07:47 AM
Dont see moveSelectionBy() anywhere, how it suppost to move anything ?

animatorgeek
07-06-2006, 05:24 PM
Dont see moveSelectionBy() anywhere, how it suppost to move anything ?

It's supposed to move because it's now in the middle of a motion tween between two keyframes with the symbol in different positions. Here's how it looks at the various steps (where "o" is a non-empty keyframe).

At the start:

o.......o

Now create a motion tween:

o>----->o

Now create a keyframe at the cursor:

o>->o>->o

That's where the problem is: that middle keyframe ends up exactly the same as the first one. The symbol is _not_ between its position in the first and last keyframes, which is what I expected to happen (and _would_ happen if I were doing it manually). It's creating the middle keyframe as if the motion tween didn't exist.

-David

krayzeebean
07-07-2006, 04:53 PM
I ran into the same thing on one of the scripts I made a few months ago. I came up with a workaround (converted the tween to keyframes), but the only thing I think you can do in your case is make the user add the motion tween before running the script.

animatorgeek
07-10-2006, 01:36 AM
Problem solved! Turns out I just had to replace convertToKeyframes() with insertKeyframe(). Now the script works beautifully. If anyone's interested in the final product, here it is:

// "Ease in and out.jsfl"
//
// created by David Johnston July 9th 2006
//
// select a frame(s) then run this. It will automatically
// create a motion tween with both ease in and out, with the
// selected frame(s) in the middle. Rock!

var cur_timeline = fl.getDocumentDOM().getTimeline();

// create a motion tween here
cur_timeline.setFrameProperty('tweenType', 'motion');

// get the current selection
var cur_selection = cur_timeline.getSelectedFrames();
var original_selection = [];

// save the current selection so we can restore it at the end
for(i = 0; i < cur_selection.length; i++)
original_selection[i] = cur_selection[i];

// Collapse the selection to only create one keyframe in each location

for (sel_index = 0; sel_index < cur_selection.length; sel_index += 3)
{
// Make the selection one frame long at the endpoint
cur_selection[sel_index + 1] = cur_selection[sel_index + 2] - 1;
}

// Set the new selection
cur_timeline.setSelectedFrames(cur_selection);

// create a keyframe here
cur_timeline.insertKeyframe();

// set the easing of the right half to be 100% out
cur_timeline.setFrameProperty('tweenEasing', 100);

// Move all the selections back one frame

for (sel_index = 0; sel_index < cur_selection.length; sel_index += 3)
{
cur_selection[sel_index + 1]--; // decrement the start of the selection
if(cur_selection[sel_index + 1] < 0) // and correct it if it was reduced too low
cur_selection[sel_index + 1] = 0;

// Make the selection one frame long at the endpoint
cur_selection[sel_index + 2]--; // decrement the start of the selection
if(cur_selection[sel_index + 2] < 0) // and correct it if it was reduced too low
cur_selection[sel_index + 2] = 0;
}

// Set the new selection
cur_timeline.setSelectedFrames(cur_selection);

// Now set the ease on the left half of the tween to 100% in
cur_timeline.setFrameProperty('tweenEasing', -100);

// set back to the original selection
cur_timeline.setSelectedFrames(original_selection) ;

krayzeebean
07-10-2006, 07:05 PM
Problem solved! Turns out I just had to replace convertToKeyframes() with insertKeyframe(). Now the script works beautifully. If anyone's interested in the final product, here it is:


Are you running this from the commands menu? The script works if i double-click it from outside of Flash, but if I run it from the commands menu the symbols position isn't updated. The original version you posted also works when double-clicked, but not from the commands menu.

animatorgeek
07-19-2006, 10:22 PM
Are you running this from the commands menu? The script works if i double-click it from outside of Flash, but if I run it from the commands menu the symbols position isn't updated. The original version you posted also works when double-clicked, but not from the commands menu.

Yes, I'm running it from the commands menu. Since posting that last message I discovered that this new version only works sometimes, and I can't figure out what decides whether it will work or not. I must say, this problem is rather annoying. Why should it be so hard to do this? Why must Flash behave differently on different executions of the same commands (i.e. manually, from the commands menu, and from outside Flash).

I'm just about to give up on this. Can anyone give me any insights?

-David

bigevilbrain
07-31-2006, 04:53 PM
Hi animatorgeek,

You just need to add some error checking:

For instance:
if (fl.getDocumentDOM() == null) { // No documents are open...
if (cur_selection.length == 0) { // No frame(s) selected...


I updated the script and added some functionality. The middle keyframe is added automatically by the script. But, you still need to manually set the motion or shape tween.

At the start:
o.......o

Create a motion/shape tween with 0 easing:
o>----->o

Select a frame anywhere in-between:
o>---[]->o

Now run the script... Result:
o>->o>->o


Also, you can select multiple frames and layers:
o.....o>-----[]-->o.........
o..........o>-----[]-->o....

-- Alex


// "Ease in and out.jsfl"
//
// created by David Johnston July 9th 2006
//
// select a frame(s) then run this. It will automatically
// create a motion tween with both ease in and out, with the
// selected frame(s) in the middle. Rock!
//
// updated by Alex Palmo July 31th 2006

if (fl.getDocumentDOM() == null) {

// No documents are open...

} else {

// Timeline
var cur_timeline = fl.getDocumentDOM().getTimeline();

// Get selected frames
var cur_selection = cur_timeline.getSelectedFrames();
if (cur_selection.length == 0) {
fl.trace( "No frame(s) selected..." );

} else {

// Save original selection so we can restore it at the end...
var original_selection = cur_selection.slice();

// Loop through selection
for (sel_index = 0; sel_index < cur_selection.length; sel_index += 3) {

// Save selection data
var layer_index = cur_selection[sel_index];
var layer_ref = cur_timeline.layers[layer_index];

// We only care about the start frame...
var sel_start = cur_selection[sel_index+1];
// var sel_end = cur_selection[sel_index+2];

// Find frames 'around' the selection
var prev_keyframe = undefined;
var next_keyframe = undefined;

var frameArray = layer_ref.frames;
var n = frameArray.length;
for (i=0; i<n; i++) {
if (i == frameArray[i].startFrame) {
// Frame is a keyframe

// Find "next" keyframe
if ( i > sel_start ) {
if ( next_keyframe == undefined ) {
next_keyframe = i;
} else {
if ( i < next_keyframe ) {
next_keyframe = i;
}
}
}

// Find "previous" keyframe
if ( i < sel_start ) {
if ( prev_keyframe == undefined ) {
prev_keyframe = i;
} else {
if ( i > prev_keyframe ) {
prev_keyframe = i;
}
}
}

}
}

// fl.trace("prev_keyframe = "+prev_keyframe);
// fl.trace("next_keyframe = "+next_keyframe);

if (prev_keyframe != undefined && next_keyframe != undefined) {

// Calculate 'middle' frame...
middle_keyframe = Math.round((next_keyframe-prev_keyframe)*0.5)+prev_keyframe;
// fl.trace("middle_keyframe = "+middle_keyframe);

if (middle_keyframe > prev_keyframe && middle_keyframe < next_keyframe) {

// You need to manually set a motion tween with 0 easing...
// layer_ref.frames[middle_keyframe].tweenType = "motion";
// layer_ref.frames[middle_keyframe].tweenEasing = 0;

var tween = layer_ref.frames[middle_keyframe].tweenType;
var easing = layer_ref.frames[middle_keyframe].tweenEasing;

if (tween == "none") {
fl.trace( "Tween should be set to 'motion' or 'shape'..." );
} else if (easing != 0) {
fl.trace( "Easing should be set to '0'..." );
} else {
cur_timeline.currentLayer = layer_index;
cur_timeline.insertKeyframe(middle_keyframe);

layer_ref.frames[middle_keyframe].tweenType = tween;
layer_ref.frames[middle_keyframe].tweenEasing = 100;
layer_ref.frames[middle_keyframe].name = "// easeInOut";

layer_ref.frames[prev_keyframe].tweenType = tween;
layer_ref.frames[prev_keyframe].tweenEasing = -100;
}

}
}

}

// Set back to the original selection
cur_timeline.setSelectedFrames(original_selection) ;

}
}

animatorgeek
03-01-2010, 09:52 PM
After years of just sucking it up and accepting that I couldn't set a keyframe in the middle of a newly-created motion tween and have the symbol's position be correct, I finally figured out the solution. It's pretty simple: After creating the motion tween, select nothing, like this:

fl.getDocumentDOM().setSelectionRect({left:0, top:0, right:0, bottom:0});

Here's my new version:


// "Ease in and out.jsfl"
// By David Johnston
// Last modified 2:19 PM Monday, March 01, 2010
//
// select a frame(s) then run this. It will automatically
// create a motion tween with both ease in and out, with the
// selected frame(s) in the middle. Rock!

doc = fl.getDocumentDOM();

if(doc != null)
{
var cur_timeline = fl.getDocumentDOM().getTimeline();

// create a motion tween here
cur_timeline.setFrameProperty('tweenType', 'motion');

// Workaround: select nothing, so that Flash realizes that the symbol is at a new position now
fl.getDocumentDOM().setSelectionRect({left:0, top:0, right:0, bottom:0});

// get the current selection
var cur_selection = cur_timeline.getSelectedFrames();
var original_selection = [];

// save the current selection so we can restore it at the end
for(i = 0; i < cur_selection.length; i++)
original_selection[i] = cur_selection[i];

// Collapse the selection to only create one keyframe in each location

for (sel_index = 0; sel_index < cur_selection.length; sel_index += 3)
{
// Make the selection one frame long at the endpoint
cur_selection[sel_index + 1] = cur_selection[sel_index + 2] - 1;
}

// Set the new selection
cur_timeline.setSelectedFrames(cur_selection);

// create a keyframe here
cur_timeline.insertKeyframe();

// set the easing of the right half to be 100% out
cur_timeline.setFrameProperty('tweenEasing', 100);

// Move all the selections back one frame

for (sel_index = 0; sel_index < cur_selection.length; sel_index += 3)
{
cur_selection[sel_index + 1]--; // decrement the start of the selection
if(cur_selection[sel_index + 1] < 0) // and correct it if it was reduced too low
cur_selection[sel_index + 1] = 0;

// Make the selection one frame long at the endpoint
cur_selection[sel_index + 2]--; // decrement the start of the selection
if(cur_selection[sel_index + 2] < 0) // and correct it if it was reduced too low
cur_selection[sel_index + 2] = 0;
}

// Set the new selection
cur_timeline.setSelectedFrames(cur_selection);

// Now set the ease on the left half of the tween to 100% in
cur_timeline.setFrameProperty('tweenEasing', -100);

// set back to the original selection
cur_timeline.setSelectedFrames(original_selection) ;
}