topical media & game development
mobile-query-three-plugins-virtualjoystick-vendor-virtualjoystick.js / js
var VirtualJoystick = function(opts)
{
opts = opts || {};
this._container = opts.container || document.body;
this._stickEl = opts.stickElement || this._buildJoystickStick();
this._baseEl = opts.baseElement || this._buildJoystickBase();
this._range = opts.range || 60;
this._mouseSupport = opts.mouseSupport !== undefined ? opts.mouseSupport : false;
this._container.style.position = "relative";
this._container.appendChild(this._baseEl);
this._baseEl.style.position = "absolute"
this._baseEl.style.display = "none";
this._container.appendChild(this._stickEl);
this._stickEl.style.position = "absolute"
this._stickEl.style.display = "none";
this._pressed = false;
this._baseX = 0;
this._baseY = 0;
this._stickX = 0;
this._stickY = 0;
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
this._onTouchEnd = __bind(this._onTouchEnd , this);
this._onTouchStart , false );
this._container.addEventListener( 'touchend' , this._onTouchMove , false );
if( this._mouseSupport ){
this._onMouseUp = __bind(this._onMouseUp , this);
this._onMouseDown , false );
this._container.addEventListener( 'mouseup' , this._onMouseMove , false );
}
}
VirtualJoystick.prototype.destroy = function()
{
this._container.removeChild(this._baseEl);
this._container.removeChild(this._stickEl);
this._container.removeEventListener( 'touchstart' , this._onTouchEnd , false );
this._container.removeEventListener( 'touchmove' , this._onMouseUp , false );
this._container.removeEventListener( 'mousedown' , this._onMouseMove , false );
}
}
returns: {Boolean} true if touchscreen is currently available, false otherwise
VirtualJoystick.touchScreenAvailable = function()
{
return 'createTouch' in document ? true : false;
}
////////////////////////////////////////////////////////////////////////////
// //
////////////////////////////////////////////////////////////////////////////
VirtualJoystick.prototype.deltaX = function(){ return this._stickX - this._baseX; }
VirtualJoystick.prototype.deltaY = function(){ return this._stickY - this._baseY; }
VirtualJoystick.prototype.up = function(){
if( this._pressed === false ) return false;
var deltaX = this.deltaX();
var deltaY = this.deltaY();
if( deltaY >= 0 ) return false;
if( Math.abs(deltaY) < this._range && Math.abs(deltaY) < Math.abs(deltaX) ){
return false;
}
return true;
}
VirtualJoystick.prototype.down = function(){
if( this._pressed === false ) return false;
var deltaX = this.deltaX();
var deltaY = this.deltaY();
if( deltaY <= 0 ) return false;
if( Math.abs(deltaY) < this._range && Math.abs(deltaY) < Math.abs(deltaX) ){
return false;
}
return true;
}
VirtualJoystick.prototype.right = function(){
if( this._pressed === false ) return false;
var deltaX = this.deltaX();
var deltaY = this.deltaY();
if( deltaX <= 0 ) return false;
if( Math.abs(deltaX) < this._range && Math.abs(deltaY) > Math.abs(deltaX) ){
return false;
}
return true;
}
VirtualJoystick.prototype.left = function(){
if( this._pressed === false ) return false;
var deltaX = this.deltaX();
var deltaY = this.deltaY();
if( deltaX >= 0 ) return false;
if( Math.abs(deltaX) < this._range && Math.abs(deltaY) > Math.abs(deltaX) ){
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////
// //
////////////////////////////////////////////////////////////////////////////
VirtualJoystick.prototype._onUp = function()
{
this._pressed = false;
this._stickEl.style.display = "none";
this._baseEl.style.display = "none";
this._baseX = this._baseY = 0;
this._stickX = this._stickY = 0;
}
VirtualJoystick.prototype._onDown = function(x, y)
{
this._pressed = true;
this._baseX = x;
this._baseY = y;
this._stickX = x;
this._stickY = y;
this._stickEl.style.display = "";
this._stickEl.style.left = (x - this._stickEl.width /2)+"px";
this._stickEl.style.top = (y - this._stickEl.height/2)+"px";
this._baseEl.style.display = "";
this._baseEl.style.left = (x - this._baseEl.width /2)+"px";
this._baseEl.style.top = (y - this._baseEl.height/2)+"px";
}
VirtualJoystick.prototype._onMove = function(x, y)
{
if( this._pressed === true ){
this._stickX = x;
this._stickY = y;
this._stickEl.style.left = (x - this._stickEl.width /2)+"px";
this._stickEl.style.top = (y - this._stickEl.height/2)+"px";
}
}
////////////////////////////////////////////////////////////////////////////
// bind touch events (and mouse events for debug) //
////////////////////////////////////////////////////////////////////////////
VirtualJoystick.prototype._onMouseUp = function(event)
{
return this._onUp();
}
VirtualJoystick.prototype._onMouseDown = function(event)
{
var x = event.clientX;
var y = event.clientY;
return this._onDown(x, y);
}
VirtualJoystick.prototype._onMouseMove = function(event)
{
var x = event.clientX;
var y = event.clientY;
return this._onMove(x, y);
}
VirtualJoystick.prototype._onTouchStart = function(event)
{
if( event.touches.length != 1 ) return;
event.preventDefault();
var x = event.touches[ 0 ].pageX;
var y = event.touches[ 0 ].pageY;
return this._onDown(x, y)
}
VirtualJoystick.prototype._onTouchEnd = function(event)
{
//??????
// no preventDefault to get click event on ios
event.preventDefault();
return this._onUp()
}
VirtualJoystick.prototype._onTouchMove = function(event)
{
if( event.touches.length != 1 ) return;
event.preventDefault();
var x = event.touches[ 0 ].pageX;
var y = event.touches[ 0 ].pageY;
return this._onMove(x, y)
}
////////////////////////////////////////////////////////////////////////////
// build default stickEl and baseEl //
////////////////////////////////////////////////////////////////////////////
VirtualJoystick.prototype._buildJoystickBase = function()
{
var canvas = document.createElement( 'canvas' );
canvas.width = 126;
canvas.height = 126;
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.strokeStyle = "cyan";
ctx.lineWidth = 6;
ctx.arc( canvas.width/2, canvas.width/2, 40, 0, Math.PI*2, true);
ctx.stroke();
ctx.beginPath();
ctx.strokeStyle = "cyan";
ctx.lineWidth = 2;
ctx.arc( canvas.width/2, canvas.width/2, 60, 0, Math.PI*2, true);
ctx.stroke();
return canvas;
}
VirtualJoystick.prototype._buildJoystickStick = function()
{
var canvas = document.createElement( 'canvas' );
canvas.width = 86;
canvas.height = 86;
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.strokeStyle = "cyan";
ctx.lineWidth = 6;
ctx.arc( canvas.width/2, canvas.width/2, 40, 0, Math.PI*2, true);
ctx.stroke();
return canvas;
}
VirtualJoystick.prototype._buildJoystickButton = function()
{
var canvas = document.createElement( 'canvas' );
canvas.width = 86;
canvas.height = 86;
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.strokeStyle = "red";
ctx.lineWidth = 6;
ctx.arc( canvas.width/2, canvas.width/2, 40, 0, Math.PI*2, true);
ctx.stroke();
return canvas;
}
(C) Æliens
04/09/2009
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.