I am having trouble creating game on html canvas. The premise of the game is you have to catch the balloons before they hit the ground. I am having problems with the background of the canvas and the basket is not moving with the mouse.
The background should be black and the basket should be following the mouse curser.
https://jsfiddle.net/pgkL09j7/8/
<html>
<head>
<title>Sean Coyne</title>
<link rel="stylesheet" type="text/css" href="home.css">
<link rel="icon" type="image/x-icon" href="favicon.ico" />
</head>
<body onload="start_game()">
<body>
<section>
<article>
<div id="logo"><img src="LogoComic.png" id="Logo"></div><br></br>
<div id="canvas">
<canvas id="c" style="border:5px solid orange" height="500" width="500"></canvas>
<p id="p1"></p>
<script>
var balloon_x=100;
var balloon_y=0;
var basket_x=100;
var basket_y=100;
var points=0;
//Background colour of canvas
var c = document.getElementById("c");
var ctx = c.getContext("2d");
ctx.fillStyle = "#000";
ctx.fillRect(0,0,500,500);
//Here is the event listener
mycanv.addEventListener("mousemove",seenmotion, false);
function seenmotion(e) {
//This is the code for the mouse
//moving over the canvas.
var bounding_box=c.getBoundingClientRect();
basket_x=(e.clientX-bounding_box.left) *
(c.width/bounding_box.width);
basket_y=(e.clientY-bounding_box.top) *
(c.height/bounding_box.height);
}
function start_game() {
setInterval(game_loop, 50);
}
function game_loop() {
// The code above is called every 50ms and is a
// frame-redraw-game-animation loop.
c.width = c.width;
// Below is the code that draws the objects
draw_balloon(balloon_x,balloon_y);
draw_basket(basket_x,basket_y);
// Below is the code that updates the balloons location
balloon_x++;
if (balloon_x>c.width) {
balloon_x=0;
}
//Here is the collision detection code
if (collision(balloon_x, balloon_y, basket_x, basket_y)) {
points -= 0.5;
}
//Here is the code for the point system
points+=1;
// and let's stick it in the top right.
var integerpoints=Math.floor(points); // make it into an integer
ctx.font="bold 24px sans-serif ";
ctx.fillText(integerpoints, c.width-50, 50);
}
context.clearRect ( 0 , 0 , 500, 500 );
function collision(basket_x, basket_y, ball_x, ball_y) {
if(balloon_y + 85 < basket_y) {
return false;
}
if (balloon_y > basket_y + 91) {
return false;
}
if (balloon_x + 80 < basket_x) {
return false;
}
if (balloon_x > basket_x + 80) {
return false;
}
return true;
}
// Code to stop the game when we're finished playing
function stop_game() {
}
//Code for the ball
function draw_balloon(x,y) {
var balloon_img=new Image();
balloon_img.src="balloon.png";
ctx.drawImage(balloon_img,x,y);
}
//Code for the basket
function draw_basket(x,y) {
var basket_img=new Image();
basket_img.src="basket.png";
ctx.drawImage(basket_img,x,y);
}
</script>
</div>
</article>
</section>
</body>
</html>
You have to change the variable for the mouselistener. So instead of
mycanv.addEventListener("mousemove",seenmotion, false);
you have to write this
c.addEventListener("mousemove",seenmotion, false);
This move the basket with the mouse, but the image isn't still right. You have to subtract half of width and height of the image from the x and y coordinate.
To fix your background you have to modify your CSS. the article and the section tag have both full width/height und an own background. This shouldn't be to hard to fix, just change the background of #c to black.
#c {
background-color: black;
}
Here's the jsfiddle: https://jsfiddle.net/pgkL09j7/10/
Visit http://www.w3schools.com/ for more information about CSS and JS. Also the code can be more easier and structured.
Related
since I'm learning new to html and javascript, I was wondering if you can place an moving image side to side on a canvas? If so how can this be done please???
Here's what I've to do so far.
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="ann.css" />
<script>
window.onload = animate;
var canvas=document.getElementById('mycanvas');
var ctx=canvas.getContext('2d');
function animate()
{
window.setInterval(slide,1000);
}
function slide()
{
var obj = document.getElementById("ball");
var left = obj.style.left;
if(left === ''){
left = 0;
}
var wartosc = parseInt(left, 10);
obj.style.left = (wartosc + 10) + "px";
}
function Loop() {
if (left>canvas.width){
var right = obj.style.right;
if(right === ''){
right = 0;
}
var wartosc = parseInt(right, 10);
obj.style.right = (wartosc + 10) + "px";
}
</script>
<style>
#ball
{
position: relative;
left: 1px;
}
#mycanvas {border:1px solid #000000}
</style>
</head>
<body>
<img src="ball.gif" id="ball" alt="Usmiech" width="30" height="30" />
<canvas id=mycanvas width=600 height=50>Canvas Not Supported
</canvas>
<body>
</html>
What I want it do to is for the image to be contained inside the canvas and to move left to right and when reached the right side of canvas to go back left and so on continuously.
However my problems are if can be done, I don't know how I can put the image on the canvas and then I can't make the image move to the right once it has reached the end off the canvas. I think the issue is my loop function, which is there to try to make it go to the right.
As you can see from the fiddle link, when I remove the loop function code it works. However it will only goes to the left.
http://jsfiddle.net/eCSb4/18/
Please can someone help me fix it? :)
You can animate a spritesheet instead of a .gif.
The sequence is simple:
Clear the canvas,
Draw the next sprite in sequence and position it to advance across the canvas.
Wait a while (perhaps in a requestAnimationFrame loop).
Repeat #1.
Here's annotated code and a Demo:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
// timing related vars
var nextTime=0;
var spriteCount=7;
var interval=700/spriteCount;
// sprite related vars
var sIndex=0;
var sw=60;
var sh=95;
var animationOn=true;
// current x,y position of sprite
var x=100;
var y=100;
// load the spritesheet
var ss=new Image();
ss.onload=start;
ss.src="http://i59.tinypic.com/jpkk6f.jpg";
function start(){
// draw the first sprite
ctx.drawImage(ss,sIndex*sw,0,sw,sh,x,y,sw,sh);
// start the animation loop
requestAnimationFrame(animate);
}
function animate(time){
// wait for the specified interval before drawing anything
if(time<nextTime || !animationOn){requestAnimationFrame(animate); return;}
nextTime=time+interval;
// draw the new sprite
ctx.clearRect(0,0,cw,ch);
ctx.drawImage(ss,sIndex*sw,0,sw,sh,x,y,sw,sh);
// get the next sprite in sequence
if(++sIndex>=spriteCount){sIndex=0;}
// advance the sprite rightward
x+=5;
if(x>cw){x=-sw-10;}
// request another animation loop
requestAnimationFrame(animate);
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=300 height=300></canvas>
I am trying to create flip card effect using html canvas by drawing it in the canvas.
no ccs3 tricks needed. It should be done in a native manner;
this is my initial test using phaser.js by changing the scale
<html>
<head>
</head>
<body>
<div id="game_canvas">
</div>
<script src = "jquery.min.js"></script>
<script src = "phaser.min.js"></script>
<script>
var game;
var sprite;
$(document).ready(function(){
game = new Phaser.Game(640, 480, Phaser.AUTO, 'game_canvas', {
preload : preload,
create : create,
update : update
});
function preload () {
game.load.image('card','download.png');
}
function create() {
this.delay = 1000;
this.spawn = 0;
sprite = game.add.sprite(game.width/4, game.height/4, 'card');
}
function update() {
console.log(this.spawn > game.time.now);
if (this.spawn > game.time.now) {
return;
}
this.spawn = game.time.now + this.delay;
sprite.scale.x *= -1;
}
});
</script>
</body>
</html>
and what i want to attain is like this using the canvas
http://www.turnjs.com/#samples/steve-jobs/10
anyone has any idea on how to do it would be a great help
thanks in advance
here is the current demo
http://sopronioli713.github.io/test/
Here's a canvas based card flip (with rotation) that I did a while back for fun.
It works by scaling in just the X direction so that the card appears to be flipping.
Notes about the effect:
You can omit the rotations if they are not required.
This effect translates to the horizontal center of the card before scaling (flipping) which makes the card "spin". If you instead want a "dealers flip" then you would instead translate to the edge of the card.
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var x=150;
var y=150;
var scaleX=100;
var angle=0;
var scaleDirection=-1;
var scaleDelta=1;
var PI2=Math.PI*2;
var backCanvas=document.createElement('canvas');
var backCtx=backCanvas.getContext('2d');
var imgCount=2;
var front=new Image();front.onload=start;front.src="https://dl.dropboxusercontent.com/u/139992952/multple/kingcard.png";
var back=new Image();back.onload=start;back.src="https://dl.dropboxusercontent.com/u/139992952/multple/kingcardback.png";
function start(){
if(--imgCount>0){return;}
animate();
}
function draw(x,y,scaleX,angle){
ctx.clearRect(0,0,cw,ch);
ctx.translate(x,y);
ctx.rotate(angle);
ctx.scale(scaleX,1);
if(scaleX>=0){
ctx.drawImage(front,-front.width/2,-front.height/2);
}else{
ctx.drawImage(back,-back.width/2,-back.height/2);
}
ctx.setTransform(1,0,0,1,0,0);
}
function animate(time){
draw(x,y,scaleX/100,angle);
angle+=PI2/720;
scaleX+=scaleDirection*scaleDelta;
if(scaleX<-100 || scaleX>100){
scaleDirection*=-1;
scaleX+=scaleDirection*scaleDelta;
}
requestAnimationFrame(animate);
}
body{ background-color: ivory; }
#canvas{border:1px solid red;}
<canvas id="canvas" width=300 height=300></canvas>
On the other hand...
You link to a page-turning demo--which is a totally different animal. If that's what your after Rick Barraza has done a nice writeup on how to do that here: http://rbarraza.com/html5-canvas-pageflip/
Let's say I have an scanned paper with some black filled rectangles and I want to positionate all of them, getting their coordinates (X and Y) and their dimensions (Width and Height).
Is there any accurate algorithm which does what I need? I'm new to pixel processing with Javascript and Canvas and I need some help. Thanks in advance!
Identifying the x,y,width,height of all black rectangles involves these steps:
Use context.getImageData to get an array of all the r,g,b,a pixel information on the canvas.
Scan the pixel colors to find any one black pixel.
Find the bounding box of the black rectangle containing that one black pixel.
That bounding box will give you the x,y,width,height of one black rectangle.
Clear that black rectangle so that it is not found when searching for the next black rectangle.
Repeat step#1 until all the rectangles are identified.
Here's example code and a Demo: http://jsfiddle.net/m1erickson/3m0dL368/
<!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;}
#clips{border:1px solid blue; padding:5px;}
img{margin:3px;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw,ch;
// background definition
// OPTION: look at the top-left pixel and assume == background
// then set these vars automatically
var isTransparent=false;
var bkColor={r:255,g:255,b:255};
var bkFillColor="rgb("+bkColor.r+","+bkColor.g+","+bkColor.b+")";
cw=canvas.width;
ch=canvas.height;
ctx.fillStyle="white";
ctx.fillRect(0,0,canvas.width,canvas.height);
drawTestRect(30,30,50,50,"1");
drawTestRect(100,30,50,50,"2");
drawTestRect(170,30,50,50,"3");
function drawTestRect(x,y,w,h,label){
ctx.fillStyle="black";
ctx.fillRect(x,y,w,h);
ctx.fillStyle="white";
ctx.font="24px verdana";
ctx.fillText(label,x+10,y+25);
}
function clipBox(data){
var pos=findEdge(data);
if(!pos.valid){return;}
var bb=findBoundary(pos,data);
alert("Found target at "+bb.x+"/"+bb.y+", size: "+bb.width+"/"+bb.height);
clipToImage(bb.x,bb.y,bb.width,bb.height);
if(isTransparent){
// clear the clipped area
// plus a few pixels to clear any anti-aliasing
ctx.clearRect(bb.x-2,bb.y-2,bb.width+4,bb.height+4);
}else{
// fill the clipped area with the bkColor
// plus a few pixels to clear any anti-aliasing
ctx.fillStyle=bkFillColor;
ctx.fillRect(bb.x-2,bb.y-2,bb.width+4,bb.height+4);
}
}
function xyIsInImage(data,x,y){
// find the starting index of the r,g,b,a of pixel x,y
var start=(y*cw+x)*4;
if(isTransparent){
return(data[start+3]>25);
}else{
var r=data[start+0];
var g=data[start+1];
var b=data[start+2];
var a=data[start+3]; // pixel alpha (opacity)
var deltaR=Math.abs(bkColor.r-r);
var deltaG=Math.abs(bkColor.g-g);
var deltaB=Math.abs(bkColor.b-b);
return(!(deltaR<5 && deltaG<5 && deltaB<5 && a>25));
}
}
function findEdge(data){
for(var y=0;y<ch;y++){
for(var x=0;x<cw;x++){
if(xyIsInImage(data,x,y)){
return({x:x,y:y,valid:true});
}
}}
return({x:-100,y:-100,valid:false});
}
function findBoundary(pos,data){
var x0=x1=pos.x;
var y0=y1=pos.y;
while(y1<=ch && xyIsInImage(data,x1,y1)){y1++;}
var x2=x1;
var y2=y1-1;
while(x2<=cw && xyIsInImage(data,x2,y2)){x2++;}
return({x:x0,y:y0,width:x2-x0,height:y2-y0+1});
}
function drawLine(x1,y1,x2,y2){
ctx.beginPath();
ctx.moveTo(x1,y1);
ctx.lineTo(x2,y2);
ctx.strokeStyle="red";
ctx.lineWidth=0.50;
ctx.stroke();
}
function clipToImage(x,y,w,h){
// don't save anti-alias slivers
if(w<3 || h<3){ return; }
// save clipped area to an img element
var tempCanvas=document.createElement("canvas");
var tempCtx=tempCanvas.getContext("2d");
tempCanvas.width=w;
tempCanvas.height=h;
tempCtx.drawImage(canvas,x,y,w,h,0,0,w,h);
var image=new Image();
image.width=w;
image.height=h;
image.src=tempCanvas.toDataURL();
$("#clips").append(image);
}
$("#unbox").click(function(){
var imgData=ctx.getImageData(0,0,cw,ch);
var data=imgData.data;
clipBox(data);
});
}); // end $(function(){});
</script>
</head>
<body>
<button id="unbox">Clip next sub-image</button><br>
<canvas id="canvas" width=300 height=150></canvas><br>
<h4>Below are images clipped from the canvas above.</h4><br>
<div id="clips"></div>
</body>
</html>
I want to use onmouseover in this javascript code. So, whenever I move the mouse over the square, the function changeColor executes and picks one color each time, from the two given colors.
<!DOCTYPE html>
<html>
<head>
<title>TEST</title>
</head>
<body>
<h1>Canvas Art Gallary</h1>
<canvas id="myCanvas" width="400" height="300" style="border:10px solid #c3c3c3">
</canvas>
<script type="text/javascript">
function changeColor(){
ctx.fillStyle = "#FFFFFF";
ctx.fillStyle = "#04B45F";
}
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "#FF0000";
ctx.fillRect(150,100,100,100);
</script>
</body>
</html>
Thanks
Listen for mouse events and toggle the color on our own custom mouseenter
Note: the rect does not have mouseenter so we must custom build one.
Listen for mousemove events
On rect mouseenter: set a wasInside flag to true and changeColor() which toggles the rect color
On rect mouseleave: clear a wasInside flag to indicate the mouse has left the rect.
Example code and a Demo: http://jsfiddle.net/m1erickson/9GcbH/
<!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;background-color:black;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var $canvas=$("#canvas");
var canvasOffset=$canvas.offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var scrollX=$canvas.scrollLeft();
var scrollY=$canvas.scrollTop();
var toggle=0;
var x=150;
var y=100;
var w=100;
var h=100;
var wasInside=false;
// draw the rect to start
ctx.fillStyle = "red";
ctx.fillRect(x,y,w,h);
function changeColor(){
if(toggle==0){
ctx.fillStyle = "#FFFFFF";
toggle=1;
}else{
ctx.fillStyle = "#04B45F";
toggle=0;
}
ctx.fillRect(x,y,w,h);
}
function handleMouseMove(e){
e.preventDefault();
var mx=parseInt(e.clientX-offsetX);
var my=parseInt(e.clientY-offsetY);
var isInsideNow=(mx>x && mx<x+w && my>y && my<=y+h);
if(isInsideNow && !wasInside){
changeColor();
wasInside=true;
}else if(!isInsideNow && wasInside){
wasInside=false;
}
}
$("#canvas").mousemove(function(e){handleMouseMove(e);});
}); // end $(function(){});
</script>
</head>
<body>
<h4>Rect color toggles white-green<br>each time mouse moves over it.</h4>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
[ Addition: explain steps of toggling ]
Each time the mouse enters the rect changeColor is called.
changeColor both changes the color and also changes toggle.
Here's a step-by-step:
1. toggle==0 at the beginning of the ap
2. mouse enters rect and changeColor is called.
3. changeColor changes color to #ffffff because toggle==0.
4. changeColor changes toggle=1
5. mouse exits rect
6. mouse enters rect again and changeColor is called again.
7. changeColor changes color to #04b45f because toggle==1.
8. changeColor changes toggle=0;
mouseover will only know when you're over the canvas, so you need to detect you're above the square (I'm using the variables already defined by you):
var sqx1 = c.offsetLeft + 150; //left top corner of the square respect to the window
var sqy1 = c.offsetTop + 100;
var sqx2 = sqx1 + 100; //right bottom corner of the square respect to the window
var sqy2 = sqy1 + 100;
var lastOverSquare = false;
c.addEventListener('mousemove', function(e) {
var overSquare =
(sqx1 <= e.pageX && sqx2 >= e.pageX) &&
(sqy1 <= e.pageY && sqy2 >= e.pageY);
if (overSquare && !lastOverSquare) changeColour(); //change only when it enters the square, not every move when we're already over it.
lastOverSquare = overSquare;
}, false);
var colours = ['#FFFFFF', '#04B45F'];
var currentColour = 0;
ctx.fillStyle = colours[currentColour];
function changeColour() {
currentColour = (currentColour + 1) % colours.length;
ctx.fillStyle = colours[currentColour];
}
Hi i'm having trouble getting my paint canvas buttons that change the colours of the paint brush to move beside the canvas.
It seems to be stuck at the tope left hand corner of the webpage unfortunately and i'm struggling trying to re-locate it. And suggestions would be very helpful. Thank you.
Here is some of my code that should give you an idea of what im talking about.
var brush = 10;
function changeColour(colour)
{
g.fillStyle = colour;
}
function clearCanvas()
{
g.clearRect(0, 0, canvas.width, canvas.height);
}
var mouseIsDown = false;
function down(e)
{
mouseIsDown = true;
/*e.originalEvent.preventDefault();*/
}
function up(e)
{
mouseIsDown = false;
}
function changeBrushSize(symbol)
{
if(symbol =='+')
{
brush = brush + 2;
}
else if (symbol == '-')
{
brush = brush - 2;
}
}
function move(e)
{
var container = document.getElementById('container');
//g.clearRect(0, 0, canvas.width, canvas.height);
//g.fillRect(e.x - 5, e.y - 5, 100, 100);
if((e.button == 0) && (mouseIsDown))
{
g.beginPath();
document.onselectstart = function(){ return false; }
//g.fillStyle = "red";
g.arc((e.x - container.offsetLeft) - brush, (e.y - container.offsetTop) - brush, brush, 0, Math.PI * 2);
g.fill();
g.closePath();
}
}
</script>
</head>
<body>
<div id="container">
<canvas id = "paintCanvas" width = "500" height = "500">
Your browser does not support the HTML5 <canvas> tag.
</canvas>
</div>
<button onclick ="clearCanvas()">Clear Canvas</button></br>
<button onclick ="changeColour('red')">Red</button>
<button onclick ="changeColour('green')">Green</button>
<button onclick ="changeColour('blue')">Blue</button>
<button onclick ="changeColour('yellow')">Yellow</button>
<button onclick ="changeColour('orange')">Orange</button>
<button onclick ="changeColour('brown')">Brown</button>
<button onclick ="changeColour('purple')">Purple</button></br>
<button onclick ="changeBrushSize('+')">Bigger Brush</button>
<button onclick ="changeBrushSize('-')">Smaller Brush</button>
</body>
You might let the user select their colors and other tools from a second "tools" canvas
Then position the "tools" canvas before the "drawing" canvas.
<canvas id="toolsCanvas"></canvas><br>
<canvas id="drawingCanvas"></canvas>
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/y5xu7/
<!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: white; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("drawingCanvas");
var context=canvas.getContext("2d");
var tools=document.getElementById("toolsCanvas");
var ctx=tools.getContext("2d");
var canvasOffset=$("#toolsCanvas").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var colors=['Red','Green','Blue','Yellow','Orange','Brown','Purple']
var lightcolors="Yellow|White";
var colorPickerWidth=25;
// draw the color picker
tools.width=colors.length*colorPickerWidth;
for(var i=0;i<colors.length;i++){
ctx.fillStyle=colors[i];
ctx.fillRect(i*colorPickerWidth,0,colorPickerWidth,25);
}
// called when the user clicks and picks a color
function handleMouseDown(e){
console.log("down");
var x=parseInt(e.clientX-offsetX);
var color=colors[parseInt(x/colorPickerWidth)];
ctx.save();
ctx.fillStyle=color;
ctx.fillRect(0,28,tools.width,25);
ctx.fillStyle="white";
if(lightcolors.indexOf(color)>-1){ctx.fillStyle="black";}
ctx.font="16px verdana";
ctx.fillText("Selected: "+color,10,45);
ctx.restore();
context.clearRect(0,0,canvas.width,canvas.height);
context.fillStyle=color;
context.font="14px arial";
context.fillText("fillStyle==your selected color",30,100);
}
$("#toolsCanvas").mousedown(function(e){handleMouseDown(e);});
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="toolsCanvas" width=300 height=53></canvas><br>
<canvas id="drawingCanvas" width=300 height=300></canvas>
</body>
</html>