Copy link to clipboard
Copied
Can you use one movieclip's position to control the frame number of another movieclip?
I have two movieclip's on my stage - one called 'handle' and one called 'plane'. The plane MC has 63 frames in it and I would like to move through the frames by dragging the handle MC up and down. I have already set up a bounding box for the 'handle' and set it up to be able to drag it up and down along the y axis with this code: (thanks to another forum user for helping me with this code in an earlier post: Createjs - dragging an object within a bounding box )
var handleHeight = 20; //actually half the height
var bounds = {x:623, y:212, width:143, height:283};
var sliderBoundary = new createjs.Shape();
sliderBoundary.graphics.beginStroke("#999")
.setStrokeStyle(2)
.drawRect(bounds.x, bounds.y, bounds.width, bounds.height);
this.stage.addChild(sliderBoundary);
this.handle.addEventListener("pressmove", fl_MouseClickHandler_2.bind(this));
function fl_MouseClickHandler_2(evt){
evt.currentTarget.y = Math.max(bounds.y + handleHeight, Math.min(bounds.y + bounds.height - handleHeight, evt.stageY));
}
this.handle.x = 704;
this.handle.y = bounds.y + bounds.height / 2;
From here, I've figured out how to adjust the 'plane' MC frame based off of static positions of the handle - I have a function for when the handle is at the top of the bounding box and one for when it's at the bottom, here is how that code looks:
this.stage.addEventListener("tick", planetop.bind(this));
function planetop(){
if (this.handle.y <= 233){
this.lift.plane.gotoAndStop(63);
this.lift.heli.gotoAndStop(63);
}
}
this.stage.addEventListener("tick", planebottom.bind(this));
function planebottom(){
if (this.handle.y >= 472) {
this.lift.plane.gotoAndStop(61);
this.lift.heli.gotoAndStop(61);
}
}
but what I would like to do is have 'plane' (I have another MC called 'heli', the user can toggle between the two with some other buttons) move evenly through it's 63 frames based on the position of the 'handle' y axis - having it stop at frame 63 when the handle is at the top and stop at frame 1 when the handle is at the bottom (I hope this makes sense). I'm not a coder and not very good with math so any help with how to accomplish this would be much appreciated!
Thanks.
...
keelym35886708 wrote
Thank you for the response!
I'm trying to utilize this code, but I'm a little confused on some sections. For the initialize part - is handle position 1 and handle position 2 referring to the y axis coordinates for when the handle is at it's top limit and bottom limit? For 0 is that meant to just be 0?
handle position 1 is handle's y value/position that causes plane to be at its first frame
handle position 2 is handle's y value/position that causes plane to be at its last fram
Copy link to clipboard
Copied
you can use paramF for linear interpolation:
// initialize
paramF(this.handle,handle position 1, 0, handle position2, this.plane.totalFrames-1);
// to use
function fl_MouseClickHandler_2(evt){
this.plane.gotoAndStop(Math.round(this.handle.m*this.handle.y+this.handle.b));
}
function paramF(mc,x1,y1,x2,y2){
mc.m=(y1-y2)/(x1-x2);
mc.b=y1-mc.m*x1
Copy link to clipboard
Copied
Thank you for the response!
I'm trying to utilize this code, but I'm a little confused on some sections. For the initialize part - is handle position 1 and handle position 2 referring to the y axis coordinates for when the handle is at it's top limit and bottom limit? For 0 is that meant to just be 0?
Then in the function paramF section - for x1 and x2 I'm not sure what to enter, since the x axis number doesn't change on my handle mc. I'm assuming the 'mc' is meant to be replaced by this.handle (?)
I can't seem to get the code to work, clarification would be much appreciated. Thanks for your help.
Copy link to clipboard
Copied
keelym35886708 wrote
Thank you for the response!
I'm trying to utilize this code, but I'm a little confused on some sections. For the initialize part - is handle position 1 and handle position 2 referring to the y axis coordinates for when the handle is at it's top limit and bottom limit? For 0 is that meant to just be 0?
handle position 1 is handle's y value/position that causes plane to be at its first frame
handle position 2 is handle's y value/position that causes plane to be at its last frame
Then in the function paramF section - for x1 and x2 I'm not sure what to enter, since the x axis number doesn't change on my handle mc. I'm assuming the 'mc' is meant to be replaced by this.handle (?)
don't change anything in in paramF or anywhere other than replacing handle position 1 and 2 with the correct y values.
Copy link to clipboard
Copied
Just got it working, THANK YOU!
Copy link to clipboard
Copied
you're welcome.
Copy link to clipboard
Copied
Had a very similar situation -- needed a scroll bar to control a movie clip.
This thread is incredibly helpful, and timely.
Was able to get the plane to stop at the extremes, but was not able to get it to step through the plane movie clip. both movie clips vanish. Only thing I can figure out is I must be screwing up when it comes to swapping out the handle position 1 and handle position 2 values that you talk about in one of your previous responses. So is it supposed read something like this (within the area of the bounding box):
paramF(this.handle,234, 470, this.plane.totalFrames-1);
Otherwise, does the placement of the initialize and functions change anything? Tried different combinations, but no luck.
Copy link to clipboard
Copied
How I ended up writing it getting it to work properly was -
paramF(this.handle, y=233, 0, y=475, this.lift.plane.totalFrames-1); // my plane movieclip is embedded in another MC called lift
then I added the function part -
this.lift.plane.gotoAndStop(Math.round(this.handle.m*this.handle.y+this.handle.b));
this.lift.heli.gotoAndStop(Math.round(this.handle.m*this.handle.y+this.handle.b));
inside of my original "pressmove" event listener for my handle. So my final eventListener for handle looked like -
this.handle.addEventListener("pressmove", fl_MouseClickHandler_2.bind(this));
function fl_MouseClickHandler_2(evt){
evt.currentTarget.y = Math.max(bounds.y + handleHeight, Math.min(bounds.y + bounds.height - handleHeight, evt.stageY));
this.lift.plane.gotoAndStop(Math.round(this.handle.m*this.handle.y+this.handle.b));
this.lift.heli.gotoAndStop(Math.round(this.handle.m*this.handle.y+this.handle.b));
}
Hope that helps you!
Copy link to clipboard
Copied
Hm.
Still seems to blow up whenever I uncomment out the paramF(this.handle, y=233, 0, y=472, this.plane.totalFrames-1);
So, in it's entirety the script should look something like the following?
var handleHeight = 20; //actually half the height
var bounds = {x:623, y:212, width:143, height:283};
var sliderBoundary = new createjs.Shape();
sliderBoundary.graphics.beginStroke("#999")
.setStrokeStyle(2)
.drawRect(bounds.x, bounds.y, bounds.width, bounds.height);
this.stage.addChild(sliderBoundary);
paramF(this.handle, y=233, 0, y=472, this.plane.totalFrames-1);
this.handle.addEventListener("pressmove", fl_MouseClickHandler_2.bind(this));
function fl_MouseClickHandler_2(evt){
evt.currentTarget.y = Math.max(bounds.y + handleHeight, Math.min(bounds.y + bounds.height - handleHeight, evt.stageY));
this.plane.gotoAndStop(Math.round(this.handle.m*this.handle.y+this.handle.b));
//this.lift.heli.gotoAndStop(Math.round(this.handle.m*this.handle.y+this.handle.b));
}
this.handle.x = 704;
this.handle.y = bounds.y + bounds.height / 2;
this.stage.addEventListener("tick", planetop.bind(this));
function planetop(){
if (this.handle.y <= 233){
this.plane.gotoAndStop(63);
//this.lift.heli.gotoAndStop(63);
}
}
this.stage.addEventListener("tick", planebottom.bind(this));
function planebottom(){
if (this.handle.y >= 472) {
this.plane.gotoAndStop(61);
//this.lift.heli.gotoAndStop(61);
}
}
function paramF(mc,x1,y1,x2,y2){
mc.m=(y1-y2)/(x1-x2);
mc.b=y1-mc.m*x1
}
Copy link to clipboard
Copied
Why do you keep trying to assign to y in your call to paramF? That variable doesn't even exist.
Copy link to clipboard
Copied
the first error i see is:
paramF(this.handle, y=233, 0, y=472, this.plane.totalFrames-1);
should be:
paramF(this.handle, 233, 0, 472, this.plane.totalFrames-1);
Copy link to clipboard
Copied
I don't really know code, but I have it written like -
paramF(this.handle, y=233, 0, y=475, this.lift.plane.totalFrames-1);
in my project and it works. My guess is it may be something to do with your bit of code:
this.stage.addEventListener("tick", planebottom.bind(this));
function planebottom(){
if (this.handle.y >= 472) {
this.plane.gotoAndStop(61);
//this.lift.heli.gotoAndStop(61);
}
}
I'm only guessing that since I don't have that event listener or function in my project and mine is working. But I couldn't tell you why that would be messing it up. Does it work if you take that out? For my movieclips (plane and heli) I have them revealed by two buttons. I set their visibility to false until the buttons are clicked which toggles their visibility on.
Copy link to clipboard
Copied
Also, just tested writing it like -
paramF(this.handle, 233, 0, 475, this.lift.plane.totalFrames-1);
and it still works.
Copy link to clipboard
Copied
i don't know who's talking to whom, but this is wrong:
paramF(this.handle, y=233, 0, y=472, this.plane.totalFrames-1);
and this is unrelated to anything in this thread:
this.stage.addEventListener("tick", planebottom.bind(this));
function planebottom(){
if (this.handle.y >= 472) {
this.plane.gotoAndStop(61);
//this.lift.heli.gotoAndStop(61);
}
}
Copy link to clipboard
Copied
Was able to get it going. Works great.
Rebuilt the project from scratch, so wasn't sure exactly what the hangup was.
Now if I wanted to go the other way is there an easy way to do that?
In addition to the slider had a play button that triggered the movie clip. Of course when you play the movie clip via the play button the slider has no idea what's going on and gets lost behind.
Copy link to clipboard
Copied
yes, to go from frame to slider position:
this.handle.y=(this.plane.currentFrame-this.handle.b)/this.handle.m
Copy link to clipboard
Copied
Aren't I already telling the handle where to go here:
this.handle.x = 704;
this.handle.y = bounds.y + bounds.height / 2;
this.stage.addEventListener("tick", planetop.bind(this));
function planetop(){
if (this.handle.y <= 233){
this.plane.gotoAndStop(63);
//this.lift.heli.gotoAndStop(63);
}
Was trying to make it so that you could hit the play button and the slider would move along like a play head, or alternatively you'd could scroll through the movie moving the slider.
Copy link to clipboard
Copied
your code may do what you want, but it does not conform to a linear relationship between two variables like one objects y position and another movieclip's frame to display, so i don't know what you want.
Copy link to clipboard
Copied
Kglad,
Not sure exactly what you meant by the previous response.
Tried the code you'd supplied last week -- this.handle.y=(this.plane.currentFrame-this.handle.b)/this.handle.m -- but it wasn't working. My guess was either I'd placed it in the wrong spot, or there was more to it, like I had to build a listener that would be constantly monitoring the progress of the timebar movieclip and updating the slider's progress.
Copy link to clipboard
Copied
that code needs to execute whenever handle's y property changes.
Copy link to clipboard
Copied
Thanks Kglad!
Got it working with:
this.stage.addEventListener("tick", moveslider.bind(this));
function moveslider(){
this.handle.x=(this.circuit.currentFrame-this.handle.b)/this.handle.m;
//
}
Copy link to clipboard
Copied
you're welcome.
Copy link to clipboard
Copied
you're missing one parameter. this is a simple linear function defined by two points:
m(234)+b is mapped to 0 (the first frame in a canvas movieclip)
m(470)+b is mapped to the last frame (totalFrames-1 in a canvas movieclp)
so using:
paramF(this.handle,234,0,470,this.plane.totalFrames-1);
defines this.handle.m and this.handle.b such that:
this.handle.m*234+this.handle.b=0; // and
this.handle.m*470+this.handle.b=this.plane.totalFrames-1
Copy link to clipboard
Copied
If anyone runs into the issue I was having, what was happening was that the stage was scaling but the mouse coordinates weren't.
The fix was:
var p=this.globalToLocal(evt.stageX, evt.stageY);
this.handle.addEventListener("pressmove", fl_MouseClickHandler_2.bind(this));
function fl_MouseClickHandler_2(evt){
var p=this.globalToLocal(evt.stageX, evt.stageY);
evt.currentTarget.x = Math.max(bounds.x + handleDistance, Math.min(bounds.x + bounds.width - handleDistance, p.x));
// evt.currentTarget.x = Math.max(bounds.x + evt.currentTarget.regX,
// Math.min(bounds.x + bounds.width - handleDistance + evt.currentTarget.regX, evt.stageX));
this.circuit.gotoAndStop(Math.round(this.handle.m*this.handle.x+this.handle.b));
}
Copy link to clipboard
Copied
Thanks montana,
I've been playing with the registration point on my movieclip and it's in the same place at the movieclip level and inside the movieclip at the graphic level. I'm still having the issue, so I'm not sure where I'm slipping up . . I even made an entirely new movieclip just to reset everything. I'm not doing a scaling stage or responsive stage or anything so I don't think it's anything to do with that . . I'm going to keep experimenting and see what I can find.
One thing I found that's interesting is that I'm using the pressmove function on the movieclip to control another movieclip's timeline - and even when the mouse is above the my sliding moveclip by a decent amount, if I move it up and down the second movieclip that is being controlled will go through it's timeline as if I was 'pressmoving' the slider movieclip . . I checked the bounding box, but it's not any larger than my graphic within the movieclip . . will keep trying things.