How to move an image around with arrow keys javascript - javascript

I recently began developing a little javascript game, just for fun. The idea was that you controlled a little dot with the arrow keys (or awsd or i don't care what) within a box on the screen. Little rectangles would then randomly spawn on all edges of the box and progress across it. you have to avoid contact with them. The project turned out to be harder than I expected and I couldn't get the movement to work right. If you could help me with that that would be great. also, feel free to take the concept and what little I have done so far and do whatever you want with it. I would be interested to see your results. Below is the code I used for the spawns without any of the movement scripts. I was using the basic idea of this code to do the movement:
var x = 5; //Starting Location - left
var y = 5; //Starting Location - top
var dest_x = 300; //Ending Location - left
var dest_y = 300; //Ending Location - top
var interval = 2; //Move 2px every initialization
function moveImage() {
//Keep on moving the image till the target is achieved
if(x<dest_x) x = x + interval;
if(y<dest_y) y = y + interval;
//Move the image to the new location
document.getElementById("ufo").style.top = y+'px';
document.getElementById("ufo").style.left = x+'px';
if ((x+interval < dest_x) && (y+interval < dest_y)) {
//Keep on calling this function every 100 microsecond
// till the target location is reached
window.setTimeout('moveImage()',100);
}
}
main body:
<html>
<head>
<style type="text/css">
html::-moz-selection{
background-color:Transparent;
}
html::selection {
background-color:Transparent;
}
img.n {position:absolute; top:0px; width:5px; height:10px;}
img.e {position:absolute; right:0px; width:10px; height:5px;}
img.s {position:absolute; bottom:0px; width:5px; height:10px;}
img.w {position:absolute; left:0px; width:10px; height:5px;}
#canvas {
width:300px;
height:300px;
background-color:black;
position:relative;
}
</style>
<script type="text/javascript">
nmecount=0
function play(){
spawn()
var t=setTimeout("play()",1000);
}
function spawn(){
var random=Math.floor(Math.random()*290)
var side=Math.floor(Math.random()*5)
var name=1
var z=10000
if (side=1)
{
var nme = document.createElement('img');
nme.setAttribute('src', '1.png');
nme.setAttribute('class', 'n');
nme.setAttribute('id', name);
nme.setAttribute('style', 'left:'+random+'px;');
nme.onload = moveS;
document.getElementById("canvas").appendChild(nme);
}
if (side=2)
{
var nme = document.createElement('img');
nme.setAttribute('src', '1.png');
nme.setAttribute('class', 'e');
nme.setAttribute('id', name);
nme.setAttribute('style', 'top:'+random+'px;');
nme.onload = moveW;
document.getElementById("canvas").appendChild(nme);
}
if (side=3)
{
var nme = document.createElement('img');
nme.setAttribute('src', '1.png');
nme.setAttribute('class', 's');
nme.setAttribute('id', name);
nme.setAttribute('style', 'left:'+random+'px;');
nme.onload = moveN;
document.getElementById("canvas").appendChild(nme);
}
if (side=4)
{
var nme = document.createElement('img');
nme.setAttribute('src', '1.png');
nme.setAttribute('class', 'w');
nme.setAttribute('id', name);
nme.setAttribute('style', 'top:'+random+'px;');
nme.onload = moveE;
document.getElementById("canvas").appendChild(nme);
}
name=name+1
}
</script>
</head>
<body onLoad="play()">
<div id="canvas">
<img id="a" src="1.png" style="position:absolute; z-index:5; left:150px; top:150px; height:10px; width=10px;" />
<button onclick="moveleft()"><</button>
</body>
</html>

I can't figure out what your game is about, and so don't know what to do with that code. However, since you mentioned you were having trouble with movement, I wrote a quick JavaScript movement engine just for you, complete with acceleration and deceleration. Use the arrow keys to move. The following code represents a complete HTML document, so copy and paste it into a blank text file and save as .html. And make sure you have a 10x10 image called '1.png' in the same folder as the file.
<html>
<head>
<script type='text/javascript'>
// movement vars
var xpos = 100;
var ypos = 100;
var xspeed = 1;
var yspeed = 0;
var maxSpeed = 5;
// boundary
var minx = 0;
var miny = 0;
var maxx = 490; // 10 pixels for character's width
var maxy = 490; // 10 pixels for character's width
// controller vars
var upPressed = 0;
var downPressed = 0;
var leftPressed = 0;
var rightPressed = 0;
function slowDownX()
{
if (xspeed > 0)
xspeed = xspeed - 1;
if (xspeed < 0)
xspeed = xspeed + 1;
}
function slowDownY()
{
if (yspeed > 0)
yspeed = yspeed - 1;
if (yspeed < 0)
yspeed = yspeed + 1;
}
function gameLoop()
{
// change position based on speed
xpos = Math.min(Math.max(xpos + xspeed,minx),maxx);
ypos = Math.min(Math.max(ypos + yspeed,miny),maxy);
// or, without boundaries:
// xpos = xpos + xspeed;
// ypos = ypos + yspeed;
// change actual position
document.getElementById('character').style.left = xpos;
document.getElementById('character').style.top = ypos;
// change speed based on keyboard events
if (upPressed == 1)
yspeed = Math.max(yspeed - 1,-1*maxSpeed);
if (downPressed == 1)
yspeed = Math.min(yspeed + 1,1*maxSpeed)
if (rightPressed == 1)
xspeed = Math.min(xspeed + 1,1*maxSpeed);
if (leftPressed == 1)
xspeed = Math.max(xspeed - 1,-1*maxSpeed);
// deceleration
if (upPressed == 0 && downPressed == 0)
slowDownY();
if (leftPressed == 0 && rightPressed == 0)
slowDownX();
// loop
setTimeout("gameLoop()",10);
}
function keyDown(e)
{
var code = e.keyCode ? e.keyCode : e.which;
if (code == 38)
upPressed = 1;
if (code == 40)
downPressed = 1;
if (code == 37)
leftPressed = 1;
if (code == 39)
rightPressed = 1;
}
function keyUp(e)
{
var code = e.keyCode ? e.keyCode : e.which;
if (code == 38)
upPressed = 0;
if (code == 40)
downPressed = 0;
if (code == 37)
leftPressed = 0;
if (code == 39)
rightPressed = 0;
}
</script>
</head>
<body onload="gameLoop()" onkeydown="keyDown(event)" onkeyup="keyUp(event)" bgcolor='gray'>
<!-- The Level -->
<div style='width:500;height:500;position:absolute;left:0;top:0;background:black;'>
</div>
<!-- The Character -->
<img id='character' src='1.png' style='position:absolute;left:100;top:100;height:10;width:10;'/>
</body>
</html>
It works as follows: There is a game loop that gets called as soon as the body loads. This game loop calls itself every 10 millis for smooth animation. While it might not actually loop every 10 millis because of run-time speeds, such a low value will ensure that the frame rate is as smooth as can be for any browser.
Within the game loop we manipulate the x and y position of the object based on its current speed. Simple: add x speed to x position, and y speed to y position. Then, we change the actual position of the element based on the current x and y coordinates.
To manipulate the x and y speeds, we take keyboard input using event handlers. Based on the key code, we set a variable which tells the game if a key is down or up. Based on whether the key is down or up, we accelerate or decelerate the object up to the maximum speed. For more gradual speed-ups and slow-downs, floating point values can be used.
You should be able to get the gist of this simple engine by examining the code. Hopefully this will help you in implementing your own movement engine for the game.

Related

How do I check for a collision in a Snake game, without triggering on the head block

I am making a snake game. It is supposed to end when I go over a block I have already been to.
The issue is that it trips the collision check on every space so you lose from the start.
What do I need to do to solve this issue?
var SNAKE_DIM = 10;
var SNAKE_COLOR = Color.green;
var SNAKE_WIDTH=40;
var SNAKE_HEIGHT=40;
var x = getWidth()/2;
var y = getHeight()/2;
var i;
//Direction that the snake moves
var EAST = 0;
var SOUTH = 1;
var WEST = 2;
var NORTH = 3;
var snake;
var rect;
var currentDirection= EAST;
function start(){
var body = new Rectangle(10,10);
body.setPosition(x,y);
body.setColor(Color.GREEN);
add(body);
setTimer(draw,50);
keyDownMethod(keyDown);
}
function elemCheck(x,y)
{
var elem = getElementAt(x,y);
if(elem != null)
{
var lose = new Text("YOU LOSE", "30pt Arial");
lose.setPosition(100,200);
add(lose);
}
}
function draw(i){
if(currentDirection ==EAST){
x = x + 5;
y = y + 0;
}
if(currentDirection ==SOUTH){
x = x + 0;
y = y + 5;
}
if(currentDirection ==WEST){
x = x + -5;
y = y + 0;
}
if(currentDirection ==NORTH){
x = x + 0;
y = y + -5;
}
elemCheck(x,y);
var addBody = new Rectangle(10,10);
addBody.setPosition(x,y);
addBody.setColor(Color.GREEN);
add(addBody);
}
function keyDown(e){
if(e.keyCode == Keyboard.LEFT){
currentDirection=WEST;
}
if(e.keyCode == Keyboard.RIGHT){
currentDirection=EAST;
}
if(e.keyCode == Keyboard.UP){
currentDirection=NORTH;
}
if(e.keyCode == Keyboard.DOWN){
currentDirection=SOUTH;
}
}
I do not have the code to actually stop the snake in yet, I removed it while I am error checking.
But from block one it says "You Lose".
Thanks!
Make sure your X and Y is set to the center of the moving square, else it will detect the square you just spawned and end the game.

Javascript: Moving an Object with Arrow Keys

Im making a simple Tetris game. So far I have a Tetris piece that rotates when the space bar is clicked.
The next step for me is to move the objects left and right using the arrow keys. From looking at other Stack Questions I found that this was possible by changing the margins.
var angle = 0;
var obj = document.getElementById('image')
document.onkeydown = checkKey;
function checkKey(e) {
e = e || window.event;
if (e.keyCode == '32') {
rotate();
}
else if (e.keyCode == '37') {
moveLeft();
}
else if (e.keyCode == '39') {
moveRight();
}
}
function rotate() {
angle = angle + 90;
console.log(angle)
obj.className = "image" + angle;
console.log(obj.className)
if (angle == 360) {
angle = 0;
}
}
function moveLeft() {
obj.style.left = parseInt(obj.style.left) - 5 + 'px';
}
function moveRight() {
obj.style.left = parseInt(obj.style.left) + 5 + 'px';
}
For some reason this isn't working for me.
I've also re-created my code in a JSFiddle using a banana instead of a Tetris piece.
The problem is not with your Javascript, but with your styles. You need to absolutely position your image (banana in this case), and set an initial "left" value. The position: absolute; can be set either in the HTML or CSS, but the left: 0; must be set in the HTML style attribute. Here is an updated jsfiddle with the changes.

how do i make a image follow another in javascript for my game

Hey can someone show me how i can make a picture of a zombie move towards a player image.
so a zombie image would move towards zs.png at a certain speed and maybe could add health so when the zombie touches the player the player looses health
This game is for the 3ds browser so it has to be javascript and html
Also here is a link to the page im running it on Link
And could someone give me the full code because im new to javascript. Thanks
this is what i have so far.
<html>
<head>
<script type='text/javascript'>
// movement vars
var xpos = 100;
var ypos = 100;
var xspeed = 1;
var yspeed = 0;
var maxSpeed = 5;
// boundary
var minx = 0;
var miny = 0;
var maxx = 300;
var maxy = 190;
// controller vars
var upPressed = 0;
var downPressed = 0;
var leftPressed = 0;
var rightPressed = 0;
function slowDownX()
{
if (xspeed > 0)
xspeed = xspeed - 0.5;
if (xspeed < 0)
xspeed = xspeed + 0.5;
}
function slowDownY()
{
if (yspeed > 0)
yspeed = yspeed - 0.5;
if (yspeed < 0)
yspeed = yspeed + 0.5;
}
function gameLoop()
{
// change position based on speed
xpos = Math.min(Math.max(xpos + xspeed,minx),maxx);
ypos = Math.min(Math.max(ypos + yspeed,miny),maxy);
// or, without boundaries:
// xpos = xpos + xspeed;
// ypos = ypos + yspeed;
// change actual position
document.getElementById('character').style.left = xpos;
document.getElementById('character').style.top = ypos;
// change speed based on keyboard events
if (upPressed == 1)
yspeed = Math.max(yspeed - 0.1,-0.1*maxSpeed);
if (downPressed == 1)
yspeed = Math.min(yspeed + 0.1,0.1*maxSpeed)
if (rightPressed == 1)
xspeed = Math.min(xspeed + 0.1,0.1*maxSpeed);
if (leftPressed == 1)
xspeed = Math.max(xspeed - 0.1,-0.1*maxSpeed);
// deceleration
if (upPressed == 0 && downPressed == 0)
slowDownY();
if (leftPressed == 0 && rightPressed == 0)
slowDownX();
// loop
setTimeout("gameLoop()",10);
}
function keyDown(e)
{
var code = e.keyCode ? e.keyCode : e.which;
if (code == 38)
upPressed = 1;
if (code == 40)
downPressed = 1;
if (code == 37)
leftPressed = 1;
if (code == 39)
rightPressed = 1;
}
function keyUp(e)
{
var code = e.keyCode ? e.keyCode : e.which;
if (code == 38)
upPressed = 0;
if (code == 40)
downPressed = 0;
if (code == 37)
leftPressed = 0;
if (code == 39)
rightPressed = 0;
}
</script>
</head>
<body onload="gameLoop()" onkeydown="keyDown(event)" onkeyup="keyUp(event)" bgcolor='red'>
<!-- The Level -->
<div style='width:320;height:220;position:absolute;left:0;top:0;background:green;'>
</div>
<!-- The Character -->
<img id='character' src='zs.gif' style='position:absolute;left:100;top:100;height:30;width:20;'/>
</body>
</html>
Edit: Updated a few blocks of code to make them actually work(!), added note about where to put scripts and included a jsFiddle
jsFiddle Link
Edit 2: Don't just put left:100;top:100;height:30;width:20; as it isn't valid CSS and many browsers will choke on it. Add px after each number to get left:100px;top:100px;height:30px;width:20px; instead.
A little research goes a long way.
How to detect if two divs touch with jquery?
Binding arrow keys in JS/jQuery
jquery animate .css
You almost definitely want to be using jQuery for what you're doing.
Try something like the following:
$(document).ready(function(){
$(document).keydown(function(e){
var c = $("#character");
if (e.keyCode === 37) {
// left arrow pressed
c.css("left","-=10px"); // subtract 10px from the character's CSS 'left' property, although you probably want some system to add a limit to this value
}else if(e.keyCode === 38) {
// up arrow pressed
c.css("top","-=10px"); // subtract 10px from the character's CSS 'up' property
}else if(e.keyCode === 39) {
// right arrow pressed
c.css("left","+=10px"); // add 10px to the character's CSS 'left' property
}else if(e.keyCode === 40) {
// down arrow pressed
c.css("top","+=10px"); // add 10px to the character's CSS 'top' property
}
return false;
});
});
This allows the character to move by using the arrow keys.
Making the zombie image move is a little more difficult. First, add the following div tag to your document:
<div id="zombie" style="position:absolute;top:10px;left:10px;"><img src="YOUR_ZOMBIE_IMAGE.gif" /></div>
Then, add the following JavaScript above the $(document).ready(function(){ line:
var zombieFrequency = 1000; // how long (in milliseconds) it should take the zombie to move to the character's position
var easeType = "swing"; // change this to "linear" for a different kind of zombie animation
Finally, add the following into the $(document).ready(function(){ block:
setInterval(function(){
var c = $("#character");
$("#zombie").animate({"left":c.css("left"),"top":c.css("top")},zombieFrequency,easeType);
},zombieFrequency);
This should make the zombie move to the character's position every 0.6 seconds (600ms = 0.6s), although I haven't tested it myself.
Alternatively, you could consider using CSS transitions, although I doubt they'd run smoothly (or even be supported) on a Nintendo 3DS.
Pay special attention to this!
Also, you cannot put links to scripts and internal scripts in the same <script> tag, like this:
<script src="//ajax.googleapis.com/libs/jquery/1.10.2/jquery.min.js">
// some more scripting
</script>
They must be separate, like this:
<script src="//ajax.googleapis.com/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
// some more scripting
</script>
On a separate note, it's recommended to decide on using either single quotes ' or double quotes ", according to the W3 spec. Most people use double quotes.
Single vs Double quotes (' vs ")

displaying sprites after Collision detection

So when I shoot the enemies they get wiped from the screen, this works.
However what I want to happen is I want to place an explosion (4 pngs one after another)
basically where the enemy was. The code for the explosion works on its own but im stuck trying to integrate it with my code.
Here is the explosion class, as you can see I am having some trouble with the interval as I have no experience with them. I think the error or wrong logic lies in this object.
Also for some reason it wipes the other canvas layers :/
Try it here: http://www.taffatech.com/DarkOrbit.html
function Explosion()
{
this.srcX = 0;
this.srcY = 1250;
this.drawX = 0;
this.drawY = 0;
this.width = 70;
this.height = 70;
this.currentFrame =0;
this.totalFrames =5;
this.hasHit = false;
}
Explosion.prototype.draw = function() //makes it last 10 frames using total frames
{
if(this.currentFrame <= this.totalFrames)
{
this.currentFrame++;
Exploder(this.drawX,this.drawY);
}
else
{
this.hasHit = false;
currentFrame =0;
}
}
function Exploder(srcX,srcY)
{
whereX = this.srcX;
whereY = this.srcY;
intervalT = setInterval(BulletExplosionAnimate, 80);
}
var bulletExplosionStart = 0;
var whereX =0;
var whereY =0;
function BulletExplosionAnimate(intervalT)
{
var wide = 70;
var high = 70;
if (bulletExplosionStart > 308)
{
bulletExplosionStart = 0;
clearInterval(intervalT);
}
else
{
ctxExplosion.clearRect(0,0,canvasWidth,canvasHeight)
ctxExplosion.drawImage(spriteImage,bulletExplosionStart,1250,wide,high,whereX,whereY,wide,high);
bulletExplosionStart += 77;
}
}
my Bullet object:
function Bullet() //space weapon uses this
{
this.srcX = 0;
this.srcY = 1240;
this.drawX = -20;
this.drawY = 0;
this.width = 11;
this.height = 4;
this.bulletSpeed = 10;
this.bulletReset = -20;
this.explosion = new Explosion();
}
Bullet.prototype.draw = function()
{
this.drawX += this.bulletSpeed;
ctxPlayer.drawImage(spriteImage,this.srcX,this.srcY,this.width,this.height,this.drawX,this.drawY,this.width,this.height);
this.checkHitEnemy();
if (this.drawX > canvasWidth)
{
this.recycle();
}
}
Bullet.prototype.fire = function(startX, startY)
{
this.drawX = startX;
this.drawY = startY;
}
Bullet.prototype.checkHitEnemy = function()
{
for(var i = 0; i < enemies.length; i++)
{
if( this.drawX >= enemies[i].drawX && this.drawX <= enemies[i].drawX + enemies[i].enemyWidth && this.drawY >= enemies[i].drawY && this.drawY <= enemies[i].drawY + enemies[i].enemyHeight)
{
this.explosion.drawX = enemies[i].drawX - (this.explosion.width/2);
this.explosion.drawY = enemies[i].drawY;
this.explosion.hasHit = true;
this.recycle(); //bullet resets after hit enemy
enemies[i].recycleEnemy(); //change this soon to have if loop if health is down
}
}
}
Bullet.prototype.recycle = function()
{
this.drawX = this.bulletReset;
}
In my player object I have a function that checks if it has hit an enemy, it works:
Player.prototype.drawAllBullets = function()
{
for(var i = 0; i < this.bullets.length; i++)
{
if(this.bullets[i].drawX >= 0)
{
this.bullets[i].draw();
}
if(this.bullets[i].explosion.hasHit)
{
this.bullets[i].explosion.draw();
}
}
}
Currently when I shoot an enemy they disappear but not explosion happens, I know my interval is not great coding, so I need some help with it, thanks!
Playing a spritesheet in canvas
It’s becoming best practice to use requestAnimationFrame to do your animations. It does some nice event grouping and performance enhancing. Here’s a good post on requestAnimationFrame: http://creativejs.com/resources/requestanimationframe/
This is how you can use requestAnimationFrame to play a spritesheet:
In this case, it’s a 4x4 spritesheet that will play over 1 second:
var fps = 16;
function explode() {
// are we done? ... if so, we're outta here
if(spriteIndex>15){return;}
// It's good practice to use requestAnimation frame
// We wrap it in setTimeout because we want timed frames
setTimeout(function() {
// queue up the next frame
requestAnimFrame(explode);
// Draw the current frame
var x=spriteIndex%(cols-1)*width;
var y=parseInt(spriteIndex/(rows-1))*height;
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.drawImage(sheet,x,y,width,height,0,0,width,height);
// increment the sprite counter
spriteIndex++;
}, 1000 / fps);
}
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/nSGyx/
<!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");
// This is Paul Irish's great cross browser shim for requestAnimationFrame
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
// define the spritesheet
var spriteIndex=0;
var width=64;
var height=64;
var rows=4;
var cols=4;
// load the sheet image
var sheet=document.createElement("img");
sheet.onload=function(){
canvas.width=width;
canvas.height=height;
// call the animation
explode();
}
sheet.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/explodeSprite.png";
var fps = 16;
function explode() {
// are we done? ... if so, we're outta here
if(spriteIndex>15){return;}
// It's good practice to use requestAnimation frame
// We wrap it in setTimeout because we want timed frames
setTimeout(function() {
// queue up the next frame
requestAnimFrame(explode);
// Draw the current frame
var x=spriteIndex%(cols-1)*width;
var y=parseInt(spriteIndex/(rows-1))*height;
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.drawImage(sheet,x,y,width,height,0,0,width,height);
// increment the sprite counter
spriteIndex++;
}, 1000 / fps);
}
$("#explode").click(function(){ spriteIndex=0; explode(); });
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=64 height=64></canvas><br>
<button id="explode">Explode</button>
</body>
</html>
.
.
.
[Edited to show more details of how animation fits into your code]
This is a recoding of your explosion functions.
Declare your explosion related variables outside the functions:
var bulletExplosionStart;
var whereX =0;
var whereY =0;
var wide = 70;
var high = 70;
Next, in Exploder(), set where the explosion will occur and reset the sprite index (bulletExplosionStart) to 0
Possible error: Check your Exploder function: you supply srcX,srcY but then do whereX=this.srcX, whereY=this.srcY. I assume you meant to use the srcX,srcY supplied as arguments to Exploder() instead of this.srcX,this.srcY.
function Exploder(srcX,srcY)
{
whereX = srcX;
whereY = srcY;
bulletExplosionStart=0;
BulletExplosionAnimate();
}
This is the recoded bulletExplosionAnimate function that plays the 4 frames of the spritesheet.
After 4 frames this animation automatically stops.
var fps = 2;
function bulletExplosionAnimate() {
// are we done? ... if so, we're outta here
if(bulletExplosionStart>308){return;}
// It's good practice to use requestAnimation frame
// We wrap it in setTimeout because we want timed frames
setTimeout(function() {
// queue up the next frame
requestAnimFrame(bulletExplosionAnimate);
// Draw the current frame
ctxExplosion.clearRect(0,0,canvasWidth,canvasHeight)
ctxExplosion.drawImage(spriteImage,
bulletExplosionStart,1250,wide,high,
whereX,whereY,wide,high);
// increment the sprite position
bulletExplosionStart += 77;
}, 1000 / fps);
}

Javascript touchEvents break Vertical Scrolling on iPad

I'm so close to getting this effect perfect, but I have run into a small little bump in the road.
I have a messaging system with a main div (#message-viewer) that contains a thread of messages. What I would like, is that when a user is viewing this on their iPad, and swipes to the right (anywhere inside this div), that #message-viewer slides off the screen and #div2 comes in from the left side of the screen.
Good News: The effect is smooth and responsive on the iPad. Javascript from Padalicious works like a charm.
Problems:
When the effect is on, my other jQuery functions do not work (for example, my buttons that open up a new div).
Vertical scrolling doesn't work! =(
I've tried:
In CSS on #swipeBox, I've tried all [overflow:] options to enable scrolling. No bueno.
I have tried attaching [ontouchstart=""] to the separate Divs, instead of creating a new one. No bueno.
I hope this makes sense... I have attached my code. I'm thinking the Padalicious code may be interfering with Y scrolling...
Thanks for the help!
HTML
<!DOCTYPE html>
<link rel="stylesheet" href="global/styles/base.css" type="text/css" />
<script src="global/js/jquery.tools.min.js"></script>
<script src="global/js/jquery.min.js"></script>
<script src="global/js/jquery-ui.min.js"></script>
<script src="global/js/jquery-1.5.js"></script>
<script src="global/js/ipad.js"></script>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="minimum-scale=1.0, maximum-scale=1.0,
width=device-width, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
</head>
<body>
<div id="swipeBox" ontouchstart="touchStart(event,'message-viewer');" ontouchend="touchEnd(event);" ontouchmove="touchMove(event);" ontouchcancel="touchCancel(event);">
<div id="content-container">
<div id="message-viewer">
// CONTENT HERE
</div>
<div class="Div2">
// CONTENT HERE
</div>
</div>
</div>
</body>
</html>
CSS
#swipeBox {
width: 100%;
height: auto;
}
JAVASCRIPT
var triggerElementID = null; // this variable is used to identity the triggering element
var fingerCount = 0;
var startX = 0;
var startY = 0;
var curX = 0;
var curY = 0;
var deltaX = 0;
var deltaY = 0;
var horzDiff = 0;
var vertDiff = 0;
var minLength = 72; // the shortest distance the user may swipe
var swipeLength = 0;
var swipeAngle = null;
var swipeDirection = null;
// The 4 Touch Event Handlers
// NOTE: the touchStart handler should also receive the ID of the triggering element
// make sure its ID is passed in the event call placed in the element declaration, like:
// <div id="picture-frame" ontouchstart="touchStart(event,'picture-frame');" ontouchend="touchEnd(event);" ontouchmove="touchMove(event);" ontouchcancel="touchCancel(event);">
function touchStart(event,passedName) {
// disable the standard ability to select the touched object
event.preventDefault();
// get the total number of fingers touching the screen
fingerCount = event.touches.length;
// since we're looking for a swipe (single finger) and not a gesture (multiple fingers),
// check that only one finger was used
if ( fingerCount == 2 ) {
// get the coordinates of the touch
startX = event.touches[0].pageX;
startY = event.touches[0].pageY;
// store the triggering element ID
triggerElementID = passedName;
} else {
// more than one finger touched so cancel
touchCancel(event);
}
}
function touchMove(event) {
event.preventDefault();
if ( event.touches.length == 2 ) {
curX = event.touches[0].pageX;
curY = event.touches[0].pageY;
} else {
touchCancel(event);
}
}
function touchEnd(event) {
event.preventDefault();
// check to see if more than one finger was used and that there is an ending coordinate
if ( fingerCount == 2 && curX != 0 ) {
// use the Distance Formula to determine the length of the swipe
swipeLength = Math.round(Math.sqrt(Math.pow(curX - startX,2) + Math.pow(curY - startY,2)));
// if the user swiped more than the minimum length, perform the appropriate action
if ( swipeLength >= minLength ) {
caluculateAngle();
determineSwipeDirection();
processingRoutine();
touchCancel(event); // reset the variables
} else {
touchCancel(event);
}
} else {
touchCancel(event);
}
}
function touchCancel(event) {
// reset the variables back to default values
fingerCount = 0;
startX = 0;
startY = 0;
curX = 0;
curY = 0;
deltaX = 0;
deltaY = 0;
horzDiff = 0;
vertDiff = 0;
swipeLength = 0;
swipeAngle = null;
swipeDirection = null;
triggerElementID = null;
}
function caluculateAngle() {
var X = startX-curX;
var Y = curY-startY;
var Z = Math.round(Math.sqrt(Math.pow(X,2)+Math.pow(Y,2))); //the distance - rounded - in pixels
var r = Math.atan2(Y,X); //angle in radians (Cartesian system)
swipeAngle = Math.round(r*180/Math.PI); //angle in degrees
if ( swipeAngle < 0 ) { swipeAngle = 360 - Math.abs(swipeAngle); }
}
function determineSwipeDirection() {
if ( (swipeAngle <= 45) && (swipeAngle >= 0) ) {
swipeDirection = 'left';
} else if ( (swipeAngle <= 360) && (swipeAngle >= 315) ) {
swipeDirection = 'left';
} else if ( (swipeAngle >= 135) && (swipeAngle <= 225) ) {
swipeDirection = 'right';
}
}
function processingRoutine() {
var swipedElement = document.getElementById(triggerElementID);
if ( swipeDirection == 'left' ) {
// REPLACE WITH YOUR ROUTINES
$("#message-viewer").removeClass("slideright");
$('.Div2').removeClass("slideright");
} else if ( swipeDirection == 'right' ) {
// REPLACE WITH YOUR ROUTINES
$("#message-viewer").addClass("slideright");
$('.Div2').addClass("slideright");
}
}
The event.preventDefault(); block scrolling

Categories

Resources