Be a Supporter!

Some mouse scroll wheel interaction

  • 645 Views
  • 7 Replies
New Topic Respond to this Topic
pauljs75
pauljs75
  • Member since: Oct. 26, 2005
  • Offline.
Forum Stats
Member
Level 03
Blank Slate
Some mouse scroll wheel interaction 2007-10-12 00:07:12 Reply

Hello all.

Anyhow, I was fiddling around to come up with some way to get flash to respond to use of the scroll wheel on the mouse. If there were a way to upload a .fla, I would have done that... Anyhow I'll explain where stuff goes in the experiment and paste the relevant code... Should be easy peasy to reproduce it.

Here's the bit that I put on the main timeline in the first frame:

var mwDelta:Number = 0;
var mwTar;

// Following stuff detects mouse wheel scrolling
mwListener = new Object();
mwListener.onMouseWheel = function(delta, scrollTarget) {
	mwDelta = delta;
	mwTar = scrollTarget;
	return mwDelta;
	return mwTar;
};
Mouse.addListener(mwListener);

And then I made 3 different movie clips. One that rotated, one that scaled, and one that flipped frames. I'll show rotation and frames, since scaling code was almost same to rotating (should be easy to figure out)...

On the rotating_mc:

// Following activates turner function inside clip
onClipEvent (enterFrame) {
	this.turner ();
}

And inside the rotating_mc:

function turner() {
	if (_root.mwTar == this) {
		this._rotation -= _root.mwDelta;
	}
}

Then on the flip through frames one:

onClipEvent (enterFrame) {
	this.checkScroll();
	trace("delta: "+_root.mwDelta+"  target: "+_root.mwTar);
}

I did some tracing to see what's going on, since I'm newb to scripting and wanted to see what was going on (if anything). You could omit that.

And inside the flipping frames one:

stop();
function checkScroll() {
	if (_root.mwTar == this) {
		if (_root.mwDelta>0) {
			nextFrame();
		} else if (_root.mwDelta<0) {
			prevFrame();
		} else {
			stop();
		}
	}
}

Believe it or not, that actually did something. 3 Items responding to the mouse wheel in flash, of course not forgetting to click somewhere on the flash to give it focus. (But I think there's a trick somewhere to auto-focus a flash when on the web.) I think the concept behind this would have some uses in actual games or interfaces.

But now I have some questions based on the experiment:
Is that the most efficient way to do something like that?
Good, bad, or ugly code? (I'm still newb, not to mention more artist than programmer anyhow.)
I noticed some lag-like behavior in response to scrolling. How often does the listener update? (Guessing its at framerate in this example, but my trace that updates on a "onFrameEnter" shows repetion 3-4 times.) It's a bit annoying, since the scroll behavior seems to overshoot because of this. (More noticable on the frame flipper.)
And when checking the trace values for scroll delta, I aways get something like +3 or -3. Is that normal? Or do my WinXP control panel mouse scroll settings actually effect that?


View my artworks and crazyness at Barbequed Pixels. Home of the pauljs75 "My Art Post" memorial monument.

KaynSlamdyke
KaynSlamdyke
  • Member since: Jun. 25, 2004
  • Offline.
Forum Stats
Member
Level 16
Melancholy
Response to Some mouse scroll wheel interaction 2007-10-12 05:30:21 Reply

At 10/12/07 12:07 AM, pauljs75 wrote: Hello all.

Hi.


But now I have some questions based on the experiment:
Good, bad, or ugly code? (I'm still newb, not to mention more artist than programmer anyhow.)

Ugly. Your listener's running fine, but the results of it are waiting on a handler. I'll explain more next paragraph. Still, very, very clean for an artists code, and I can tell it's your own work. So good job for a first experiment

I noticed some lag-like behavior in response to scrolling. How often does the listener update? (Guessing its at framerate in this example, but my trace that updates on a "onFrameEnter" shows repetion 3-4 times.) It's a bit annoying, since the scroll behavior seems to overshoot because of this. (More noticable on the frame flipper.)

Listeners update as soon as Flash hears them. However, a few of your events are running on enterFrames, which trigger after Flash has updated the stage in response to it increasing a frame. If you want more response, cut out the middle man and run all your function calls inside the MouseWheel listener.

For example, remove the onEnterFrame block, but put the checkScroll function call inside the myListener.onMouseWheel assignment. Then you won't actually need a myDelta either. Now it'll rotate instantly upon scrolling the wheel, rather than waiting for the next frame. You could also call the turner function from here as well, just so you can see the output's reduced lag.

And when checking the trace values for scroll delta, I aways get something like +3 or -3. Is that normal? Or do my WinXP control panel mouse scroll settings actually effect that?

Pass. I have a feeling it's OS settings though. That's a thing to bear in mind for constructing these applications. Some people will have different mousewheel settings (or sometimes, no wheel at all)


...

BBS Signature
pauljs75
pauljs75
  • Member since: Oct. 26, 2005
  • Offline.
Forum Stats
Member
Level 03
Blank Slate
Response to Some mouse scroll wheel interaction 2007-10-12 06:59:26 Reply

Ah...

Thanks for the response. Yeah, I know it's a bit of a kludge. My understanding of how listeners work wasn't too great anyhow. Took a few tries just to get what I have so far to work... At least I can pick up on things pretty fast if I can get feedback on what my understanding is, something reference books and websites don't do - even if they're excellent for the most part.

The reason behind some of the weirdness was that I was thinking of putting the function code for a movieclip's behavior inside the movieclip, since I'm not sure if I could anticipate everything on the main timeline. Also it'd keep the main timeline cleaner. But I guess this thinking is a little off-kilter for how actionScript works.

So the trick is to figure out what behaviors you want the listener to potentially produce and put the functions for them inside it. Is that right? And just call the function from on the movieClip... I take it that it's also possible to call the function from inside the movieClip, so that way all instances would have the behavior inherently and not have to add a script every time I drag a copy from the library. (I guess it's even more obvious that I'm a newb. But trying to make it clear.)

So it works like this from the main timeline...

var someThing = new Object;
someThing.Listener = function () {
   function doThis () {
      ...stuff...;
   };
   function doThat() {
    ...stuff...;
   };
};
someInput.addListener(someThing);

And then on the movieclip I would put...

_root.someThing.doThis();

Hmmm... Is that right?

As for code being understandable even if ugly or half-bass-ackwards in execution, it's some kind of habit I got into from doing other web stuff and looking at scripts/HTML. It's a real PITA if I forget what something does, so having comments or "logical" variables helps. I guess the bonus is that it helps others out if they need to look for some reason.

I did some more checking, and yeah the delta flash gets is from the mouse prefs setting. Makes it kinda useless as a delta value. (From past math experience, a "delta" should be a value that gives "notches or scroll amount per known time interval", but appears broken in that aspect.) But at least a conditional if-statment can get the useful up/down/neutral part. And sure, not everyone has a scroll wheel, but the option to use it if you can is still pretty cool. (Also nice for lean interfaces not needing sliders or +/- button clutter, etc. For zooming or dials, scroll wheel also seems more intuitive than click-dragging too.)


View my artworks and crazyness at Barbequed Pixels. Home of the pauljs75 "My Art Post" memorial monument.

GustTheASGuy
GustTheASGuy
  • Member since: Nov. 2, 2005
  • Offline.
Forum Stats
Member
Level 08
Blank Slate
Response to Some mouse scroll wheel interaction 2007-10-12 09:12:28 Reply

At 10/12/07 12:07 AM, pauljs75 wrote: var mwDelta:Number = 0;
var mwTar;

// Following stuff detects mouse wheel scrolling
mwListener = new Object();
mwListener.onMouseWheel = function(delta, scrollTarget) {
mwDelta = delta;
mwTar = scrollTarget;
return mwDelta;
return mwTar;

This part is lol. You use 'return' to have 'onMouseWheel (...)' have a value when used in an expression. So it's pretty useless here. The function ends when it does the 'return' statement. Sooo there's no use in doing two in a row. Or any at all.
You'd use multiple return statements kinda like
function (yesplz) { if (yesplz) return 'pie'; cookies (); return 'cookies'; }
(as in if 'yesplz' exit with 'pie' but if not call 'cookies' and then return)

};
Mouse.addListener(mwListener);

Also you don't have to create a whole new object for that because you can just use 'this'.

// Following activates turner function inside clip
onClipEvent (enterFrame) {
this.turner ();
}

Using 'onClipEvent' is not cool. For like no reason. See MovieClip.onEnterFrame, etc..

I noticed some lag-like behavior in response to scrolling. How often does the listener update?

It's instant. Call 'updateAfterEvent' to have Flash update the graphics.

And when checking the trace values for scroll delta, I aways get something like +3 or -3. Is that normal? Or do my WinXP control panel mouse scroll settings actually effect that?

Yup it's the Control panel thingy.

The reason behind some of the weirdness was that I was thinking of putting the function code for a movieclip's behavior inside the movieclip, since I'm not sure if I could anticipate everything on the main timeline. Also it'd keep the main timeline cleaner. But I guess this thinking is a little off-kilter for how actionScript works.

It's better not to have to browse through object to find where you put your code. >.>

So the trick is to figure out what behaviors you want the listener to potentially produce and put the functions for them inside it. Is that right? And just call the function from on the movieClip... I take it that it's also possible to call the function from inside the movieClip, so that way all instances would have the behavior inherently and not have to add a script every time I drag a copy from the library. (I guess it's even more obvious that I'm a newb. But trying to make it clear.)

There are multiple ways to add inherited behaviour (even though they're work exactly the same in the end). The 1337357 is to use classes, but that would not only have you not have the code on the display object but outside of the actual FLA.
For example, rightclick a movieclip in the Library and select Linkage. Check 'Export for AS' and enter an identifier and class 'Twistey'. Write a text file

class Twistey extends MovieClip {
  function onEnterFrame () {
    _rotation += 5;
  }
}

..and save that as 'Twistey.as' next to the FLA. Then you can publish that in Flash and it'll rotate on its own. You can write AS files within Flash too.
Another way to do that without external files is creating a class object thing the AS1 way (the 'class' construct was intoduced in AS2). So clear the class linkage field and check this out:

_global.Twistey = function () {};
Twistey.prototype.onEnterFrame = function () { this._rotation += 5; };
Object.registerClass ('identifier name goes here', Twistey);

And that's pretty much exactly the same except you won't get strict object typing.
Now what I was doing here is assign the 'constructor' function (you'd define it as 'function Twistey () {}' in the 'class' statement if you'd need to) to '_global.Twistey' and then the default 'onEnterFrame' value to its 'prototype' property. Then when you do 'new constructorey (...)' it's the same as doing 'constructorey.apply ({}, [...])', that is, creating an empty object '{}' and then calling 'constructorey' (where arguments are '...') as if it was on it (thus making 'this' inside the functions of the class refer to that object).
Then ANOTHER way is to do the assignment of functions you want to have on the movieclip on its first frame. But (although this makes a diffirence only if you're creating the objects in masses by code) you'd rather not have the whole 'function () {' on that frame because that will cause it to create a new instruction list for every object while you could just do 'onEnterFrame = _parent.enterframeofsuchobjects;' and define that function on its parent referring to the child that is yet to assign its 'onEnterFrame' to itself with 'this'. Basically the same thing as with the classes that I explained previously.

var someThing = new Object;

Ahem, 'new Object ()' but you'd rather use '{}'. You can actually specify properties within that...
{ a : 1, b : 'eleven', c : function () { trace (this.b); } }

someThing.Listener = function () {
function doThis () {
...stuff...;
};
function doThat() {
...stuff...;
};
};
someInput.addListener(someThing);

Yeah AS probably allows defining functions within functions. Meh.

I did some more checking, and yeah the delta flash gets is from the mouse prefs setting. Makes it kinda useless as a delta value. (From past math experience, a "delta" should be a value that gives "notches or scroll amount per known time interval", but appears broken in that aspect.)

It does add up the 3s for me if I scroll it way fast.

All in all I just wanted to pwn Kayn with my smartnessness.


BBS Signature
KaynSlamdyke
KaynSlamdyke
  • Member since: Jun. 25, 2004
  • Offline.
Forum Stats
Member
Level 16
Melancholy
Response to Some mouse scroll wheel interaction 2007-10-12 09:54:20 Reply

At 10/12/07 09:12 AM, GustTheASGuy wrote: All in all I just wanted to pwn Kayn with my smartnessness.

The forums' already established that you're half my age and twice my better.
Do you seriously want me to get you a medal? I could inscribe it with "Congratulations Gust. Just like the rest of the world you are better than me at something"


...

BBS Signature
DanBomer
DanBomer
  • Member since: Apr. 1, 2006
  • Offline.
Forum Stats
Member
Level 09
Blank Slate
Response to Some mouse scroll wheel interaction 2007-10-12 11:01:33 Reply

At 10/12/07 09:54 AM, KaynSlamdyke wrote: The forums' already established that you're half my age and twice my better.
Do you seriously want me to get you a medal? I could inscribe it with "Congratulations Gust. Just like the rest of the world you are better than me at something"

If he doesn't want it, I'll have it. :P

but change gust to Dan lol

BBS Signature
GustTheASGuy
GustTheASGuy
  • Member since: Nov. 2, 2005
  • Offline.
Forum Stats
Member
Level 08
Blank Slate
Response to Some mouse scroll wheel interaction 2007-10-12 13:09:34 Reply

Okay fine I'll stop being so awesome compared to you.


BBS Signature
pauljs75
pauljs75
  • Member since: Oct. 26, 2005
  • Offline.
Forum Stats
Member
Level 03
Blank Slate
Response to Some mouse scroll wheel interaction 2007-10-14 06:01:25 Reply

Anyhow, after spending hours being like the guy banging his head on the keyboard in that one animated .gif... I came up with this stuff...

On main timeline I put:

// Following Listener contains behaviors associated with mouse wheel
mwListener = new Object();
mwListener.onMouseWheel = function(delta, scrollTarget) {
	if (scrollTarget.behavior.dial) {
		scrollTarget._rotation += delta*4;  // added some multiplier for more responsiveness.
		trace("Turning "+scrollTarget+" by "+delta+" amount to "+scrollTarget._rotation+" rotation.");
	}
	if (scrollTarget.behavior.seq == true) {
		if (delta>0) {
			scrollTarget.nextFrame();
		} else if (delta<0) {
			scrollTarget.prevFrame();
		} else {
			scrollTarget.stop();
		}
		trace("At frame "+scrollTarget._currentframe+" of "+scrollTarget);
	}
};
Mouse.addListener(mwListener);

And then inside anything I wanted to respond, I threw this little bit inside:

var behavior = new Object;
behavior.dial = true;
behavior.seq = false;

This seems to be 180° from the way I thought and tried doing stuff earlier (listener seems to do more commanding than listening from the way it seems to me, which is why I made a kludge trying to use it the first time - trying to build a "broadcaster" that's already part of it. lol), but believe it or not, the newer way works much better. (This just might be useful to the next person coming along to look in the archives.) Now I get a single scroll notch behavior rather than overshoot. :D What's great is that it works with relatively short and sweet toggles put on or inside the things it controls. Still get the +/-3 for delta, so who knows what's going on there. Maybe I should dig out the Intellimouse driver disk instead of relying on XP. (Seems silly since the Intellimouse is by M$, but knowing how they do drivers sometimes...)

Interesting comments on differing ways of doing stuff. Not sure if I'm close to being that involved yet. Sometimes the books try to get into this nitty-gritty way of doing stuff, and that's where I also got lost with their explanations. (And I like my PeachPit and O'Reilly books for the most part.)


View my artworks and crazyness at Barbequed Pixels. Home of the pauljs75 "My Art Post" memorial monument.