Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
Sign in to follow this  
UbiAssassin

Button that reacts to mouseposition on MouseOver

Recommended Posts

Has anyone ever tried to create a button that transform adjusts to the position of the mousecursor as you mouseOver it? I am looking to create the same basic effect as the Dell Stage app buttons:

 

Button.png

 

I already have a couple of buttons that react to mouseOver in one direction, but they do not adjust in real-time to the exact cursor position as you move over the button in one direction or the other.

 

Here is my code that does the simple transform in one direction:

 

private function buttonReactOver(e:MouseEvent):void
 {
 TweenMax.to(this, .5, {z: -15});
 TweenMax.to(this, .5, {rotationY: -15});
 }
}

 

My initial thought would be to create 8 invisible hitboxes in my button (4 for each side) and (4 for each corner). I could then use eventListeners for each to call functions like the one above. Each would rotate the main visual in the correct direction depending on the hitbox I am inside of at the time. There must be a more efficient way to go about this though?

 

Thanks :)

Link to post
Share on other sites

Greetings from Beautiful Boise, UbiAssassin!

 

I created a circular shape and converted it to a MovieClip, put an Instance on the Stage and named that instance buttonA. The Symbol's Registration Point is in the center.

 

Here's the code I came up with:

 

import com.greensock.TweenLite;
import com.greensock.easing.Quad;
import com.greensock.plugins.TweenPlugin;
import com.greensock.plugins.TransformAroundPointPlugin;
import com.greensock.OverwriteManager;
TweenPlugin.activate([TransformAroundPointPlugin]);
OverwriteManager.init(OverwriteManager.AUTO);
TweenLite.defaultEase = Quad.easeOut;
TweenPlugin.activate([TransformAroundPointPlugin]);
var buttonDistance:Number;
var cursorDistance:Number = 100;
var buttonPoint:Point = new Point(buttonA.x, buttonA.y);
var mousePoint:Point = new Point(mouseX, mouseY);
var homePointButtonA:Point = new Point(stage.stageWidth / 2, stage.stageHeight / 2);
stage.addEventListener(MouseEvent.MOUSE_MOVE, animateButton, false, 0, false);
function animateButton(e:MouseEvent):void {
buttonPoint.x = buttonA.x;
buttonPoint.y = buttonA.y;
mousePoint.x = mouseX;
mousePoint.y = mouseY;
buttonDistance = Point.distance(buttonPoint, mousePoint);
 trace(buttonDistance);
 trace(cursorDistance);
if (buttonDistance <= cursorDistance) {
 TweenLite.to(buttonA, 1, {transformAroundPoint: {point: mousePoint}, x: mouseX, y:mouseY});
}else if (buttonDistance > cursorDistance) {
 TweenLite.to(buttonA, 3, {transformAroundPint: {point: buttonPoint}, x: homePointButtonA.x, y: homePointButtonA.y});
}

 

My rationale is that I would create an Array out of Button Instances and use it to assign the MouseEvent.MOUSE_MOVE Listener.

 

All I've done is tell the buttonA Instance to react to the Cursor when the Cursor gets within a certain distance (I used the flash.geom.Point.distance() Method to do that). That distance is var = cursorDistance.

 

The way it's set up, at 24fps, one can easily "jerk" the Cursor out of range so that the buttonA Instance returns to the Stage center (homePointButtonA). This is purely coincidental-it would behave differently if the frame rate or other parameters were different. The way it's set up now feels about right...and I know that's pretty sloppy...

 

So, if the Cursor gets within a certain distance the buttonA Instance will follow it, and when the Cursor gets a bit out of range, the buttonA Instance goes home.

 

Just me and a concept-I'm not a motion expert by any measure. Good luck with your project!

Link to post
Share on other sites

Thank you very much! I will poke around with this. I really appreciate your time :)

Link to post
Share on other sites

I actually don't have access to the transformAroundCenter code yet, but I am trying something that is showing promise:

 

public function ScreenButtonScript()
{
// This is the base button image.

trace("Load the Base Image");
addChildAt(screenBase, 0);
screenBase.centerRegistration = true;
screenBase.alpha = 1;

// This is the right hitbox on top of the base button image.

hitRight.x = 30;
hitRight.y = -5;
addChildAt(hitRight, 1);
hitRight.alpha = 1;

// This is the topright hitbox on top of the base button image.

hitTopRight.x = 30;
hitTopRight.y = -30;
addChildAt(hitTopRight, 1);
hitTopRight.alpha = 1;

mouseChildren = true;
buttonMode = true;
}

// These are the deformation functions for the two plates I have loaded.

private function deformRight(e:MouseEvent):void
{
trace("Deformations for Right Button");
TweenMax.to(screenBase, .5, {z: -15});
TweenMax.to(screenBase, .5, {rotationY: 15});
TweenMax.to(screenBase, .5, {rotationX: 0});
}
private function deformTopRight(e:MouseEvent):void
{
trace("Deformations for TopRight Button");
TweenMax.to(screenBase, .5, {z: -15});
TweenMax.to(screenBase, .5, {rotationY: 15});
TweenMax.to(screenBase, .5, {rotationX: 15});
}

// Deformation deblur I call later to remove the blur.

private function screenDeBlur():void
{
var currentX = screenBase.x;
var currentY = screenBase.y;
screenBase.transform.matrix3D = null;
screenBase.x = currentX;
screenBase.y = currentY;
}

 

So that is not all the code calling each function, but I have two right side deformations set up (Right and TopRight) using two small movie squares (lvl 1) that I am loading on top of the main button (lvl 0). This seems to work well but I lose the mouse arrow when I am over top of one of the movie instances that calls for the deform, even though I set mouseChildren: true;. Is there something I can do to keep the little hand mousebutton cursor even when I am over the other eventListener movie plates that call the button deforms?

 

 

 

It is also a bit tweaky as the plates that call for the deformations do not seem to always catch the mouseOver events. I assume this is because the main button also has mouseOver EventListeners as well. Maybe they fight for priority from time to time?

 

Thanks.

Link to post
Share on other sites

Well, if the code I threw out there does actually do what you want (I threw it together in a rush...my apologies) you could get by without TransformAroundCenterPlugin by just ensuring that any Shapes you build do have their Registration Point in the Center and just TweenLite'ing them as an Object without the Plugin.

 

Good luck!

Link to post
Share on other sites

Thanks a bunch. It was not actually that yours does not do what I am after. I was just already trying the other option, so I finished my test. I am going to try yours next time I dig into it actually since my attempt is a bit on the tweaky half-functional side. Thanks again and I will tell you how it works out :)

Link to post
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
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×