Skip to content

Instantly share code, notes, and snippets.

@tkojitu
Last active August 29, 2015 13:57
Show Gist options
  • Save tkojitu/9637622 to your computer and use it in GitHub Desktop.
Save tkojitu/9637622 to your computer and use it in GitHub Desktop.
var gPad = {
canvasId: null,
x: 0,
y: 0,
oldX: 0,
oldY: 0,
touchX: 0,
touchY: 0,
moving: false,
HALF_SIZE: 50,
getControlPad: function() {
return document.getElementById(this.canvasId);
},
onTouchStart: function(event) {
event.preventDefault();
var touch = event.changedTouches[0];
if (!this.hitsPointer(touch)) {
return;
}
var local = this.clientToLocal(touch);
this.touchX = local.x;
this.touchY = local.y;
this.oldX = this.x;
this.oldY = this.y;
this.moving = true;
},
clientToLocal: function(touch) {
var pad = this.getControlPad();
return {
x: touch.clientX - pad.offsetLeft,
y: touch.clientY - pad.offsetTop
};
},
hitsPointer: function(touch) {
var local = this.clientToLocal(touch);
return this.x - this.HALF_SIZE <= local.x
&& local.x <= this.x + this.HALF_SIZE
&& this.y - this.HALF_SIZE <= local.y
&& local.y <= this.y + this.HALF_SIZE;
},
onTouchMove: function(event) {
event.preventDefault();
if (!this.moving) {
return;
}
var touch = event.changedTouches[0];
var local = this.clientToLocal(touch);
this.x = this.oldX + local.x - this.touchX;
this.y = this.oldY + local.y - this.touchY;
this.limitPointer();
console.log("" + this.x + "," + this.y);
},
limitPointer: function() {
var pad = this.getControlPad();
if (this.x - this.HALF_SIZE < 0) {
this.x = this.HALF_SIZE;
} else if (pad.clientWidth < this.x + this.HALF_SIZE) {
this.x = pad.clientWidth - this.HALF_SIZE;
}
if (this.y - this.HALF_SIZE < 0) {
this.y = this.HALF_SIZE;
} else if (pad.clientHeight < this.y + this.HALF_SIZE) {
this.y = pad.clientHeight - this.HALF_SIZE;
}
},
onTouchEnd: function(event) {
event.preventDefault();
this.moving = false;
},
initControlPad: function(canvasId) {
this.canvasId = canvasId;
this.addEventListeners();
this.initPointer();
},
addEventListeners: function() {
var pad = this.getControlPad();
var that = this;
pad.addEventListener("touchstart",
function(event) {that.onTouchStart(event);},
false);
pad.addEventListener("touchmove",
function(event) {that.onTouchMove(event);},
false);
pad.addEventListener("touchend",
function(event) {that.onTouchEnd(event);},
false);
},
initPointer: function() {
var pad = this.getControlPad();
this.x = pad.clientWidth / 2;
this.y = pad.clientHeight / 2;
},
drawControlPad: function() {
this.clearPad();
this.drawPointer();
},
clearPad: function() {
var pad = this.getControlPad();
var context = pad.getContext("2d");
context.clearRect(0, 0, pad.clientWidth, pad.clientHeight);
},
drawPointer: function() {
var pad = this.getControlPad();
var context = pad.getContext("2d");
context.fillStyle = "#ff0000";
context.fillRect(this.x - this.HALF_SIZE, this.y - this.HALF_SIZE,
this.HALF_SIZE * 2, this.HALF_SIZE * 2);
},
movePointer: function() {
this.movePointerX();
this.movePointerY();
},
movePointerX: function() {
if (this.moving) {
return;
}
var centerX = this.getCenterX();
if (this.x < centerX) {
this.x += 1;
} else if (this.x > centerX) {
this.x -= 1;
}
},
movePointerY: function() {
if (this.moving) {
return;
}
var centerY = this.getCenterY();
if (this.y < centerY) {
this.y += 1;
} else if (this.y > centerY) {
this.y -= 1;
}
},
getCenterX: function() {
var pad = this.getControlPad();
return pad.clientWidth / 2;
},
getCenterY: function() {
var pad = this.getControlPad();
return pad.clientHeight / 2;
},
getAngle: function() {
var centerX = this.getCenterX();
var centerY = this.getCenterY();
return Math.atan2(this.y - centerY, this.x - centerX) * 180.0 / Math.PI;
},
isPointerMoving: function() {
if (this.getCenterX() == this.x && this.getCenterY() == this.y) {
return false;
}
var dist = Math.sqrt(Math.pow(this.x - this.getCenterX(), 2) +
Math.pow(this.y - this.getCenterY(), 2));
return dist > this.HALF_SIZE / 2.0;
},
get8direction: function() {
if (!this.isPointerMoving()) {
return 0;
}
var angle = this.getAngle();
if (0 <= angle && angle < 22.5) {
return 3;
} else if (22.5 <= angle && angle < 67.5) {
return 4;
} else if (67.5 <= angle && angle < 112.5) {
return 5;
} else if (112.5 <= angle && angle < 157.5) {
return 6;
} else if (157.5 <= angle && angle <= 180.0) {
return 7;
} else if (-22.5 <= angle && angle <= 0) {
return 3;
} else if (-67.5 <= angle && angle < -22.5) {
return 2;
} else if (-112.5 <= angle && angle < -67.5) {
return 1;
} else if (-157.5 <= angle && angle < -112.5) {
return 8;
} else if (-180 <= angle && angle < -157.5) {
return 7;
} else {
return 0;
}
},
mainloop: function() {
this.movePointer();
this.drawControlPad();
}
};
<!DOCTYPE html>
<html>
<head>
<title>ControlPadDemo</title>
<style>
</style>
<script src="three.js"></script>
<script src="controlPad.js"></script>
<script src="ControlPadDemo.js"></script>
<style>
body{
margin: 0;
overflow: hidden;
}
#controlPad{
border: 1px solid #000000;
}
</style>
</head>
<body onload="onLoad()">
<div id="output"></div>
<canvas id="controlPad" width=200 height=200></canvas>
</body>
</html>
var gApp = {
camera: null,
cube: null,
renderer: null,
scene: null,
setupOutput: function() {
this.renderer = this.newRenderer();
var output = document.getElementById("output");
output.appendChild(this.renderer.domElement);
this.scene = this.newScene();
this.camera = this.newCamera(this.scene.position);
this.renderer.render(this.scene, this.camera);
},
newRenderer: function() {
var renderer = new THREE.WebGLRenderer();
renderer.setClearColorHex(0xEEEEEE, 1.0);
var size = this.getRendererSize();
renderer.setSize(size.width, size.height);
renderer.shadowMapEnabled = true;
return renderer;
},
getRendererSize: function() {
var size = (window.innerWidth < window.innerHeight) ? window.innerWidth : window.innerHeight;
return {
width: size,
height: size
};
},
newScene: function() {
var scene = new THREE.Scene();
this.cube = this.newCube();
scene.add(this.cube);
var light = this.newLight();
scene.add(light);
return scene;
},
newCube: function() {
var cubeGeometry = new THREE.CubeGeometry(4, 4, 4);
var cubeMaterial = new THREE.MeshLambertMaterial({color: 0xff0000});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.castShadow = true;
cube.position.x = -4;
cube.position.y = 3;
cube.position.z = 0;
return cube;
},
newLight: function() {
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(-40, 60, -10);
spotLight.castShadow = true;
return spotLight;
},
newCamera: function(position) {
var ratio = this.getAspectRatio();
var camera = new THREE.PerspectiveCamera(45, ratio, 0.1, 1000);
camera.position.x = 0;
camera.position.y = 40;
camera.position.z = 0;
camera.lookAt(position);
return camera;
},
getAspectRatio: function() {
var size = this.getRendererSize();
return size.width / size.height;
},
rotateCube: function(event) {
this.cube.rotation.x = event.target.value / 100.0;
this.renderer.render(this.scene, this.camera);
},
mainloop: function() {
this.rotateCube();
this.renderer.render(this.scene, this.camera);
},
rotateCube: function() {
var dir = gPad.get8direction();
switch (dir) {
case 1:
this.cube.rotation.z += 1;
break;
case 3:
this.cube.rotation.x += 1;
break;
case 5:
this.cube.rotation.z -= 1;
break;
case 7:
this.cube.rotation.x -= 1;
break;
default:
break;
}
}
};
function onLoad() {
gApp.setupOutput();
gPad.initControlPad("controlPad");
gPad.drawControlPad();
mainloop();
}
function mainloop() {
gPad.mainloop();
gApp.mainloop();
window.requestAnimationFrame(mainloop);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment