AS3: MouseIdleMonitor
View Example
View Documentation
Download Class & Example Files
I recently had the need to track if the user has stopped using their mouse (if the mouse was idle) in an application I was building. It actually turned out to be a lot easier than I had imagined with the use of a timer and the built in mouse events in Flash.
This led to the birth of the MouseIdleMonitor which is a simple little utility class that dispatches two events depending on if the mouse is idle or not. For more information, please refer to the documentation.
Here is the class:
-
package com.reintroducing.mouse
-
{
-
import flash.display.Stage;
-
import flash.events.EventDispatcher;
-
import flash.events.MouseEvent;
-
import flash.events.TimerEvent;
-
import flash.utils.Timer;
-
import flash.utils.getQualifiedClassName;
-
-
import com.reintroducing.events.MouseIdleMonitorEvent;
-
-
/**
-
* A small utility class that allows you to see if a user has been inactive with the mouse. The class will dispatch a custom MouseIdleMonitorEvent
-
* with a params object that contains the time the user has been idle, in milliseconds.
-
*
-
* @author Matt Przybylski [http://www.reintroducing.com]
-
* @version 1.0
-
*/
-
public class MouseIdleMonitor extends EventDispatcher
-
{
-
//- PRIVATE & PROTECTED VARIABLES -------------------------------------------------------------------------
-
-
private var _stage:Stage;
-
private var _inactiveTime:int;
-
private var _timer:Timer;
-
private var _idleTime:int;
-
private var _isMouseActive:Boolean;
-
-
//- PUBLIC & INTERNAL VARIABLES ---------------------------------------------------------------------------
-
-
-
-
//- CONSTRUCTOR -------------------------------------------------------------------------------------------
-
-
/**
-
* Creates an instance of hte MouseIdleMonitor class.
-
*
-
* <p>
-
* The class will dispatch two events:
-
* <ul>
-
* <li>MouseIdleMonitorEvent.MOUSE_ACTIVE: Dispatched when the mouse becomes active, repeatedly on MOUSE_MOVE</li>
-
* <li>MouseIdleMonitorEvent.MOUSE_IDLE: Dispatched when the mouse becomes inactive, params object holds idle time ("time")</li>
-
* </ul>
-
* </p>
-
*
-
* @param $stage The stage object to use for the mouse tracking
-
* @param $inactiveTime The time, in milliseconds, to check if the user is active or not (default: 1000)
-
*
-
* @return void
-
*/
-
public function MouseIdleMonitor($stage:Stage, $inactiveTime:int = 1000):void
-
{
-
super();
-
-
this._stage = $stage;
-
this._inactiveTime = $inactiveTime;
-
this._timer = new Timer(this._inactiveTime);
-
}
-
-
//- PRIVATE & PROTECTED METHODS ---------------------------------------------------------------------------
-
-
-
-
//- PUBLIC & INTERNAL METHODS -----------------------------------------------------------------------------
-
-
/**
-
* Starts the MouseIdleMonitor and allows it to check for mouse inactivity.
-
*
-
* @return void
-
*/
-
public function start():void
-
{
-
this._stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
-
this._timer.addEventListener(TimerEvent.TIMER, onTimer);
-
-
this._timer.start();
-
}
-
-
/**
-
* Stops the MouseIdleMonitor from checking for mouse inactivity.
-
*
-
* @return void
-
*/
-
public function stop():void
-
{
-
this._idleTime = 0;
-
this._timer.reset();
-
-
this._stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
-
this._timer.removeEventListener(TimerEvent.TIMER, onTimer);
-
}
-
-
//- EVENT HANDLERS ----------------------------------------------------------------------------------------
-
-
/**
-
* Reset the timer if the mouse moves, user is active.
-
*/
-
private function onMouseMove($evt:MouseEvent):void
-
{
-
this._isMouseActive = true;
-
this._idleTime = 0;
-
this._timer.reset();
-
this._timer.start();
-
-
this.dispatchEvent(new MouseIdleMonitorEvent(MouseIdleMonitorEvent.MOUSE_ACTIVE, {}));
-
}
-
-
/**
-
* Runs if the user is inactive, sets the idle time.
-
*/
-
private function onTimer($evt:TimerEvent):void
-
{
-
this._isMouseActive = false;
-
this._idleTime += this._inactiveTime;
-
-
this.dispatchEvent(new MouseIdleMonitorEvent(MouseIdleMonitorEvent.MOUSE_IDLE, {time: this._idleTime}));
-
}
-
-
//- GETTERS & SETTERS -------------------------------------------------------------------------------------
-
-
/**
-
* Returns a boolean value that specifies if the mouse is active or not.
-
*
-
* @return Boolean
-
*/
-
public function get isMouseActive():Boolean
-
{
-
return this._isMouseActive;
-
}
-
-
/**
-
* Returns an integer representing the amount of time the user's mouse has been inactive, in milliseconds
-
*
-
* @return int
-
*/
-
public function get idleTime():int
-
{
-
return this._idleTime;
-
}
-
-
//- HELPERS -----------------------------------------------------------------------------------------------
-
-
override public function toString():String
-
{
-
return getQualifiedClassName(this);
-
}
-
-
//- END CLASS ---------------------------------------------------------------------------------------------
-
}
-
}
If you found this post useful, please consider leaving a comment, subscribing to the feed, or making a small donation.
20 Comments
Nice work and interesting approach Matt!
I've written similar util some time ago, the only difference is that it fires the idle event after specified "idle" time. You can pause the timer i.e. when you hover over an element. It also uses singleton model so different classes can gain start/stop control over it.
Tomek
Tomek,
Sounds pretty good, I think i contemplated on using a Singleton but decided not to although I can't remember now why
Wow nice code.. you happen to have something like this that works in AS2?
I have a situation where I need to check if the site is idle, not necessarily the mouse, to let the background change colors. Although it would be a good substitute. Thanks for any help.
Here you go, that the old AS2 version of my class:
-
/*--------------------------------------------------------------------------
-
[AS2] MouseMoveTimeout
-
========================================================================
-
var mouseMoveTimeout:MouseMoveTimeout = new MouseMoveTimeout(this, 5, action);
-
//after 5 seconds of not moving the mouse action() method is called
-
--------------------------------------------------------------------------*/
-
-
import mx.utils.utils.Delegate;
-
-
class net.blog2t.util.MouseMoveTimeout extends MovieClip
-
{
-
var MOUSE_MOVE_CHECK_INTERVAL:Number = 1;
-
-
var mouseCountdownTime:Number;
-
var tickerInterval:Number;
-
var _timeout:Number;
-
var _callback:Function;
-
var _this:MovieClip;
-
-
/*
-
* Constructor
-
*/
-
public function MouseMoveTimeout(targetObject:MovieClip, timeout:Number, callback:Function)
-
{
-
_timeout = timeout;
-
_callback = callback;
-
_this = targetObject;
-
-
debug(_this + ": Mouse move timeout set to: " + _timeout + "s. Use start() method to start ticking.");
-
}
-
-
/*
-
* Starts ticking
-
*/
-
public function start():Void
-
{
-
debug("Mouse move timeout started.");
-
-
setMoveTimeout(MOUSE_MOVE_CHECK_INTERVAL);
-
_this.onMouseMove = Delegate.create(this, reset);
-
}
-
-
/*
-
* Reset countdown time when user moves mouse
-
*/
-
public function reset():Void
-
{
-
debug("Reset timeout to: " + _timeout);
-
mouseCountdownTime = _timeout;
-
}
-
-
/*
-
* Stops the ticker and removes on mouse move event
-
*/
-
public function remove():Void
-
{
-
clearInterval(tickerInterval);
-
delete _this.onMouseMove;
-
debug("Mouse move interval stopped and removed");
-
}
-
-
/*------------------------------------------------------------------------------------------------------------------
-
* PRIVATE METHODS
-
*/
-
-
/*
-
* Set interval (to every second) to count mouse inactivity time
-
*/
-
private function setMoveTimeout(mouseTimeout:Number):Void
-
{
-
debug("Start mouse move interval count down every: " + mouseTimeout + "[s]");
-
-
reset();
-
tickerInterval = setInterval(Delegate.create(this, decreaseTimeout), mouseTimeout * 1000);
-
}
-
-
/*
-
* Decrease the time and call state changing method when counter has expired
-
*/
-
private function decreaseTimeout():Void
-
{
-
mouseCountdownTime --;
-
-
debug("Mouse timeout in: " + mouseCountdownTime);
-
-
if (mouseCountdownTime == 0)
-
{
-
_callback.call(_this, this);
-
reset();
-
}
-
}
-
-
/*
-
* Easy way to disable debugging
-
*/
-
private function debug(msg:String):Void
-
{
-
trace("[MMT] " + msg);
-
}
-
}
Og2t,
I just edited your comment to wrap it around AS tags but the vertical scroller got cut off so to see the rest you'll just have to highlight the code and scroll down. Sorry.
Hey thanks for the speeeeedy response... wow!
This is a great class. I actually found one too, but its not a class and a little more compact...
Cheers!
-
//-----------------------------------------
-
//Check For Mouse Idle
-
//-----------------------------------------
-
-
function idleS( ) {
-
-
// See if there has been any mouse movement in the last two seconds
-
-
if ((_root._xmouse + _root._ymouse) != mousePos) {
-
-
// If there has, restart the check for the idle timer
-
-
//trace("resetting");
-
-
gotoAndStop("noAttract");
-
-
clearInterval(idle);
-
-
idle = setInterval(idleTime, 28000);
-
-
//} else {
-
-
//trace("no movement this period");
-
-
}
-
-
// Store an integer representing the mouse position
-
-
mousePos = _root._xmouse + _root._ymouse;
-
-
}
-
-
function startIdle( ) {
-
-
mousePos = -100000; // Initialize it to a dummy value
-
-
idleSample = setInterval(idleS, 2000);
-
-
}
-
-
startIdle( );
-
-
stop( );
-
-
//--------------------------------------
I will save yours for when I am using a class structure.
BTW, what name did you use to save the as file?
Thanks again,
Karlos
Design Drumm
Yeah, you can leave it out (just use MouseMoveTimeout) and save the file into you FLA directory as MouseMoveTimeout.as
Then type in the first frame on the timeline:
var mouseMoveTimeout = new MouseMoveTimeout(this, 5, action);
function action() {
trace("hello");
}
That function will be invoked every 5 seconds providing you're not moving your mouse.
Sweet deal..
What is your name so I can put your credits in my file?
Is that ok to ask? Sorry, forum newbie.
THX
DD
If you want, email it to me.
I like to give people credit for their intellectuals.
![]()
Thanks,
Design Drumm
Correction to code I posted above:
-
//-----------------------------------------
-
//Check For Mouse Idle
-
//-----------------------------------------
-
-
function idleTime( ) {
-
-
// Play the attract animation
-
-
//trace("playing the animation")
-
-
gotoAndStop("attract");
-
-
}
-
-
function idleS( ) {
-
-
// See if there has been any mouse movement in the last two seconds
-
-
if ((_root._xmouse + _root._ymouse) != mousePos) {
-
-
// If there has, restart the check for the idle timer
-
-
//trace("resetting");
-
-
gotoAndStop("noAttract");
-
-
clearInterval(idle);
-
-
idle = setInterval(idleTime, 28000);
-
-
//} else {
-
-
//trace("no movement this period");
-
-
}
-
-
// Store an integer representing the mouse position
-
-
mousePos = _root._xmouse + _root._ymouse;
-
-
}
-
-
function startIdle( ) {
-
-
mousePos = -100000; // Initialize it to a dummy value
-
-
idleSample = setInterval(idleS, 2000);
-
-
}
-
-
startIdle( );
-
-
stop( );
-
-
//--------------------------------------
Source: (did not show an authors name so here is the source)
Genius,
Your a scholar and a gentleman! I'm going to tweak it into a screensaver for a flash program i'm doing!
Once again cheers!!
Thanks Matt Przybylski for this great class.
I have used it and had a necessary to make the apps active on mouse click also apart from just mouse move.
Hence I added this line in onTimer method:
this._stage.addEventListener( MouseEvent.MOUSE_DOWN, onMouseMove, false, 0, true );
and cleared it in onMouseMove method:
this._stage.removeEventListener( MouseEvent.MOUSE_DOWN, onMouseMove );
Just FYI that I edited it.
Best
DD
@Deepanjan: That is a good addition although it should not be added in onTimer because you just want it to be added once not added every time. I added it into the class but its part of the start method along with MOUSE_UP as well and then remove the listeners in the stop method. Thanks.













Great job!
(y)