I want to call a function by touching a button in HTML5. I haveange in a canvas drawn a rect.
Here is my code:
<body>
<canvas id="canvas" width="200" height="300"></canvas>
<button id="as" type="button">Left</button></body>
<script>
var inc=10;
var c=document.getElementById("canvas");
ctx = c.getContext("2d");
ctx.fillRect(x,0,150,75);
function moveLeft(){ x+=inc }
</script>
Since you mentioned 'touch', I guess we'll need a timer. The canvas draw routine also need some fixing. Here is my version:
<html><body>
<canvas id="canvas" width="200" height="300" style='border:1px solid black'></canvas>
<button id="as" type="button" onmouseover='startMove()' onmouseout='stopMove()'>Left</button></body>
<script>
var c=document.getElementById("canvas");
var ctx = c.getContext("2d");
var inc = 10;
var timer = 0;
var x = 100;
function moveLeft(){ if ( x > 0 ) x-=inc; drawCtx(); }
function drawCtx(){ ctx.clearRect(0,0,200,300); ctx.fillStyle='black'; ctx.fillRect(x,0,50,75); }
function startMove(){ stopMove(); timer = setInterval(moveLeft, 1000); }
function stopMove(){ clearInterval(timer); }
drawCtx();
</script>
What this do is when you mouse over it will start calling moveLeft once per second (1000ms interval) until you move away the mouse.
Code is not nice, but it works and I hope it is simple enough to get the point across.
Here an example moving all directions and border checking:
HTML:
<canvas id="canvas"></canvas><br>
<button type="button" onclick="moveRect(0, -10);">move up</button><br>
<button type="button" onclick="moveRect(-10, 0);">move left</button>
<button type="button" onclick="moveRect(+10, 0);">move right</button><br>
<button type="button" onclick="moveRect(0, +10);">move down</button>
JS:
var c = null, ctx = null, x = 0, y = 0;
var width = 150, height = 75;
function moveRect(x2, y2) {
ctx.clearRect(x, y, width, height);
x += x2;
if (x < 0) x = 0;
else if (x > c.width - width) x = c.width - width;
y += y2;
if (y < 0) y = 0;
else if (y > c.height - height) y = c.height - height;
ctx.fillRect(x, y, width, height);
}
window.onload = function() {
c = document.getElementById("canvas");
ctx = c.getContext("2d");
x = 0;
moveRect(0, 0);
}
CSS:
#canvas {
width: 200;
height: 300px;
border: 1px solid red;
}
Also see this example.
You can to give fill style to make your rectangle visible or draw it border. Secondly you want to attach event to button to move the rectangle drawn on canvas. The could be done by this code and could mold the code according to your need. Demo on JsFiddle using Javascript and Demo on JsFiddle using jQuery
x =200;
$('#as').click(function()
{
var inc=10;
var c=document.getElementById("canvas");
//c.style.backgroundColor = "#ff0000";
ctx = c.getContext("2d");
ctx.fillStyle="#ff0000";
ctx.fillRect(x+5,0,15,75);
ctx.fillStyle="#ffffff";
ctx.fillRect(x,0,15,75);
x-=5;
}
);
Related
So I have this rectangle that animates across to the right. How can I get the rectangle to reverse it when it hits the boundaries. I'm trying to make it go back and forth.
<!DOCTYPE html>
<html>
<head>
<script type='text/javascript'>
window.onload=function(){
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var x = 0;
var y = 50;
var width = 10;
var height = 10;
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillRect(x, y, width, height);
x++;
if(x <= 490) {
setTimeout(animate, 33);
}
}
animate();
}
</script>
</head>
<body>
<canvas id="canvas" width="500" height="400"
style="border: 1px solid #000000;"></canvas>
</body>
</html>
https://codepen.io/forTheLoveOfCode/pen/wqdpeg
Is that what you need? (link to codepen above).
var canvas = document.getElementById("canvas_id");
var context = canvas.getContext('2d');
var x=5;
var y=5;
var velocity = 10;
function move(){
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
x =x + velocity
if ((x+50)>canvas.width || x<0){
velocity *=-1;
}
draw()
}
function draw(){
context.fillStyle = "#E80C7A";
context.strokeStyle = "#000000";
context.lineWidth = '3';
context.fillRect(x, y, 50, 100);
context.strokeRect(x, y, 50, 100);
}
setInterval(move, 100);
<html>
<body>
<canvas id = "canvas_id">
</canvas>
</body>
</html>
here's a solution with boundaries detection
window.onload=function(){
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var x = 0;
var y = 50;
var width = 10;
var height = 10;
var speed = 10; // speed
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillRect(x, y, width, height);
if(
(x >= 500 - width && speed > 0) || // going to the right and bound reached
(x <= 0 && speed < 0) // going to the left and bound reached
) {
speed *= -1; // inverting the direction
}
x += speed;
setTimeout(animate, 33);
}
animate();
}
<canvas id="canvas" width="500" height="400"
style="border: 1px solid #000000;"></canvas>
consider using requestAnimationFrame instead of setTimeout to do this kind of work.
I would like the rectangle to move on the canvas and not copy every time.
It draws it but then the rectangle stays there.
I am a beginner with the canvas so if it is an epic fail then be prepared.
The codepen is at LINK.
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
var WIDTH = canvas.width;
var HEIGHT = canvas.height;
var boxWidth = 50;
var boxHeight = 50;
var bX = WIDTH / 2 - boxWidth / 2;
var bY = HEIGHT / 2 - boxHeight / 2;
function render() {
ctx.fillStyle = "white";
ctx.rect(bX, bY, boxWidth, boxHeight);
ctx.fill();
}
function control() {
bX++;
}
function main() {
control();
render();
}
main();
var run = setInterval(main, 10)
canvas {
width: 400px;
height: 400px;
background-color: black;
}
div {
text-align: center;
}
<div>
<canvas width="400px" height="400px" background-color="black" id="canvas"></canvas>
</div>
Repaint your canvas before drawing the rectangle each time - think about it. Its all done in layers.
The rectangle is "staying there" because you aren't replacing the rectangle your drew last time.
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
var WIDTH = canvas.width;
var HEIGHT = canvas.height;
var boxWidth = 50;
var boxHeight = 50;
var bX = WIDTH / 2 - boxWidth / 2;
var bY = HEIGHT / 2 - boxHeight / 2;
function render() {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); //use clear rect instead
ctx.fillStyle = "white";
ctx.fillRect(bX, bY, boxWidth, boxHeight); //use fillRect instead of fill()
}
function control() {
bX++;
}
(function main() {
control();
render();
requestAnimationFrame(()=>main());
})()
canvas {
width: 400px;
height: 400px;
background-color: black;
}
div {
text-align: center;
}
<html>
<head></head>
<body>
<div>
<canvas width="400px" height="400px" background-color="black" id="canvas"></canvas>
</div>
</body>
</html>
Also have a look at the requestAnimationFrame() method as opposed to setInterval - it syncs up with the window's javascript timer and is less likely to cause problems.
how to get mouseover to draw on html canvas with event listener with my code? https://jsfiddle.net/dannixx/d0p0j8cL/
jifiddle file, i want to be able to draw line on canvas with mouseover https://jsfiddle.net/dannixx/d0p0j8cL/
<!DOCTYPE html>
<html>
<head>
<title>Canvas</title>
<style type="text/css">
#Canvas1 {
border: : dotted 3px black;
background-color: blue;
}
</style>
<script>
window.onload = function(){
var theCanvas = document.getElementById("Canvas1");
if (theCanvas && document.getContext("2d")){
var ctx = theCanvas.getContext("2d";)
if(ctx){
ctx.fillStyle = "lightblue";
ctx.fillRect(0,0 ctx.canvas.width, ctx.canvas.height)
}
}
}
</script>
</head>
<body>
<h1>cnavas</h1>
<p>ex</p>
<canvas id="Canvas1" width="400", height="300"></canvas>
<p id="demo"></p>
</body>
</html>
Here is a really simple example using a onmousemove listener that updates the new mouse coordinates and draws a line from the previous coordinates to the new coordinates. Run it and see!
var x = null;
var y = null;
var c = null;
var ctx = null;
function getPos(e) {
//if it is the first time the event listener is called then set x and y to the new mouse coordinate
if(x == null) {
x=e.clientX;
y=e.clientY;
}
//otherwise draw from the previous point (x, y) to the new coordinates (e.clientX, e.clientY).
ctx.beginPath();
ctx.moveTo(x,y);
ctx.lineTo(e.clientX,e.clientY);
ctx.stroke();
x=e.clientX;
y=e.clientY;
}
window.onload = function(){
c=document.getElementById("Canvas1");
ctx=c.getContext("2d");
}
<canvas onmousemove="getPos(event)" id="Canvas1" width="400", height="300"></canvas>
Here is a simple example script (using the stroke method) for drawing on a canvas:
HTML :
<canvas id="can1"></canvas>
CSS :
#can1 {
border:dashed 3px #000;
}
JavaScript :
var can = document.getElementById("can1");
var canCtx = can.getContext("2d");
var sx = 0, sy = 0;
var clicked = false;
function _left(e){
return e.pageX - can.offsetLeft;
}
function _top(e){
return e.pageY - can.offsetTop;
}
function _draw(e, sx, sy){
var x = _left(e);
var y = _top(e);
canCtx.moveTo(sx, sy);
canCtx.lineTo(x, y);
canCtx.strokeStyle="red";
canCtx.stroke();
}
can.addEventListener("mousedown", function(e){
sx = _left(e);
sy = _top(e);
_draw(e, sx, sy);
clicked = true;
}, false);
can.addEventListener("mousemove", function(e){
if(clicked == true){
_draw(e, can);
}
}, false);
addEventListener("mouseup", function(){
clicked = false;
}, false);
I have a canvas, size 400 x 400. On it, i have drawn a map area, 200 x 200.
I have translated this to the center of the canvas. I can zoom in and out, all is well. But, when i pan, it zooms from the center of my map area. I want it to always zoom from the center of the canvas no matter where the map area is. I think i need to negate the pan coords somehow, but i can't figure it out.
Here is my code:
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var canvas1 = document.getElementById("canvasX");
var ctxX = canvas1.getContext("2d");
var cw = canvas.width;
var ch = canvas.height;
var mapW = 200;
var mapH = 200;
var panX=0;
var panY=0;
var scaleFactor=1.00;
drawTranslated();
function zoomIn(){
document.getElementById("zoomin").click();
{ scaleFactor*=1.1; drawTranslated(); };
}
function zoomOut(){
document.getElementById("zoomout").click();
{ scaleFactor/=1.1; drawTranslated(); };
}
function panUp(){
document.getElementById("panup").click();
{ panY-=25; drawTranslated(); };
}
function panDown(){
document.getElementById("pandown").click();
{ panY+=25; drawTranslated(); };
}
function panLeft(){
document.getElementById("panleft").click();
{ panX-=25; drawTranslated(); };
}
function panRight(){
document.getElementById("panright").click();
{ panX+=25; drawTranslated(); };
}
function drawTranslated(){
// canvas
ctx.clearRect(0,0,cw,ch);
ctx.save();
ctx.translate(cw/2, ch/2);
ctx.translate(panX,panY);
ctx.scale(scaleFactor, scaleFactor);
ctx.fillStyle = "Green";
ctx.fillRect(mapW/-2, mapH/-2, mapW, mapH);
ctx.restore();
// canvasX
ctxX.clearRect(0,0,cw,ch);
ctxX.save();
ctxX.translate(cw/2, ch/2);
ctxX.beginPath();
ctxX.moveTo(0, 25);
ctxX.lineTo(0, -25);
ctxX.moveTo(-25, 0);
ctxX.lineTo(25, 0);
ctxX.closePath();
ctxX.lineWidth = 1;
ctxX.strokeStyle = 'Black';
ctxX.stroke();
ctxX.restore();
}
#wrapper {position: relative;}
canvas {position: absolute; border: 1px solid Black;}
<!DOCTYPE html>
<html>
<body>
<div id="wrapper">
<button id="zoomin" class="nav" title="Zoom In" onclick="zoomIn()">+</button>
<button id="zoomout" class="nav" title="Zoom Out" onclick="zoomOut()">−</button>
<button id="panup" class="nav" title="Up" onclick="panUp()">⇧</button>
<button id="pandown" class="nav" title="Down" onclick="panDown()">⇩</button>
<button id="panleft" class="nav" title="Left" onclick="panLeft()">⇦</button>
<button id="panright" class="nav" title="Right" onclick="panRight()">⇨</button>
</div>
<div id="wrapper">
<canvas id="myCanvas" width="400" height="400"></canvas>
<canvas id="canvasX" width="400" height="400"></canvas>
</div>
</body>
</html>
After some time of trying to find some equation to solve this, i think i have found the solution.
ctx.translate(panX,panY);
ctx.scale(scaleFactor, scaleFactor);
By panning first, then scaling, it will zoom from the center of the context (In this case the green square). However, simply changing it around to:
ctx.scale(scaleFactor, scaleFactor);
ctx.translate(panX,panY);
it will zoom from the center of the canvas.
It seems to do what i want it to, so unless i am mistaken, i believe this is the answer.
I have included another snippet. The only changes are those 2 lines, but i think it would be helpful for people to able to see the difference it makes.
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var canvas1 = document.getElementById("canvasX");
var ctxX = canvas1.getContext("2d");
var cw = canvas.width;
var ch = canvas.height;
var mapW = 200;
var mapH = 200;
var panX = 0;
var panY = 0;
var scaleFactor = 1.00;
drawTranslated();
function zoomIn() {
document.getElementById("zoomin").click(); {
scaleFactor *= 1.1;
drawTranslated();
};
};
function zoomOut() {
document.getElementById("zoomout").click(); {
scaleFactor /= 1.1;
drawTranslated();
};
};
function panUp() {
document.getElementById("panup").click(); {
panY -= 25;
drawTranslated();
};
};
function panDown() {
document.getElementById("pandown").click(); {
panY += 25;
drawTranslated();
};
};
function panLeft() {
document.getElementById("panleft").click(); {
panX -= 25;
drawTranslated();
};
};
function panRight() {
document.getElementById("panright").click(); {
panX += 25;
drawTranslated();
};
};
function drawTranslated() {
// canvas
ctx.clearRect(0, 0, cw, ch);
ctx.save();
ctx.translate(cw / 2, ch / 2);
ctx.scale(scaleFactor, scaleFactor);
ctx.translate(panX, panY);
ctx.fillStyle = "Green";
ctx.fillRect(mapW / -2, mapH / -2, mapW, mapH);
ctx.restore();
// canvasX
ctxX.clearRect(0, 0, cw, ch);
ctxX.save();
ctxX.translate(cw / 2, ch / 2);
ctxX.beginPath();
ctxX.moveTo(0, 25);
ctxX.lineTo(0, -25);
ctxX.moveTo(-25, 0);
ctxX.lineTo(25, 0);
ctxX.closePath();
ctxX.lineWidth = 1;
ctxX.strokeStyle = 'Black';
ctxX.stroke();
ctxX.restore();
};
#wrapper {
position: relative;
}
canvas {
position: absolute;
border: 1px solid Black;
}
<div id="wrapper">
<button id="zoomin" class="nav" title="Zoom In" onclick="zoomIn()">+</button>
<button id="zoomout" class="nav" title="Zoom Out" onclick="zoomOut()">−</button>
<button id="panup" class="nav" title="Up" onclick="panUp()">⇧</button>
<button id="pandown" class="nav" title="Down" onclick="panDown()">⇩</button>
<button id="panleft" class="nav" title="Left" onclick="panLeft()">⇦</button>
<button id="panright" class="nav" title="Right" onclick="panRight()">⇨</button>
</div>
<div id="wrapper">
<canvas id="canvas" width="400" height="400"></canvas>
<canvas id="canvasX" width="400" height="400"></canvas>
</div>
There surely is a better way but in Fabric.js you can do
canvas.zoomToPoint(new fabric.Point(canvas.width / 2, canvas.height / 2), canvas.getZoom() / ZOOM_PERCENT);
See more here Canvas
For a more pure solution, you can also try translating the context by half the canvas size using
ctx.translate()
A fiddle that might help
http://jsfiddle.net/m1erickson/QEuw4/
I'm trying to make a canvas of squers and rectangles that appear randomly, the amount of them is the users choice. after they input the numbers of eace of them, press a button-it should appear on the canvas. in my code it does not happen, and i cant understand why! making me crazy here. I'm obviously missing something here, and i guess its a very stupid thing.
function draw() {
var drawing = document.getElementById("canvas");
var context = drawing.getContext("2d");
saveImage();
}
//save the user input to use it later
var numOfRect = parseInt(document.getElementById("inSquer").value);
var numOfCirc = parseInt(document.getElementById("inCircle").value);
//This function will draw on the canvas
function paint(numOfRect, numOfCirc) {
for (var makeIt = 0; makeIt < numOfRect; makeIt++) {
makeRect(drawing, context);
makeCircle(drawing, context);
}
}
//This function draw the circles
function makeCircle(drawing, context) {
var radius = Math.floor(Math.random() * 80);
var x = Math.floor(Math.random() * canvas.width);
var y = Math.floor(Math.random() * canvas.height);
context.beginPath();
context.arc(x, y, radius, 0, 2 * Math.PI);
context.fillStyle = "blue";
context.fill();
}
//This function draw the squers
function makeRect(drawing, context) {
var w = Math.floor(Math.random() * 50);
var x = Math.floor(Math.random() * canvas.width);
var y = Math.floor(Math.random() * canvas.height);
context.fillStyle = "yellow";
context.fillRect(x, y, w, w);
}
//function to save the canvas as an image
function saveImage() {
var canvas = document.getElementById("canvas");
canvas.onclick = function() {
window.location = canvas.toDataURL("image/png");
};
}
#canvas {
margin-left: 150px;
border: 1px solid black;
}
<html>
<head>
<script src="js.js">
</script>
<link href="design.css" rel="stylesheet" />
</head>
<body onload="draw()">
<canvas id="canvas" width="1200" height="750"></canvas>
</br>
</br>
<span>
How many Circles do you want?
<input id="inCircle"></input>
</span>
</br>
How many Squers do you want?
<input id="inSquer"></input>
</br>
<button id="creat" onclick="paint()">Creat My Work</button>
</body>
</html>
paint(numOfRect, numOfCirc) wants 2 parameters, but <button id="creat" onclick="paint()">Creat My Work</button> is not giving any.
Also
var numOfRect = parseInt(document.getElementById("inSquer").value);
var numOfCirc = parseInt(document.getElementById("inCircle").value);
does not exactly do anything, as the values are empty when that code runs.
Try changing the paint function like so:
function paint()
{
var numOfRect = parseInt(document.getElementById("inSquer").value);
var numOfCirc = parseInt(document.getElementById("inCircle").value);
for (var makeIt = 0; makeIt < numOfRect; makeIt++)
{
makeRect(drawing, context);
makeCircle(drawing, context);
}
}
Please consider the following snippet.
First of all, your paint() function was missing two arguments. Apart from that, I would recommend to define all the variables on top of your script, so it's easier to keep track.
I have added a few comments in the code to highlight the changes.
Also I have removed a few redundant DOM interactions.
// Wait for DOM to be loaded.
document.addEventListener("DOMContentLoaded", function(event) {
// Keep references to elements, so we could interact with them later.
var drawing = document.getElementById("canvas");
var context = drawing.getContext("2d");
var inSquer = document.getElementById("inSquer");
var inCircle = document.getElementById("inCircle");
var button = document.getElementById("creat");
// Attach event listeners to the button and canvas element.
button.addEventListener("click", function() {
// Retrieve values from input fields every time you click.
paint(parseInt(inSquer.value), parseInt(inCircle.value));
});
drawing.addEventListener("click", function() {
saveImage();
});
// Function to save the canvas as an image.
function saveImage() {
window.location = drawing.toDataURL("image/png");
}
// This function will draw on the canvas.
function paint(numOfRect, numOfCirc) {
for (var makeIt = 0; makeIt < numOfRect; makeIt++) {
makeRect(drawing, context);
makeCircle(drawing, context);
}
}
// This function draw the circles.
function makeCircle(drawing, context) {
var radius = Math.floor(Math.random() * 80);
var x = Math.floor(Math.random() * canvas.width);
var y = Math.floor(Math.random() * canvas.height);
context.beginPath();
context.arc(x, y, radius, 0, 2 * Math.PI);
context.fillStyle = "blue";
context.fill();
}
// This function draw the squers.
function makeRect(drawing, context) {
var w = Math.floor(Math.random() * 50);
var x = Math.floor(Math.random() * canvas.width);
var y = Math.floor(Math.random() * canvas.height);
context.fillStyle = "yellow";
context.fillRect(x, y, w, w);
}
});
#canvas {
margin-left: 150px;
border: 1px solid black;
}
<html>
<head>
</head>
<body>
<canvas id="canvas" width="1200" height="750"></canvas>
<br/>
<br/>
<span>
How many Circles do you want?
<input id="inCircle" />
</span>
<br/>How many Squers do you want?
<input id="inSquer" />
<br/>
<button id="creat">Creat My Work</button>
</body>
</html>