Jump to content
Search Community

Mouse Events

emiel test
Moderator Tag

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

Hi,

 

I've just started using GreenSock JS (awesome!!), and I'm having some issues how to use and handle mouse events. Could anyone point me in the right direction?

 

Thanks,

 

Emiel

Link to comment
Share on other sites

Hi,

 

There are probably a zillion ways to address this. As someone who is just starting to learn about js while transferring their greensock actionscript knowledge over to the other side I know what its like to try to merge all this new stuff together.

 

I've found that leveraging the features of jQuery really helps in getting over some of javascript-DOM complexities. For instance, if I have a greensock TimelineLite named tl, and buttons with classes of "restart" and "rewind" I would use those buttons to control the timeline like so:

 

$(".restart").click(function(){
 tl.timeScale(1)
 tl.restart();
 });

$(".rewind").click(function(){
 tl.timeScale(3);
 tl.reverse();
 });

 

you can find an example of this here: http://snorkl.tv/dev/js_demo1/

 

I am by no means an authority on javascript but have found with a little "frustration investment" you can start getting the basic things to work in short amount of time. I urge you read as many beginner js tutorials as possible while learning the greensock stuff. It will really help.

 

this jQuery series is phenomenal: http://net.tutsplus....ery-in-30-days/

  • Like 2
Link to comment
Share on other sites

General rule of thumb, is place your Tween related stuff within the function/methods scope that are assigned to or are invoked from within other methods or event handlers.

 

There is what's known as a 'literal' approach where you declare objects/functions on the fly 'literally with no name reference' and then there is the more refined approach of named or referenced objects where you declare (or nest) the the object within another object's scope.

 

To illustrate, see the three examples below. A mix of these examples is what most developers are resolved to use because of time and complexity, but ideally, the named approach where you can control 'scope' of the objects and their named properties/methods, etc. is a more robust and trouble-free solution. It also ensures more readable and compact events code and logic for objects/elements that might have a lot going on, especially if doing custom drag-n-drop stuff.

 

EXAMPLE LITERAL SCOPE #1:

<canvas id="myCanvas" style="position:absolute; width:400px; height:150px; left:0px; top:0px; background-color:#CCCCCC; cursor:pointer;"></canvas>
<script>
// this is generally considered a "global" scope property
var canvas = document.getElementById("myCanvas");
// set the onclick handler to the canvas element in the "global" scope by way of a 'literal' function object declartion (un-named)
canvas.onclick = function(){
TweenLite.to(canvas, 0.4, {css:{left:'+=20', top:'+=20'}});
}; // each click on the canvas "invokes" animate method
</script>

EXAMPLE OOP #2 (mixed scopes):

<script>
// this is generally considered a "global" scope property
var canvas = document.getElementById("myCanvas");
// this is generally considered a "global" scope class reference to the AnimateClass object
var animateClass = new AnimateClass();
// this is generally considered a "global" scope class (also a method) because it requires instantiation (the new keyword)
function AnimateClass(){
// this property is public once AnimateClass is instantiated
this.tweenCount = 0; // a number property
// this method is public once AnimateClass is instantiated
this.animate = function(){
	// invokes the TweenLite method to() with the pertinent CSS properties to animate
	TweenLite.to(canvas, 0.4, {css:{left:'+=20', top:'+=20'}});
	this.tweenCount++; // increments the tween count to keep track of how many times clicked
};
}
// this is generally considered a "global" scope method that is not instantiated but merely invoked
function animate(event){
// new AnimateClass scope is now instantiated into the animateClass property
animateClass.animate(); // simply invoke the animateClass.animate() method to fire off the tween
}
// set the onclick handler to the canvas element in the "global" scope
canvas.onclick = animate; // each click on the canvas "invokes" animate method
</script>

EXAMPLE OOP #3 (contained scope):

<canvas id="myCanvas" style="position:absolute; width:400px; height:150px; left:0px; top:0px; background-color:#CCCCCC; cursor:pointer;"></canvas>
<script>
// this is generally considered a "global" scope class (also a method) because it requires instantiation (the new keyword)
function AnimateClass(){
// this property is public once AnimateClass is instantiated and holds a reference to the canvas element
this.canvas = document.getElementById("myCanvas");
// this property is public once AnimateClass is instantiated
this.tweenCount = 0; // a number property
// this method is public once AnimateClass is instantiated
this.animate = function(event){
	// invokes the TweenLite method to() with the pertinent CSS properties to animate
	TweenLite.to(animateClass.canvas, 0.4, {css:{left:'+=20', top:'+=20'}});
	this.tweenCount++; // increments the tween count to keep track of how many times clicked
};
}
// this is generally considered a "global" scope class reference to the AnimateClass object
var animateClass = new AnimateClass();
// set the onclick handler to the canvas element in the "animateClass" class object scope
animateClass.canvas.onclick = animateClass.animate; // each click on the canvas "invokes" animateClass.animate method

 

As you can see, the #1 literal approach is a lot less code, which is fine for small and simple integrations. However, as you start getting more complex with the interactivity, you can probably see the advantages of creating objects to hold your tween logic and to have a more reliable location to update in one or two places as opposed to all over the place searching for 'un-named' literal functions (AKA anonymous functions).

 

I personally favor the "composition" approach, where some of the key properties and methods are in the global scope and then I have other objects (like classes and nested properties/methods within those classes) handle the more complex tweening.

  • Like 4
Link to comment
Share on other sites

Randall, That is awesome. I have stumbled blindly into some of those techniques but lacked the ability to technically describe what I was doing. The concise examples with supporting comments are really valuable. Thanks!

  • Like 2
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...