I'm trying to create virtual touch joystick on HTML5 canvas. I found several solutions, one really working, but it was too complicated for me to modify, so I did a lot of work on my own, but it had some issues. It doesn't support two joysticks at a time and also it's terribly slow :( Please show me the way I should go. My html code looks like this:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width; height=device-height; initial-scale=1.0; maximum-scale=1.0;">
<title>Touch controller</title>
<link rel="stylesheet" href="css/virtualjoystick.css">
<script src="js/jquery-1.11.0.min.js"></script>
<script src="js/touch.js"></script>
</head>
<body>
<div class="container" id="video">
<canvas height="977" width="1920" id="canvas"></canvas>
</div>
</body>
</html>
And touch.js is like this:
//touch control JavaScript
$(document).ready(function(){
//setup
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
resetCanvas(c);
//handlers
$("#canvas").mousedown(function(e){
if(side(e.clientX) == "left"){
if(!left.isset){
//alert("left");
left.isset = true;
left.startX = e.clientX;
left.startY = e.clientY;
left.curX = e.clientX;
left.curY = e.clientY;
refreshCanvas(ctx);
}
}
else if(side(e.clientX) == "right"){
if(!right.isset){
//alert("left");
right.isset = true;
right.startX = e.clientX;
right.startY = e.clientY;
right.curX = e.clientX;
right.curY = e.clientY;
refreshCanvas(ctx);
}
}
});
$("#canvas").mousemove(function(e){
if(side(e.clientX) == "left"){
if(left.isset){
left.curX = e.clientX;
left.curY = e.clientY;
refreshCanvas(ctx);
}
}
else if(side(e.clientX) == "right"){
if(right.isset){
right.curX = e.clientX;
right.curY = e.clientY;
refreshCanvas(ctx);
}
}
});
$("#canvas").mouseup(function(e){
if(side(e.clientX) == "left"){
if(left.isset){
//alert("left");
left.isset = false;
left.startX = false;
left.startY = false;
left.curX = false;
left.curY = false;
refreshCanvas(ctx);
}
}
else if(side(e.clientX) == "right"){
if(right.isset){
//alert("left");
right.isset = false;
right.startX = false;
right.startY = false;
right.curX = false;
right.curY = false;
refreshCanvas(ctx);
}
}
});
});
var left = {isset:false};
var right = {isset:false};
function resetCanvas(c){
c.width = $(window).innerWidth();
c.height = $(window).innerHeight();
//c.scrollTo(0,0);
}
function refreshCanvas(ctx){
ctx.clearRect(0,0,1920,1080);
if(left.isset){
drawBase(ctx, left.startX, left.startY);
drawHandle(ctx, left.startX, left.startY, left.curX, left.curY);
}
if(right.isset){
drawBase(ctx, right.startX, right.startY);
drawHandle(ctx, right.startX, right.startY, right.curX, right.curY);
}
}
function drawBase(ctx, x, y){
ctx.beginPath();
ctx.lineWidth = 2;
ctx.arc(x,y,40,0,2*Math.PI);
ctx.stroke();
}
function drawHandle(ctx, startX, startY, curX, curY){
//stop handle when leaving joystick
var x = curX - startX;
var y = curY - startY;
if( ( (x*x) + (y*y) ) >= (1600) ){
var f = y/x;
if(x < 0) var invert = true;
x = 0;
y = 0;
while( ( (x*x) + (y*y) ) <= (1600) ){
y = x*f;
if(invert) x--;
else x++;
}
x += startX;
y += startY;
}
else {
x = curX;
y = curY;
}
ctx.beginPath();
ctx.lineWidth = 4;
ctx.arc(x,y,20,0,2*Math.PI);
ctx.stroke();
}
function side(x){
var c = document.getElementById("canvas");
var dead = c.width/20;
var left = (c.width - dead)/2;
var right = left + dead;
if(x < left) return "left";
else if(x > right) return "right";
else return false;
}
I'm trying to do it as simple as possible, because I need it to be fast. However I wasn't successful yet. Thanks for advices
I am looking at doing the same thing but there is not a lot on the net. I found this example from a 'For Dummies' book... Virtual Joystick for Your HTML5
I know that my response is 6 years too late, but the reason you're having "performance" issues in your game's render loop is because you are attaching the movement of your joysticks to the rate in which the mousemove event is fired. This is slower than the canvas refresh rate.
Instead, you should do the following:
Detect & set when the mouse is down
In your refresh loop, do your mouse move logic based on whether
the mouse is down
Detect & unset when mouse is up
Related
I'm trying to get my inputhandler to work in Javascript.
What
In my Game.update I currently have this code:
this.Update = function() {
if (input.GetMousePressed()) {
console.log(input.GetMousePosition());
}
}
And this is my inputhandler:
function InputHandler(canvas) {
this.canvas = canvas;
this.mousePressed = false;
this.mouseDown = false;
this.mousePosition = new Position(0, 0);
this.GetMousePosition = function() {
return this.mousePosition;
}
this.SetMousePosition = function(event) {
var rect = this.canvas.getBoundingClientRect();
this.mousePosition = new Position(event.clientX - rect.left, event.clientY - rect.top);
}
this.GetMousePressed = function() {
return this.mousePressed;
}
this.canvas.onmousedown = function(event) {
input.mouseDown = true;
input.SetMousePosition(event);
}
this.canvas.onclick = function(event) {
input.mouseClicked = true;
input.SetMousePosition(event);
}
window.onmouseup = function(event) {
if (input.mouseDown == true) {
input.mousePressed = true;
input.mouseDown = false;
}
}
The first problem is that I dont know how to handle mousePressed and set it to false. Now it stays true forever.
I'm quite new to Javascript and I'm thankful for any change that would make this better or cleaner code or if what Im doing is bad practice.
I'm using addEventListener for normal button pressing and maybe I should for this to?
Not sure why you need mousepressed/mouseup and click events. The only difference between successful pressed/up and click is that click target should be the same element.
So I would either use the first option or the last but not both.
Your mousePressed flag is set to true because it gets assigned true value once you press the mouse. You need to reset it back to false at some point.
Usually, you don't even need this flag since you trigger whatever function you need inside mousepressed event. Not sure why you would save the information that this happened, do you use it somewhere else?
Also, yes using addEventListener would be better.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
body {
background-color: black;
}
canvas {
position: absolute;
margin: auto;
left: 0;
right: 0;
border: solid 1px white;
border-radius: 10px;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script type="application/javascript">
var imageWidth = 180;
var imageHeight = 160;
var canvas = null;
var ctx = null;
var mouseDown = false;
var mouseX = 0;
var mouseY = 0;
var bounds = null;
function canvas_onmousedown(e) {
mouseDown = true;
}
function canvas_onmousemove(e) {
if (mouseDown) {
mouseX = e.clientX - bounds.left;
mouseY = e.clientY - bounds.top;
}
}
function canvas_onmouseup(e) {
mouseDown = false;
}
function loop() {
ctx.fillStyle = "gray";
ctx.fillRect(0,0,imageWidth,imageHeight);
if (mouseDown) {
ctx.fillStyle = "yellow";
} else {
ctx.fillStyle = "black";
}
ctx.fillRect(mouseX - 25,mouseY - 25,50,50);
requestAnimationFrame(loop);
}
window.onload = function() {
canvas = document.getElementById("canvas");
canvas.width = imageWidth;
canvas.height = imageHeight;
canvas.onmousedown = canvas_onmousedown;
canvas.onmousemove = canvas_onmousemove;
canvas.onmouseup = canvas_onmouseup;
ctx = canvas.getContext("2d");
bounds = canvas.getBoundingClientRect();
requestAnimationFrame(loop);
}
</script>
</body>
</html>
I'm trying to make a HTML5 game in javascript. Similar to pong, but once the bubble hits the paddle or bottom screen it "bursts" or disappears. I cant seem to get the Bubble to disappear or burst in my code. Could anyone help me?
var canvasColor;
var x,y,radius,color;
var x=50, y=30
var bubbles=[];
var counter;
var lastBubble=0;
var steps=0, burst=0, escaped=0;
var batonMovement = 200;
var moveBatonRight = false;
var moveBatonLeft = false;
function startGame()
{
var r,g,b;
var canvas,color;
//Initialize
canvasColor = '#EAEDDC';
x = 10;
y = 10;
radius = 10;
clearScreen();
counter=0;
while (counter <100)
{
//make bubble appear randomly
x=Math.floor(Math.random()*450)
//Set up a random color
r = Math.floor(Math.random()*256);
g = Math.floor(Math.random()*256);
b = Math.floor(Math.random()*256);
color='rgb('+r+','+g+','+b+')';
bubbles[counter] = new Bubble(x,y,radius,color);
counter+=1;
}
setInterval('drawForever()',50);
}
function Bubble (x,y,radius,color)
{
this.x=x;
this.y=y;
this.radius=radius;
this.color=color;
this.active=false;
}
function drawForever()
{
var canvas, pen;
canvas = document.getElementById('myCanvas');
pen = canvas.getContext('2d');
steps +=1
clearScreen();
if (steps%20==0 && lastBubble < 100){
bubbles[lastBubble].active=true;
lastBubble +=1;
}
drawBaton();
counter=0;
while (counter <100)
{
if (bubbles[counter].active==true){
pen.fillStyle = bubbles[counter].color;
pen.beginPath();
pen.arc(bubbles[counter].x,
bubbles[counter].y,
bubbles[counter].radius,
0,
2*Math.PI);
pen.fill();
bubbles[counter].y+=2;
}
if (y>=240 && y<=270 && x>=batonMovement-10 && x<=batonMovement+60)
{
bubbles[lastBubble]=false;
}
else if (y>=450)
{
bubbles[lastBubble]=false;
}
counter +=1;
}
}
function clearScreen()
{
var canvas, pen;
canvas = document.getElementById('myCanvas');
pen = canvas.getContext('2d');
pen.fillStyle = canvasColor;
pen.fillRect(0,0,450,300);
}
function drawBaton()
{
var canvas, pen;
if (moveBatonLeft == true && batonMovement > 0)
{
batonMovement -= 20;
}
else if (moveBatonRight == true && batonMovement < 400)
{
batonMovement += 20;
}
//draw Baton (rectangle)
canvas = document.getElementById('myCanvas');
pen = canvas.getContext('2d');
pen.fillStyle = '#0000FF';
pen.fillRect(batonMovement,250,50,10);
}
function moveLeft()
{
moveBatonLeft=true;
}
function moveRight()
{
moveBatonRight=true;
}
function stopMove()
{
moveBatonLeft=false;
moveBatonRight=false;
}
Below is the HTML code...
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Bubble Burster</title>
<script type="text/javascript" src="project.js"></script>
</head>
<body onload="startGame();">
<div style="text-align:center;">
<h2>Bubble Burster</h2>
<canvas id="myCanvas" width="450" height="300" style="border:5px solid #000000; background-color: #f1f1f1;">
Your browser does not support the canvas element.
</canvas><br>
<button onmousedown="moveLeft();" onmouseup="stopMove();">LEFT</button>
<button onmousedown="moveRight();" onmouseup="stopMove();">RIGHT</button><br><br>
<form>
<input type="radio" name="difficulty" value="easy" onclick="check(this.value);" checked> Easy
<input type="radio" name="difficulty" value="moderate" onclick="check(this.value)"> Moderate
<input type="radio" name="difficulty" value="hard" onclick="check(this.value)"> Hard <br><br>
</form>
<span id="burst">Burst:</span>
<span id="escaped">Escaped: </span>
<span id="steps">Steps elapsed:</span>
<h3 id="output"></h3>
</div>
</body>
</html>
You are referring to x, y which are not defined in the drawForever function. The global values of x and y may not refer to the right bubble. In fact y is set to 10 in the startGame function and never altered subsequently. You also probably want to refer to bubbles[counter] rather than bubbles[lastBubble]. The game seems to work if you make the changes below, referring to bubbles[counter].x and bubbles[counter].y instead of x and y.
function drawForever() {
var canvas, pen;
canvas = document.getElementById('myCanvas');
pen = canvas.getContext('2d');
steps += 1
clearScreen();
if (steps % 20 == 0 && lastBubble < 100) {
bubbles[lastBubble].active = true;
lastBubble += 1;
}
drawBaton();
counter = 0;
while (counter < 100) {
if (bubbles[counter].active == true) {
pen.fillStyle = bubbles[counter].color;
pen.beginPath();
pen.arc(bubbles[counter].x,
bubbles[counter].y,
bubbles[counter].radius,
0,
2 * Math.PI);
pen.fill();
bubbles[counter].y += 2;
}
y = bubbles[counter].y; // ADDED (y was not defined in original code)
x = bubbles[counter].x; // ADDED (x was not defined in original code)
if (y >= 240 && y <= 270 && x >= batonMovement - 10 && x <= batonMovement + 60) {
bubbles[counter] = false; // ALTERED (burst the current bubble, not whatever lastBubble refers to
} else if (y >= 450) {
bubbles[counter] = false; // ALTERED (burst the current bubble, not whatever lastBubble refers to
}
counter += 1;
}
}
https://jsfiddle.net/acLot87q/4/
You should also make x and y local variables within each function; they are not currently serving the purpose that you seem to think.
Below is a script which defines two functions that draw 4 rectangular buttons and 1 circular button respectively. I am trying to implement specific Hover and Click functionality into the buttons (as described in the script alerts) but I am at a bit of a loss as to how to do this. I tried calling the makeInteractiveButton() functions on each click but this caused a lot of odd overlap and lag. I want the script to do the following:
If the circular button is hovered, I would like it's fillColour to change and if it is clicked I would like it to change again to the colours described in the code (#FFC77E for hover, #FFDDB0 for clicked). This should only happen for the duration of the hover or click.
HTML:
<html lang="en">
<body>
<canvas id="game" width = "750" height = "500"></canvas>
<script type='text/javascript' src='stack.js'></script>
</body>
</html>
JavaScript:
var c=document.getElementById('game'),
canvasX=c.offsetLeft,
canvasY=c.offsetTop,
ctx=c.getContext('2d')
elements = [];
c.style.background = 'grey';
function makeInteractiveButton(x, strokeColor, fillColor) {
ctx.strokeStyle=strokeColor;
ctx.fillStyle=fillColor;
ctx.beginPath();
ctx.lineWidth=6;
ctx.arc(x, 475, 20, 0, 2*Math.PI);
ctx.closePath();
ctx.stroke();
ctx.fill();
elements.push({
arcX: x,
arcY: 475,
arcRadius: 20
});
}
b1 = makeInteractiveButton(235, '#FFFCF8', '#FFB85D');
c.addEventListener('mousemove', function(event) {
x=event.pageX-canvasX; // cursor location
y=event.pageY-canvasY;
elements.forEach(function(element) {
if (x > element.left && x < element.left + element.width &&
y > element.top && y < element.top + element.height) { // if cursor in rect
alert('Rectangle should undergo 5 degree rotation and 105% scale');
}
else if (Math.pow(x-element.arcX, 2) + Math.pow(y-element.arcY, 2) <
Math.pow(element.arcRadius, 2)) { // if cursor in circle
alert('Set b1 fillColour to #FFC77E.');
}
});
}, false);
c.addEventListener('click', function(event) {
x=event.pageX-canvasX; // cursor location
y=event.pageY-canvasY;
elements.forEach(function(element) {
if (x > element.left && x < element.left + element.width &&
y > element.top && y < element.top + element.height) { // if rect clicked
alert('Move all cards to centre simultaneously.');
}
else if (Math.pow(x-element.arcX, 2) + Math.pow(y-element.arcY, 2) <
Math.pow(element.arcRadius, 2)) { // if circle clicked
alert('Set b1 fillColour to #FFDDB0.');
}
});
}, false);
One way is keep all element data and write a hitTest(x,y) function but when you have a lot of complex shapes its better to use a secondary canvas to render element with their ID instead of their color in it and the color of x,y in second canvas is ID of hitted element, I should mention that the second canvas is'nt visible and its just a gelper for get the hitted element.
Github Sample:
https://siamandmaroufi.github.io/CanvasElement/
Simple implementation of hitTest for Rectangles :
var Rectangle = function(id,x,y,width,height,color){
this.id = id;
this.x=x;
this.y=y;
this.width = width;
this.height = height;
this.color = color || '#7cf';
this.selected = false;
}
Rectangle.prototype.draw = function(ctx){
ctx.fillStyle = this.color;
ctx.fillRect(this.x,this.y,this.width,this.height);
if(this.selected){
ctx.strokeStyle='red';
ctx.setLineDash([5,5]);
ctx.lineWidth = 5;
ctx.strokeRect(this.x,this.y,this.width,this.height);
}
}
Rectangle.prototype.hitTest=function(x,y){
return (x >= this.x) && (x <= (this.width+this.x)) &&
(y >= this.y) && (y <= (this.height+this.y));
}
var Paint = function(el) {
this.element = el;
this.shapes = [];
}
Paint.prototype.addShape = function(shape){
this.shapes.push(shape);
}
Paint.prototype.render = function(){
//clear the canvas
this.element.width = this.element.width;
var ctx = this.element.getContext('2d');
for(var i=0;i<this.shapes.length;i++){
this.shapes[i].draw(ctx);
}
}
Paint.prototype.setSelected = function(shape){
for(var i=0;i<this.shapes.length;i++){
this.shapes[i].selected = this.shapes[i]==shape;
}
this.render();
}
Paint.prototype.select = function(x,y){
for(var i=this.shapes.length-1;i>=0;i--){
if(this.shapes[i].hitTest(x,y)){
return this.shapes[i];
}
}
return null;
}
var el = document.getElementById('panel');
var paint = new Paint(el);
var rectA = new Rectangle('A',10,10,150,90,'yellow');
var rectB = new Rectangle('B',150,90,140,100,'green');
var rectC = new Rectangle('C',70,85,200,70,'rgba(0,0,0,.5)');
paint.addShape(rectA);
paint.addShape(rectB);
paint.addShape(rectC);
paint.render();
function panel_mouseUp(evt){
var p = document.getElementById('panel');
var x = evt.x - p.offsetLeft;
var y = evt.y - p.offsetTop;
var shape = paint.select(x,y);
if(shape){
alert(shape.id);
}
//console.log('selected shape :',shape);
}
function panel_mouseMove(evt){
var p = document.getElementById('panel');
var x = evt.x - p.offsetLeft;
var y = evt.y - p.offsetTop;
var shape = paint.select(x,y);
paint.setSelected(shape);
}
el.addEventListener('mouseup',panel_mouseUp);
el.addEventListener('mousemove',panel_mouseMove);
body {background:#e6e6e6;}
#panel {
border:solid thin #ccc;
background:#fff;
margin:0 auto;
display:block;
}
<canvas id="panel" width="400px" height="200px" >
</canvas>
just click or move over the shapes
How can I change this code instead of dragging you just click two elements to exchange the position of the two elements? I wanted to exchange two tiles through clicking one then another but instead, in here you need to drag the first tile to bring it to the other then they will exchange.
function onPuzzleClick(e){
if(e.layerX || e.layerX == 0){
_mouse.x = e.layerX - _canvas.offsetLeft;
_mouse.y = e.layerY - _canvas.offsetTop;
}
else if(e.offsetX || e.offsetX == 0){
_mouse.x = e.offsetX - _canvas.offsetLeft;
_mouse.y = e.offsetY - _canvas.offsetTop;
}
_currentPiece = checkPieceClicked();
if(_currentPiece != null){
_stage.clearRect(_currentPiece.xPos,_currentPiece.yPos,pcWidth,pcHeight);
_stage.save();
_stage.globalAlpha = .9;
_stage.drawImage(_img, _currentPiece.sx, _currentPiece.sy, pcWidth, pcHeight, _mouse.x - (pcWidth / 2), _mouse.y - (pcHeight / 2), pcWidth, pcHeight);
_stage.restore();
document.onmousemove = updatePuzzle;
document.onmouseup = pieceDropped;
}
}
function checkPieceClicked(){
var i;
var piece;
for(i = 0;i < _pieces.length;i++){
piece = _pieces[i];
if(_mouse.x < piece.xPos || _mouse.x > (piece.xPos + pcWidth) || _mouse.y < piece.yPos || _mouse.y > (piece.yPos + pcHeight)){
//PIECE NOT HIT
}
else{
return piece;
}
}
return null;
}
function updatePuzzle(e){
_currentDropPiece = null;
if(e.layerX || e.layerX == 0){
_mouse.x = e.layerX - _canvas.offsetLeft;
_mouse.y = e.layerY - _canvas.offsetTop;
}
else if(e.offsetX || e.offsetX == 0){
_mouse.x = e.offsetX - _canvas.offsetLeft;
_mouse.y = e.offsetY - _canvas.offsetTop;
}
_stage.clearRect(0,0,width,height);
var i;
var piece;
for(i = 0;i < _pieces.length;i++){
piece = _pieces[i];
if(piece == _currentPiece){
continue;
}
_stage.drawImage(_img, piece.sx, piece.sy, pcWidth, pcHeight, piece.xPos, piece.yPos, pcWidth, pcHeight);
_stage.strokeRect(piece.xPos, piece.yPos, pcWidth,pcHeight);
if(_currentDropPiece == null){
if(_mouse.x < piece.xPos || _mouse.x > (piece.xPos + pcWidth) || _mouse.y < piece.yPos || _mouse.y > (piece.yPos + pcHeight)){
//NOT OVER
}
else{
_currentDropPiece = piece;
_stage.save();
_stage.globalAlpha = .4;
_stage.fillStyle = PUZZLE_HOVER_TINT;
_stage.fillRect(_currentDropPiece.xPos,_currentDropPiece.yPos,pcWidth, pcHeight);
_stage.restore();
}
}
}
_stage.save();
_stage.globalAlpha = .6;
_stage.drawImage(_img, _currentPiece.sx, _currentPiece.sy, pcWidth, pcHeight, _mouse.x - (pcWidth / 2), _mouse.y - (pcHeight / 2), pcWidth, pcHeight);
_stage.restore();
_stage.strokeRect( _mouse.x - (pcWidth / 2), _mouse.y - (pcHeight / 2), pcWidth,pcHeight);
}
function pieceDropped(e){
document.onmousemove = null;
document.onmouseup = null;
if(_currentDropPiece != null){
var tmp = {xPos:_currentPiece.xPos,yPos:_currentPiece.yPos};
_currentPiece.xPos = _currentDropPiece.xPos;
_currentPiece.yPos = _currentDropPiece.yPos;
_currentDropPiece.xPos = tmp.xPos;
_currentDropPiece.yPos = tmp.yPos;
Here’s how to swap pieces using mouse clicks instead of drags
In the mouseup handler:
Check if the user hit any piece.
If the user hit a piece and no piece was previously “selected”, then “select” this piece.
If the user hit a piece and there was as previous selection, then swap the 2 pieces and reset the pieces.
If the user clicks outside of all pieces, clear any “selected” piece.
Here is working code for you to look at and a Fiddle: http://jsfiddle.net/m1erickson/a75xz/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var canvasOffset=$("#canvas").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var canvasWidth=canvas.width;
var canvasHeight=canvas.height;
// create "pieces"
var selectedPiece=-1;
var pieceSize=75;
var pieces=[];
pieces.push({x:50,y:30,color:"orange"});
pieces.push({x:150,y:30,color:"green"});
pieces.push({x:250,y:30,color:"blue"});
for(var x=0;x<pieces.length;x++){
drawPiece(x,false);
}
// draw the specified piece
// stroke it in red if it's selected
function drawPiece(pieceId,isStroked){
if(pieceId<0){return;}
var piece=pieces[pieceId];
ctx.save();
ctx.beginPath();
ctx.fillStyle=piece.color;
ctx.rect(piece.x,piece.y,pieceSize,pieceSize);
ctx.fill();
ctx.strokeStyle=(isStroked ? "red" : "black");
ctx.lineWidth=6;
ctx.stroke();
ctx.fillStyle="white";
ctx.font = 'italic 18px Calibri';
ctx.fillText("Box#"+pieceId,piece.x+15,piece.y+25);
ctx.restore();
}
function hitTest(x,y){
var hit=-1;
for(var pieceId=0;pieceId<pieces.length;pieceId++){
piece=pieces[pieceId];
var isHit=!(x<piece.x || x>(piece.x + pieceSize) || y<piece.y || y>(piece.y + pieceSize));
if(isHit){
hit=pieceId;
break; // Hit! We're outta here...
}
}
return(hit); // returns piece# if hit else -1 to indicate no hits
}
function handleMouseUp(e){
canMouseX=parseInt(e.clientX-offsetX);
canMouseY=parseInt(e.clientY-offsetY);
// de-highlight previous selection, if any
drawPiece(selectedPiece,false)
// did we hit a piece?
var hit=hitTest(canMouseX,canMouseY);
// if no-hit, the user clicked outside a box
// so clear the selectedPiece and we're outta here
if(hit<0){
drawPiece(selectedPiece,false)
selectedPiece=-1;
return;
}
// Hit!
// if no previous selection,
// set selectedPiece and highlight selectedPiece
if(selectedPiece<0){
selectedPiece=hit;
drawPiece(selectedPiece,true);
}
// else, there was a piece already selected
// so swap these pieces!
else{
var s=pieces[selectedPiece];
var h=pieces[hit];
var temp={x:s.x, y:s.y};
s.x=h.x;
s.y=h.y;
h.x=temp.x;
h.y=temp.y;
drawPiece(selectedPiece,false);
drawPiece(hit,false);
selectedPiece=-1; // clear
}
} // end handleMouseDown()
$("#canvas").mouseup(function(e){handleMouseUp(e);});
}); // end $(function(){});
</script>
</head>
<body>
<br/><p>Click once to select a box</p>
<p>Click a second box to swap the boxes</p>
<canvas id="canvas" width=400 height=300></canvas>
</body>
</html>
i had a problem on confusing how to put ontouch inside my coding because i want it function on ipad, below is my code
<script language="javascript">
function sig1()
{
if(sig == null)
{
xclear('myCanvas');
}
}
code for clear the line in canvas
<body id="main_body" class="no_guidelines" onload="sig1()" onmouseup="bodyonmouseup">
to let the canvas had fillstyle color and function
<canvas border=1 id="myCanvas" height=200 width=400 onmousedown="onmousedown()" onmouseup="onmouseup()" onmousemove="onmousemove()">Your browser does not support the application</canvas>
canvas that can draw line like signature
var sig = null;
var ele;
function bodyonmouseup(e)
{
var ele;
ele = document.getElementById('myCanvas');
ele.isDown = false;
}
function onmousedown(e)
{
var ele,p;
if (!e) e = window.event;
ele = (e.srcElement);
if (! ele) ele = e.target;
ele.isDown = true;
ele.context = ele.getContext("2d");
ele.context.lineWidth = 1;
ele.context.beginPath();
ele.context.moveTo(e.offsetX,e.offsetY);
sig.line = new Array();
p = new Object();
p.x = e.offsetX;
p.y = e.offsetY;
sig.p = p;
sig.line[sig.line.length] = p;
sig.lines[sig.lines.length] = sig.line;
}
function onmousemove(e)
{
var ele,dx,dy,p;
if (!e) e = window.event;
ele = (e.srcElement);
if (! ele) ele = e.target;
if (! ele.isDown) return;
ele.context.lineTo(e.offsetX,e.offsetY);
ele.context.stroke();
dx = e.offsetX - sig.p.x;
dy = e.offsetY - sig.p.y;
if (dx == 0 && dy == 0) return;
sig.p = new Object();
sig.p.x = e.offsetX;
sig.p.y = e.offsetY;
sig.line[sig.line.length] = sig.p;
}
So i want to know if i want keep both onMouse and ontouch, how i put the ontouch so that the canvas can be draw on ipad?? please help, it is urgent
Use this js. Your finger will be your mouse. They are converting all touch events to mouse events.
jquery-ui-touch-punch