I want to create several moving circles in Canvas in Javascript - javascript

I want make aimbooster. (http://www.aimbooster.com/)
I don't know how to make several circles that change in size at the same time.
My drawing process is...
Create a circle.
Draw a circle changing its size.
Reset the x- and y-coordinates when a circle is clicked.
Repeat this process.
The way I've tried to solve this problem is...
I tried to combine the draw function and the CircleForm function into a class and use a repeat statement.
I keep getting errors.
How do you make multiple circles?
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
// canvas maximum, minimum size
var max_x = 610,
min_x = 30,
min_y = 30,
max_y = 466;
// Initial Circle State
var x = 200,
y = 200,
r = 1,
startAngle = 0,
endAngle = Math.PI*2;
var moving;
var inc = true;
// -------------------------------------------------------------------
class Ball {
move(){
moving = setInterval(draw, 1);
}
stop(){
clearInterval(moving);
}
position(){
x = Math.floor(Math.random() * ((max_x) - (min_x))+min_x);
y = Math.floor(Math.random() * ((max_y) - (min_y))+min_y);
}
first_size(){
r = 1;
}
moving_size(){
var size_fast = 0.09; //0.09
if(inc){
r+=size_fast;
}else{
r-=size_fast;
}
}
}
let ball = new Ball();
// ---------------------------------------------------------------------------
function macroBall(){
ball.stop();
ball.position();
ball.first_size();
ball.move();
}
function CircleForm(x,y,r,startAngle, endAngle){
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
context.beginPath();
context.arc(x,y,r,startAngle, endAngle);
context.fillStyle = "orange";
context.fill();
context.stroke();
}
function draw(){
context.clearRect(0,0,canvas.width,canvas.height);
CircleForm(x,y,r,startAngle, endAngle);
rad_check(r);
ball.moving_size();
}
// Circle radius check
function rad_check(r){
if(r>=30){
inc = false;
}
if(r<=2){
inc = true;
}
}
canvas.addEventListener('mousedown', function(e) {
getCursorPosition(canvas, e)}
);
function getCursorPosition(canvas, event) {
const rect = canvas.getBoundingClientRect()
const xpos = event.clientX - rect.left
const ypos = event.clientY - rect.top
console.log("x: " + xpos + " y: " + ypos);
judgeHit(xpos,ypos);
}
// circle click event
function judgeHit(xpos, ypos,moving){
if(Math.abs(x-xpos)<=r && Math.abs(y-ypos)<=r){
macroBall();
}
}
ball.move();
*{
margin:0;
}
html, body{
height:100%;
}
body{
background:#376481 url(bg.jpg);
background-size: 100% 100%;
}
#page-container{
width:100%;
min-height:100%;
background:url(bg_stripes.png);
}
#column{
width: 640px;
margin-left: auto;
margin-right: auto;
display:grid;
}
#top{
height:80px;
}
.nav{
height:20px;
background-color:#CCCCCC;
}
.nav ul{
padding:0px;
margin-left:220px;
text-align: center;
}
.nav ul li{
font-size:10pt;
list-style:none;
float:left
}
.nav ul li a{
text-decoration:none;
color:#4477BB;
}
#myCanvas{
background-color:white;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Aim_Boost</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div id="page-container">
<div id="top"></div>
<div id="column">
<img src="header.png" style="width: 640px; height: 116px;" alt="AimBooster">
<div id="page">
<div class="nav">
<ul>
<li>Play</li>
<li> • News</li>
<li> • FAQ</li>
<li> • Feedback</li>
<li> • Donate</li>
</ul>
</div>
<div id="thi">
<canvas id="myCanvas" width="640px" height="497px"></canvas>
</div>
</div>
</div>
</div>
<script src="javas.js"></script>
</body>
</html>

You will need to add a constructor() method to the class to start. Read about it here developer.mozilla.org. Once you have that you can use the constructor to assign the objects properties.
Push all of the objects to any array and then iterate over them to animate. This a a very basic example showing how to create multiple circles. You can also create them without a loop.
let ball1 = new Ball();
let ball2 = new Ball();
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
let balls = [];
var inc = true;
class Ball {
constructor() {
this.x = Math.random() * canvas.width;
this.y = Math.random() * canvas.height;
this.r = 4;
this.c = "orange";
this.speed = 0.5;
}
draw() {
context.beginPath();
context.arc(this.x, this.y, this.r, 0, Math.PI * 2);
context.fillStyle = this.c;
context.fill();
context.stroke();
}
grow() {
if (inc) {
this.r += this.speed;
} else {
this.r -= this.speed;
}
}
incCheck() {
if (this.r >= 30) {
inc = false;
} else if (this.r < 2) {
inc = true;
}
}
}
function createBalls() {
for (let i = 0; i < 50; i++) {
balls.push(new Ball());
}
}
createBalls();
function drawBalls() {
for (let i = 0; i < balls.length; i++) {
balls[i].draw();
balls[i].grow();
balls[i].incCheck();
}
}
setInterval(() => {
context.clearRect(0, 0, canvas.width, canvas.height);
drawBalls()
}, 50)
*{
margin:0;
}
html, body{
height:100%;
}
body{
background:#376481 url(bg.jpg);
background-size: 100% 100%;
}
#page-container{
width:100%;
min-height:100%;
background:url(bg_stripes.png);
}
#column{
width: 640px;
margin-left: auto;
margin-right: auto;
display:grid;
}
#top{
height:80px;
}
.nav{
height:20px;
background-color:#CCCCCC;
}
.nav ul{
padding:0px;
margin-left:220px;
text-align: center;
}
.nav ul li{
font-size:10pt;
list-style:none;
float:left
}
.nav ul li a{
text-decoration:none;
color:#4477BB;
}
#myCanvas{
background-color:white;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Aim_Boost</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div id="page-container">
<div id="top"></div>
<div id="column">
<img src="header.png" style="width: 640px; height: 116px;" alt="AimBooster">
<div id="page">
<div class="nav">
<ul>
<li>Play</li>
<li> • News</li>
<li> • FAQ</li>
<li> • Feedback</li>
<li> • Donate</li>
</ul>
</div>
<div id="thi">
<canvas id="myCanvas" width="640px" height="497px"></canvas>
</div>
</div>
</div>
</div>
<script src="javas.js"></script>
</body>
</html>

Related

Why is my cursor and my line of draw are in diffrent sides?

I am attempting to create a drawing app in JS, however, whenever anything is drawn, it is positioned away from my cursor depending on where it is on the canvas, when I am on the furthest left/bottom side of the canvas, you can draw where your cursor is, but the further right/up I move, the more the brush begins to "drift" and go further than where my cursor is.
const canvas = document.getElementById("canvas");
const increaseBtn = document.getElementById("increase");
const decreaseBtn = document.getElementById("decrease");
const sizeEl = document.getElementById("size");
const colorEl = document.getElementById("color");
const clearEl = document.getElementById("clear");
//Core Drawing Functionality (with some research)
const ctx = canvas.getContext("2d");
let size = 5;
let isPressed = false;
let color = "black";
let x;
let y;
let fakeSize = 1;
canvas.addEventListener("mousedown", (e) => {
isPressed = true;
x = e.offsetX;
y = e.offsetY;
});
canvas.addEventListener("mouseup", (e) => {
isPressed = false;
x = undefined;
y = undefined;
});
canvas.addEventListener("mousemove", (e) => {
if (isPressed) {
const x2 = e.offsetX;
const y2 = e.offsetY;
drawCircle(x2, y2);
drawLine(x, y, x2, y2);
x = x2;
y = y2;
}
});
function drawCircle(x, y) {
ctx.beginPath();
ctx.arc(x, y, size, 0, Math.PI * 2);
ctx.fillStyle = color;
ctx.fill();
}
function drawLine(x1, y1, x2, y2) {
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.strokeStyle = color;
ctx.lineWidth = size * 2;
ctx.stroke();
}
function updateSizeOnScreen() {
sizeEl.innerHTML = fakeSize;
}
increaseBtn.addEventListener("click", () => {
size += 5;
fakeSize++;
if (fakeSize > 10) {
fakeSize = 10;
}
if (size > 50) {
size = 50;
}
updateSizeOnScreen();
});
decreaseBtn.addEventListener("click", () => {
size -= 5;
fakeSize--;
if (fakeSize < 1) {
fakeSize = 1;
}
if (size < 5) {
size = 5;
}
updateSizeOnScreen();
});
colorEl.addEventListener("change", (e) => {
color = e.target.value;
});
clearEl.addEventListener("click", () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
});
//Eraser and Pencil Actions (my own algorithm)
const eraser = document.getElementById("eraser");
const pencil = document.getElementById("pencil");
eraser.addEventListener("click", () => {
localStorage.setItem("colorEl", JSON.stringify(color));
color = "#fff";
colorEl.disabled = true;
canvas.classList.add("eraseractive");
eraser.classList.add("eraseractive");
colorEl.classList.add("eraseractive");
canvas.classList.remove("pencilactive");
eraser.classList.remove("pencilactive");
colorEl.classList.remove("pencilactive");
});
pencil.addEventListener("click", () => {
JSON.parse(localStorage.getItem("colorEl"));
color = colorEl.value;
colorEl.disabled = false;
canvas.classList.remove("eraseractive");
eraser.classList.remove("eraseractive");
colorEl.classList.remove("eraseractive");
canvas.classList.add("pencilactive");
eraser.classList.add("pencilactive");
colorEl.classList.add("pencilactive");
});
// Dark/Light Mode
const darkMode = document.getElementById("darkMode");
const lightMode = document.getElementById("lightMode");
const toolbox = document.getElementById("toolbox");
darkMode.addEventListener("click", () => {
darkMode.classList.add("mode-active");
lightMode.classList.remove("mode-active");
lightMode.classList.add("rotate");
darkMode.classList.remove("rotate");
toolbox.style.backgroundColor = "#293462";
document.body.style.backgroundImage =
"url('/assets/images/darkModeBackground.svg')";
document.body.style.backgroundSize = "1920px 1080px";
canvas.style.borderColor = "#293462";
toolbox.style.borderColor = "#293462";
});
lightMode.addEventListener("click", () => {
lightMode.classList.add("mode-active");
darkMode.classList.remove("mode-active");
darkMode.classList.add("rotate");
lightMode.classList.remove("rotate");
toolbox.style.backgroundColor = "#293462";
document.body.style.backgroundImage =
"url('/assets/images/lightModeBackground.svg')";
document.body.style.backgroundSize = "1920px 1080px";
canvas.style.borderColor = "#293462";
toolbox.style.borderColor = "#293462";
});
* {
box-sizing: border-box;
font-size: 20px !important;
}
body {
background: url("https://drawing-app-green.vercel.app/assets/images/lightModeBackground.svg");
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
margin: 0;
position: relative;
max-height: 100vh;
overflow: hidden;
}
::selection {
background: transparent;
}
::-moz-selection {
background: transparent;
}
.mode {
display: flex;
position: absolute;
top: 10px;
right: 25px;
cursor: pointer;
}
.light-mode {
color: yellow;
}
.dark-mode {
color: #16213e;
}
.container {
display: flex;
flex-direction: column;
max-width: 1200px;
width: 100%;
max-height: 600px;
height: 100%;
}
canvas {
display: flex;
border: 2px solid #293462;
cursor: url("https://drawing-app-green.vercel.app/assets/images/pencilCursor.png") 2 48, pointer;
background-color: #fff;
margin-top: 3rem;
width: 100%;
height: 600px;
}
.toolbox {
background-color: #293462;
border: 1px solid #293462;
display: flex;
width: 100%;
align-items: center;
justify-content: center;
padding: 0.2rem;
}
.toolbox > * {
background-color: #fff;
border: none;
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 2rem;
height: 30px;
width: 30px;
margin: 0.25rem;
padding: 0.25rem;
cursor: pointer;
}
.toolbox > *:last-child {
margin-left: auto;
}
canvas.eraseractive {
cursor: url("https://drawing-app-green.vercel.app/assets/images/eraserCursor.png") 2 48, pointer;
}
#color.eraseractive {
cursor: not-allowed;
}
canvas.pencilactive {
cursor: url("https://drawing-app-green.vercel.app/assets/images/pencilCursor.png") 2 48, pointer;
}
.mode-active {
visibility: hidden;
}
.rotate {
transform: rotate(360deg);
transition: transform 1s linear;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Drawing App</title>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css"
integrity="sha512-xh6O/CkQoPOWDdYTDqeRdPCVd1SpvCA9XXcUnZS2FmJNp1coAFzvtCN9BmamE+4aHK8yyUHUSCcJHgXloTyT2A=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
/>
</head>
<body>
<i class="fa-solid fa-moon dark-mode fa-2x mode" id="darkMode"></i>
<i
class="fa-solid fa-sun light-mode fa-2x mode mode-active"
id="lightMode"
></i>
<div class="container">
<canvas id="canvas" width="1024" height="600"></canvas>
<div class="toolbox" id="toolbox">
<button id="decrease">-</button>
<span id="size">1</span>
<button id="increase">+</button>
<input type="color" id="color" />
<button id="pencil">
<img src="assets/images/pencilCursor.png" alt="" />
</button>
<button id="eraser">
<img src="assets/images/eraserCursor.png" alt="" />
</button>
<button id="clear">X</button>
</div>
</div>
<script src="assets/js/script.js"></script>
</body>
</html>
Your problem is that your canvas dimentions don't match with the dimentions of the HTML element that contains it. You see: your canvas has a fixed width="" and height="" attributes set. But in your HTML your canvas element has a width of 100%. So that means that the container vairies in dimentions but the canvas inside it not. This result in the canvas trying to resize to show inside the container thus giving you issues with calculating exacly what pixel you are clicking.
You have two options:
Option 1: calculate your click position taking into account canvas deformation
If you want your canvas to resize, then calculate the real position using a simple ratio formula. If for example your canvas has a width of 100 but right now its container is 10px wide, then if you click on pixel 5 you expect a dot to be drawn at pixel 50. In other words if your canvas is smaller by a factor of 10 then you need to multiply your position by a factor of 10.
In your code it would look something like this:
// this is your same code in lines 33 ana34 but see that I added a multiplication by the ratio between the canvas size and the canvas container
const x2 = e.offsetX * (canvas.width / ctx.canvas.getBoundingClientRect().width);
const y2 = e.offsetY * (canvas.height / ctx.canvas.getBoundingClientRect().height);
Option #2: Dont allow your canvas to deform
Remove the container class, and remove the width:100% from your canvas css. Your canvas will overflow and cause a scrollbar but the positions will be calculated properly with your code.

How can I draw JavaScript graphical elements on top of custom image?

I have some Javascript drawing random square elements in the DOM. I have a gif (Image) I want these elements to appear over but they keep appearing underneath the gif. I tried defining z-depth and layout parameters to move these elements on top of the image here, but this produced no difference.
Any assistance in achieving the result (drawing elements onclick, on top of this gif) would be much appreciated.
I ultimately want to draw various other images over this image onclick, restricted to this particular area on top of the gif. If someone can suggest a solution to this as well I would be very much grateful!
(Code features some unused elements from my past attempts)
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="div.css" />
</head>
<body>
<div style="cursor: pointer;" id="boxy" >
<img src="bg.gif" alt="unfinished bingo card" onclick="create()" />
</div>
</div>
<script>
var body = document.getElementsByTagName("body")[0];
var canvas = document.createElement("canvas");
canvas.height = 1300;
canvas.width = 1300;
var context = canvas.getContext("2d");
body.appendChild(canvas);
var rects = [];
function create() {
// Opacity
context.globalAlpha = 0.7;
var color = '#' + Math.round(0xffffff * Math.random()).toString(16);
context.fillStyle = color;
//Each rectangle's size is (20 ~ 100, 20 ~ 100)
var coordx = Math.random() * canvas.width;
var coordy = Math.random() * canvas.width;
var width = Math.random() * 80 + 20;
var height = Math.random() * 80 + 20;
var rect = {
x: coordx,
y: coordy,
w: width,
h: height
}
var ok = true;
rects.forEach(function (item) {
if (isCollide(rect, item)) {
console.log("collide");
ok = false;
} else {
console.log("no collision");
}
})
if (ok) {
context.fillRect(coordx, coordy, width, height);
rects.push(rect);
} else {
console.log('rect dropped');
}
console.log(rects);
}
function isCollide(a, b) {
return !(
((a.y + a.h) < (b.y)) ||
(a.y > (b.y + b.h)) ||
((a.x + a.w) < b.x) ||
(a.x > (b.x + b.w))
);
}
document.getElementById('boxy').addEventListener('click', create);
document.getElementById('canvas').style.position = "relative";
document.getElementById('canvas').style.zIndex = "10";
</script>
</body>
</html>
#my-div {
width: 1300x;
height: 1300px;
z-index: -1;
}
a.fill-div {
display: block;
height: 100%;
width: 100%;
text-decoration: none;
}
#boxy {
display: inline-block;
height: 100%;
width: 100%;
text-decoration: none;
z-index: -1;
}
.canvas {
display: inline-block;
height: 100%;
width: 100%;
text-decoration: none;
z-index: 10;
}
You have to use position:absolute; to take it out of the html flow.
Now anything added after the image will be placed like the image was never there.
img {
width: 100vw;
height: 100vh;
position: absolute;
top: 0;
left: 0;
z-index: -10;
}
div {
font-size: 2rem;
color: white;
}
<img src="https://images.unsplash.com/photo-1664273107076-b6d1fbfb973b?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1171&q=80">
<div>Hello i am on top of the image
</div>

How can I download html5 canvas drawing as image

I just recently uploaded my code files to a server. My website is a simple html5 drawing application where users are able to draw freely. I have this part done fine, however I am looking to implement a download button that simply downloads whatever the user has drawn as an image directly to their device i.e. phone, table, desktop. I have been looking for solutions to this for hours now and cant find anything. Is it a problem with my server? or anything like that? any help would be much appreciated. Below is my code
<!DOCTYPE html>
<html>
<head>
<title>Elemental</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style type="text/css">
#import url('https://fonts.googleapis.com/css?family=Montserrat+Alternates');
#media screen and (max-width: 425px){
html,body{
overflow-x: hidden;
width: 100%;
margin: 0;
}
canvas { border: 3px solid #0BF446;
border-radius: 15px 0px 15px 0px;
display: block;
margin: 0 auto;
margin-top: 35px;
background-color:#313131;
position: relative;}
#download{background-color:#04A12B ;
border-radius: 0 15px 0 15px;
padding: 20px 40px;
margin: 0 auto;
display: block;
font-size: 14px;
margin-top: 35px;
color: white;
font-family: 'Montserrat Alternates', sans-serif;}
#clearbutton{background-color:#04A12B ;
border-radius: 0 15px 0 15px;
padding: 20px;
margin: 0 auto;
display: block;
font-size: 14px;
color: white;
font-family: 'Montserrat Alternates', sans-serif;
margin-top: 35px;}
</style>
</head>
<body>
<body onload="init()">
<img src="minilogo.png" id ="logo">
<canvas id="c" width="350px" height="350px"></canvas>
<button id = "download">Download</button>
<input type = "submit" value="Clear Sketchpad" id="clearbutton" onclick="clearCanvas(canvas,ctx);">
<script>
function init() {
// Get the specific canvas element from the HTML document
canvas = document.getElementById('c');
}
function midPointBtw(p1, p2) {
return {
x: p1.x + (p2.x - p1.x) / 2,
y: p1.y + (p2.y - p1.y) / 2
};
}
function getPattern() {
return ctx.createPattern(img, 'repeat');
}
var el = document.getElementById('c');
var ctx = el.getContext('2d');
ctx.lineWidth = 30;
ctx.lineJoin = ctx.lineCap = 'round';
var img = new Image;
img.onload = function() {
ctx.strokeStyle = getPattern();
};
img.src = "https://i.postimg.cc/rF2R0GRY/dick2.png";
var isDrawing, points = [];
var getXY = function(e) {
var source = e.touches ? e.touches[0] : e;
return {
x: source.clientX,
y: source.clientY
};
};
var startDrawing = function(e) {
isDrawing = true;
points.push(getXY(e));
event.preventDefault();
};
var keepDrawing = function(e) {
if (!isDrawing) return;
points.push(getXY(e));
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
var p1 = points[0];
var p2 = points[1];
ctx.moveTo(p1.x, p1.y);
for (var i = 1, len = points.length; i < len; i++) {
var midPoint = midPointBtw(p1, p2);
ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y);
p1 = points[i];
p2 = points[i + 1];
}
ctx.lineTo(p1.x, p1.y);
ctx.stroke();
event.preventDefault();
};
var stopDrawing = function() {
isDrawing = false;
points = [];
};
el.addEventListener('touchstart', startDrawing);
el.addEventListener('mousedown', startDrawing);
el.addEventListener('touchmove', keepDrawing);
el.addEventListener('mousemove', keepDrawing);
el.addEventListener('touchend', stopDrawing);
el.addEventListener('mouseup', stopDrawing);
function clearCanvas(canvas,ctx) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath()
}
</script>
</body>
</html>
You can use the Canvas#toDataURL method to generate a URL containing all the data of the canvas's current image. This can then be used in place of any URL -- a link's href, a window.open, etc. For a download link, you can use the download attribute on a link, which is an HTML5 addition. The value of the download attribute is the filename that will be used as the default save filename.
So to put all that together:
<a id='downloadLink' download='myDrawing.png'>Download Image</a>
<script>
function createDownload() {
const downloadURL = document.getElementById('c').toDataURL();
document.getElementById('downloadLink').href = downloadURL;
}
</script>

Reverse image at end of animation

I'm trying to re-create the bouncing ball effect but with an arrow.
When the arrow gets to the right wall it points left and come back until it reach the left wall and then point right again. Within a continuous loop.
I'm fairly new to JS and animation. Any help would be appreciated.
So far I have the arrow work fine back and forth, but doesn't reverse/flip when hitting the wall.
Thank you.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<canvas id="canvas" width="500" height="400" style="border: solid; border-color: black;"></canvas>
<script type="text/javascript">
window.onload = function () {
var context;
var dx = 1;
var w3;
var ctx;
var img;
function setCanvas() {
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
ctx = canvas.getContext('2d');
img = new Image();
img.onload = function (e) {
draw();
}
img.src = '/rightArrow2.png';
w3 = img.width;
draw();
}
}
var startPos = 200;
var endPos = 100;
var x = 100;
var y = 10;
function draw() {
ctx.clearRect(0, 0, 500, 500);
ctx.drawImage(img, x, y);
x += dx;
if (x < endPos || x > startPos) {
ctx.clearRect(0, 0, 500, 500);
var canvas = document.getElementById('canvas');
ctx2 = canvas.getContext('2d');
var img2 = new Image();
img2.src = document.getElementById("canvas").toDataURL();
var w4 = img2.width;
ctx2.save();
ctx2.translate(-w4, 0);
ctx2.scale(-1, 1);
ctx2.drawImage(img2, x , y);
ctx2.restore();
dx = -dx;
}
setTimeout(draw, 15);
}
setCanvas();
}
</script>
</body>
</html>
var context;
var dx= 4;
var dy=4;
var y=150;
var x=10;
function draw(){
context= myCanvas.getContext('2d');
context.clearRect(0,0,300,300);
context.beginPath();
context.fillStyle="#0000ff";
context.arc(x,y,20,0,Math.PI*2,true);
context.closePath();
context.fill();
if( x<0 || x>300)
dx=-dx;
if( y<0 || y>300)
dy=-dy;
x+=dx;
y+=dy;
}
setInterval(draw,10);
<!--
body { background-color:#ededed; font:normal 12px/18px Arial, Helvetica, sans-serif; }
#container { width:600px; margin:0 auto; }
#myCanvas { background:#fff; border:1px solid #cbcbcb; }
#nav { display:block; width:100%; text-align:center; }
#nav li { display:block; font-weight:bold; line-height:21px; text-shadow:1px 1px 1px #fff; width:100px; height:21px; padding:5px; margin:0 10px; background:#e0e0e0; border:1px solid #ccc; -moz-border-radius:4px;-webkit-border-radius:4px; border-radius:4px; float:left; }
#nav li a { color:#000; display:block; text-decoration:none; width:100%; height:100%; }
-->
<div id="container">
<canvas id="myCanvas" width="300" height="300"></canvas>
<ul id="nav">
<li>View Tutorial</li>
<li>Post Comment</li>
</ul>
</div>
Try replacing your draw() function with this:
function draw() {
ctx.clearRect(0, 0, 500, 500);
if (dx > 0) {
ctx.drawImage(img, x, y);
}
else {
ctx.save();
ctx.translate(x + img.width, y);
ctx.scale(-1, 1);
ctx.drawImage(img, 0, 0);
ctx.restore();
}
x += dx;
if (x < endPos || x > startPos) {
dx = -dx;
}
setTimeout(draw, 15);
}

HTML5 Canvas y-height not correct

So I'm just trying to make a simple animated HMTL canvas with an animated block that moves around the canvas using WASD. I initially noticed that painting a rectangle on the canvas of size 5,5 made what looked like a rectangle of size 5,10. When testing my redrawing function and printing to the console the x and y location of the element in the canvas, I noticed that my rectangle can go from 1-300 in the X direction, but only 1-150 in the Y direction. This happens even though the canvas is styled as 300,300. Can anyone figure out if I've done something silly?
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<script type="text/javascript" src="script.js" defer></script>
</head>
<body>
<div class="text-holder holder" id="instruction-holder">
<p class="text" id="instruction">Use WASD to navigate around the viewer</p>
</div>
<div class="holder" id="canvas-holder">
<canvas id="canvas"></canvas>
</div>
</body>
</html>
and the css
#canvas {
width: 300px;
height:300px;
margin-left: auto;
margin-right: auto;
display: block;
border-style: solid;
border-color: grey;
border-radius: 1px;
}
.holder {
display: block;
margin-left: auto;
margin-right: auto;
text-align: center;
}
and the js
var UP = "87", DOWN = "83", LEFT = "65", RIGHT = "68", X = 10, Y = 5, XSIZE = 10, YSIZE = 5;
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
var xPos, yPos;
window.addEventListener("load",init);
document.addEventListener('keydown',move);
function init() {
xPos = 1;
yPos = 1;
ctx.fillStyle = "black";
ctx.fillRect(xPos,yPos,XSIZE,YSIZE);
}
function clear() {
ctx.clearRect(0,0,300,300);
}
function reDraw(delX, delY) {
console.log(yPos+delY + " " + (xPos+delX));
if (xPos+delX > 0 && xPos+delX < 300 &&
yPos+delY > 0 && yPos+delY < 150) {
clear();
ctx.fillStyle = "black";
xPos = xPos+delX;
yPos = yPos+delY;
ctx.fillRect(xPos,yPos,XSIZE,YSIZE);
}
}
function move(ev) {
var delX, delY;
var key = ev.keyCode;
if (key == UP) {
delX = 0;
delY = -Y;
} else if (key == DOWN) {
delX = 0;
delY = Y;
} else if (key == LEFT) {
delX = -X;
delY = 0;
} else if (key == RIGHT) {
delX = X;
delY = 0;
}
if (delX != undefined && delY != undefined) {
reDraw(delX, delY);
}
}
You have to set the size of canvas explicitly or it will use the default size of 300x150 (CSS only scales the element, not the bitmap - the bitmap of 300x150 is stretched to fit what you see on screen by the CSS rule, but the bitmap will remain the same size internally):
<canvas id="canvas" width=300 height=300></canvas>
Then just remove these:
#canvas {
/* width: 300px; */
/* height:300px; */
...

Categories

Resources