So, in my car-parking based webgame, I want it so the car goes over the parking lines in the html canvas, but nothing is working. Obviously, I tried putting the car drawing in javascript before the parking lot, but that doesn't work. I have the game at https://parkingmaster.w3spaces.com try parking over the lines, they'll go over the car.
JavaScript:
ctx = canvas.getContext('2d'),
last = performance.now(),
x = 0,
animate;
var y = 20;
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.rect(x, y, 110,65);
ctx.rect(x + 5, y + 58, 30,10);
ctx.rect(x + 75, y + 58, 30,10)
ctx.rect(x + 5, y - 3, 30,10);
ctx.rect(x + 75, y -3, 30,10)
ctx.fillStyle = "#000000";
ctx.fill();
x += 5;
animate = requestAnimationFrame(draw);
if (x > 500) {
GameOver();
}
parkinglot(draw);
document.getElementById("speedbar").innerHTML = '5';
};
var canvas = document.getElementById('myCanvas'),
ctx = canvas.getContext('2d'),
last = performance.now(),
x = 0,
animate;
var y = 20;
function mouseRightDown(draw) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.rect(x, y, 110,65);
ctx.rect(x + 5, y + 58, 30,10);
ctx.rect(x + 75, y + 58, 30,10)
ctx.rect(x + 5, y - 3, 30,10);
ctx.rect(x + 75, y -3, 30,10)
ctx.fillStyle = "#000000";
ctx.fill();
y += 1.5;
x += 0.3;
if (y > canvas.height - 66) {
GameOver();
}
animate2 = requestAnimationFrame(mouseRightDown);
parkinglot(draw);
}
var canvas = document.getElementById('myCanvas'),
ctx = canvas.getContext('2d'),
last = performance.now(),
x = 0,
animate;
var y = 20;
function mouseLeftDown(draw) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.rect(x, y, 110,65);
ctx.rect(x + 5, y + 58, 30,10);
ctx.rect(x + 75, y + 58, 30,10)
ctx.rect(x + 5, y - 3, 30,10);
ctx.rect(x + 75, y -3, 30,10)
ctx.fillStyle = "#000000";
ctx.fill();
y += -1.5;
x += 0.3;
if (y < -1) {
GameOver();
}
animate3 = requestAnimationFrame(mouseLeftDown);
parkinglot(draw);
}
var canvas = document.getElementById('myCanvas'),
ctx = canvas.getContext('2d'),
last = performance.now(),
x = 0,
animate;
var y = 20;
function mouseReverseDown(draw) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.rect(x, y, 110,65);
ctx.rect(x + 5, y + 58, 30,10);
ctx.rect(x + 75, y + 58, 30,10)
ctx.rect(x + 5, y - 3, 30,10);
ctx.rect(x + 75, y -3, 30,10)
ctx.fillStyle = "#000000";
ctx.fill();
x += -4;
if (x < -2) {
GameOver();
}
document.getElementById("speedbar").innerHTML = '4';
animate4 = requestAnimationFrame(mouseReverseDown);
parkinglot(draw);
}
function GameOver() {
var gameOverAlert = alert("Game Over");
var gameOverAlert = false;
document.getElementById("status-button-bar").innerHTML = '';
var gameOverAlert = true;
if (gameOverAlert == true); {
var gameOverAlert = false;
}
window.location.href = "https://parkingmaster.w3spaces.com/index.html?bypass-cache=1624983081";
document.getElementById("hidebuttons").innerHTML = '';
}
var canvas = document.getElementById('myCanvas'),
ctx = canvas.getContext('2d');
function parkinglot(draw) {
ctx.fillStyle = '#fad201';
ctx.fillRect(590, 0, 10, canvas.height);
ctx.fillRect(450, 0, 140, 10);
ctx.fillRect(450, 90, 140, 10);
ctx.fillRect(450, 180, 140, 10);
// outline
ctx.fillStyle = '#00FF00';
ctx.fillRect(450, 270, 20, 10);
ctx.fillRect(480, 270, 20, 10);
ctx.fillRect(510, 270, 20, 10);
ctx.fillRect(540, 270, 20, 10);
ctx.fillRect(570, 270, 20, 10);
ctx.fillStyle = '#00FF00';
ctx.fillRect(450, 360, 20, 10);
ctx.fillRect(480, 360, 20, 10);
ctx.fillRect(510, 360, 20, 10);
ctx.fillRect(540, 360, 20, 10);
ctx.fillRect(570, 360, 20, 10);
}
var canvas = document.getElementById('myCanvas'),
ctx = canvas.getContext('2d');
function cars(draw) {
ctx.fillStyle = '#000000';
ctx.fillRect(0, 20, 110,65);
ctx.fillRect(5, 78, 30,10);
ctx.fillRect(75, 78, 30,10)
ctx.fillRect(5, 17, 30,10);
ctx.fillRect(75, 17, 30,10)
}
Your code ends with:
cars(draw);
parkinglot(draw);
So you're drawing the cars, and then the parking-lot.
Canvas draws new elements on op of existing elements, therefore your parking-lot will be placed above the car drawings.
So'll you'll probably just need to change the order of drawing:
parkinglot(draw);
cars(draw);
Example were we draw a red line, and then a green one. You'll see that the last drawn line will be visible in the intersection:
let c = document.getElementsByTagName('canvas')[0];
c.width = 200;
c.height = 200;
let x = c.getContext('2d');
x.lineWidth = 5;
// Red
x.beginPath();
x.moveTo(0, 0);
x.lineTo(200, 200);
x.strokeStyle = "#ff5500";
x.stroke();
// Green
x.beginPath();
x.moveTo(200, 0);
x.lineTo(0, 200);
x.strokeStyle = "#008000";
x.stroke();
canvas { border: 1px solid black; }
<canvas></canvas>
Related
I'm trying to create simple animation to take the moon that I have drawn behind the clouds and allow users to move it across the x axis in the canvas. I have seen where others have done this with rectangles, and I have seen where their code seems basic enough for my inexperience to follow... but I'm struggling a bit with my code.
Every time I put code in that I think will work, it wipes out the canvas... which means I have placement and structural issues... but I'm having trouble figuring out where and how.
Can someone help me figure out how to animate my drawMoon so that it will move across the x axis when the left and right arrow keys are used?
NOTE I have tried using event listeners for keydown and keyup, but I'm sure I'm doing it wrong.
Attaching code that has nothing included so that you all have the base code without the animation attempt.
Any help is appreciated.
UPDATE I think I broke it more..... thoughts?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Howling at the Moon</title>
</head>
<body onload="init();">
<canvas id="myCanvas" width="900" height="900">Your browser does not support the canvas tag.</canvas>
<script type="text/javascript">
var canvas, ctx;
var moonx = 0;
var moony = 0;
var moonAngle = 0;
var incrementX = 0;
function init() {
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
window.addEventListener("keydown", handleKeydown, false);
window.addEventListener("keyup", handleKeyup, false);
drawMonster(260, 260);
drawMoon(100, 100);
drawCloud(150, 175);
requestId = requestAnimationFrame(animationLoop);
function handleKeydown(evt) {
if (evt.keyCode === 37) {
incrementX = -1;
} else if (evt.keyCode === 39) {
incrementX = 1;
}
}
function handleKeyup(evt) {
incrementX = 0;
}
function animationLoop() {
context.globalCompositeOperation = 'destination-out'
}
drawMoon(moonx, moony, moonAngle, "green", "yellow");
moonx += incrementX;
requestId = requestAnimationFrame(animationLoop);
}
function drawMonster(x, y) {
ctx.save();
ctx.beginPath();
ctx.arc(740, 750, 175, 0, Math.PI / 0.5);
ctx.fillStyle = "lightgrey";
ctx.fill();
ctx.lineWidth = 3;
ctx.stroke();
//mouth1
ctx.fillStyle = "black";
ctx.fillRect(x + 350, y + 550, 200, 20);
//mouth2
ctx.fillStyle = "black";
ctx.fillRect(x + 375, y + 540, 150, 20);
//mouth3
ctx.fillStyle = "black";
ctx.fillRect(x + 375, y + 560, 150, 20);
ctx.restore();
//eyes
addShadows2();
ctx.fillStyle = "lightslategrey";
ctx.fillRect(x + 350, y + 400, 40, 40);
ctx.fillRect(x + 450, y + 400, 40, 40);
//pupil
ctx.fillStyle = "black";
ctx.fillRect(x + 350, y + 400, 20, 20);
ctx.fillRect(x + 450, y + 400, 20, 20);
}
//moon
function drawMoon(moonx, moony) {
ctx.beginPath();
ctx.arc(100, 75, 150, 0, Math.PI / 0.5);
ctx.fillStyle = "lightgrey";
addShadows();
ctx.fill();
ctx.lineWidth = 3;
ctx.stroke();
}
//cloud
function drawCloud(x, y) {
ctx.beginPath();
ctx.arc(x, y, 60, Math.PI * 0.5, Math.PI * 1.5);
ctx.arc(x + 70, y - 60, 70, Math.PI * 1, Math.PI * 1.85);
ctx.arc(x + 152, y - 45, 50, Math.PI * 1.37, Math.PI * 1.91);
ctx.arc(x + 200, y, 60, Math.PI * 1.5, Math.PI * 0.5);
ctx.moveTo(x + 200, y + 60);
ctx.lineTo(x, y + 60);
ctx.strokeStyle = "#797874";
ctx.stroke();
ctx.fillStyle = "lightslategrey";
ctx.fill();
}
function addShadows() {
ctx.shadowColor = "beige"; // color
ctx.shadowBlur = 160; // blur level
ctx.shadowOffsetX = 15; // horizontal offset
ctx.shadowOffsetY = 15; // vertical offset
}
function addShadows2() {
ctx.shadowColor = "black";
ctx.shadowBlur = 40;
ctx.shadowOffsetX = 15;
ctx.shadowOffsetY = 10;
}
function addShadows3() {
ctx.shadowColor = "beige";
ctx.shadowBlur = 160;
ctx.shadowOffsetX = 10;
ctx.shadowOffsetY = 10;
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Howling at the Moon</title>
</head>
<body onload="init();">
<canvas id="myCanvas" width="900" height="900">Your browser does not support the canvas tag.</canvas>
<script type="text/javascript">
var canvas, ctx;
function init() {
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
window.addEventListener('keydown', handleKeydown, false);
window.addEventListener('keyup', handleKeyup, false);
drawMonster(260, 260);
drawMoon(100, 100);
drawCloud(150, 175);
function handleKeydown(evt) {
if (evt.keyCode === 37) {
//left key
incrementX = -1;
} else if (evt.keyCode === 39) {
// right key
incrementX = 1;
}
}
function drawMonster(x, y) {
ctx.save();
ctx.beginPath();
ctx.arc(740, 750, 175, 0, Math.PI / .5);
ctx.fillStyle = "lightgrey";
ctx.fill();
ctx.lineWidth = 3;
ctx.stroke();
//mouth1
ctx.fillStyle = 'black'
ctx.fillRect(x + 350, y + 550, 200, 20);
//mouth2
ctx.fillStyle = 'black'
ctx.fillRect(x + 375, y + 540, 150, 20);
//mouth3
ctx.fillStyle = 'black'
ctx.fillRect(x + 375, y + 560, 150, 20);
ctx.restore();
//eyes
addShadows2();
ctx.fillStyle = 'lightslategrey'
ctx.fillRect(x + 350, y + 400, 40, 40);
ctx.fillRect(x + 450, y + 400, 40, 40);
//pupil
ctx.fillStyle = 'black'
ctx.fillRect(x + 350, y + 400, 20, 20);
ctx.fillRect(x + 450, y + 400, 20, 20);
}
function animateMoon()
{
ctx.clearArc(0,0,canvas.width,canvas.height);
drawMoon(x,y);
requestId = requestAnimationFrame(animateMoon);
}
//moon
function drawMoon(x, y) {
ctx.beginPath();
ctx.arc(100, 75, 150, 0, Math.PI / .5);
ctx.fillStyle = "lightgrey";
addShadows();
ctx.fill();
ctx.lineWidth = 3;
ctx.stroke();
}
//cloud
function drawCloud(x, y) {
ctx.beginPath();
ctx.arc(x, y, 60, Math.PI * 0.5, Math.PI * 1.5);
ctx.arc(x + 70, y - 60, 70, Math.PI * 1, Math.PI * 1.85);
ctx.arc(x + 152, y - 45, 50, Math.PI * 1.37, Math.PI * 1.91);
ctx.arc(x + 200, y, 60, Math.PI * 1.5, Math.PI * 0.5);
ctx.moveTo(x + 200, y + 60);
ctx.lineTo(x, y + 60);
ctx.strokeStyle = "#797874";
ctx.stroke();
ctx.fillStyle = "lightslategrey";
ctx.fill();
}
function addShadows() {
ctx.shadowColor = "beige"; // color
ctx.shadowBlur = 160; // blur level
ctx.shadowOffsetX = 15; // horizontal offset
ctx.shadowOffsetY = 15; // vertical offset
}
function addShadows2() {
ctx.shadowColor = "black";
ctx.shadowBlur = 40;
ctx.shadowOffsetX = 15;
ctx.shadowOffsetY = 10;
}
function addShadows3() {
ctx.shadowColor = "beige";
ctx.shadowBlur = 160;
ctx.shadowOffsetX = 10;
ctx.shadowOffsetY = 10;
}
function start() {
// Start the animation loop, targets 60 frames/s
requestId = requestAnimationFrame(animationLoop);
}
function stop() {
if (requestId) {
cancelAnimationFrame(requestId);
}
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Howling at the Moon</title>
</head>
<body onload="init();">
<canvas id="myCanvas" width="900" height="900">Your browser does not support the canvas tag.</canvas>
<script type="text/javascript">
var canvas, ctx;
function init() {
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
window.addEventListener('keydown', handleKeydown, false);
window.addEventListener('keyup', handleKeyup, false);
drawMonster(260, 260);
drawMoon(100, 100);
drawCloud(150, 175);
function handleKeydown(evt) {
if (evt.keyCode === 37) {
//left key
incrementX = -1;
} else if (evt.keyCode === 39) {
// right key
incrementX = 1;
}
}
function drawMonster(x, y) {
ctx.save();
ctx.beginPath();
ctx.arc(740, 750, 175, 0, Math.PI / .5);
ctx.fillStyle = "lightgrey";
ctx.fill();
ctx.lineWidth = 3;
ctx.stroke();
//mouth1
ctx.fillStyle = 'black'
ctx.fillRect(x + 350, y + 550, 200, 20);
//mouth2
ctx.fillStyle = 'black'
ctx.fillRect(x + 375, y + 540, 150, 20);
//mouth3
ctx.fillStyle = 'black'
ctx.fillRect(x + 375, y + 560, 150, 20);
ctx.restore();
//eyes
addShadows2();
ctx.fillStyle = 'lightslategrey'
ctx.fillRect(x + 350, y + 400, 40, 40);
ctx.fillRect(x + 450, y + 400, 40, 40);
//pupil
ctx.fillStyle = 'black'
ctx.fillRect(x + 350, y + 400, 20, 20);
ctx.fillRect(x + 450, y + 400, 20, 20);
}
function animateMoon() {
ctx.clearArc(0, 0, canvas.width, canvas.height);
drawMoon(x, y);
requestId = requestAnimationFrame(animateMoon);
}
//moon
function drawMoon(x, y) {
ctx.beginPath();
ctx.arc(100, 75, 150, 0, Math.PI / .5);
ctx.fillStyle = "lightgrey";
addShadows();
ctx.fill();
ctx.lineWidth = 3;
ctx.stroke();
}
//cloud
function drawCloud(x, y) {
ctx.beginPath();
ctx.arc(x, y, 60, Math.PI * 0.5, Math.PI * 1.5);
ctx.arc(x + 70, y - 60, 70, Math.PI * 1, Math.PI * 1.85);
ctx.arc(x + 152, y - 45, 50, Math.PI * 1.37, Math.PI * 1.91);
ctx.arc(x + 200, y, 60, Math.PI * 1.5, Math.PI * 0.5);
ctx.moveTo(x + 200, y + 60);
ctx.lineTo(x, y + 60);
ctx.strokeStyle = "#797874";
ctx.stroke();
ctx.fillStyle = "lightslategrey";
ctx.fill();
}
function addShadows() {
ctx.shadowColor = "beige"; // color
ctx.shadowBlur = 160; // blur level
ctx.shadowOffsetX = 15; // horizontal offset
ctx.shadowOffsetY = 15; // vertical offset
}
function addShadows2() {
ctx.shadowColor = "black";
ctx.shadowBlur = 40;
ctx.shadowOffsetX = 15;
ctx.shadowOffsetY = 10;
}
function addShadows3() {
ctx.shadowColor = "beige";
ctx.shadowBlur = 160;
ctx.shadowOffsetX = 10;
ctx.shadowOffsetY = 10;
}
function start() {
// Start the animation loop, targets 60 frames/s
requestId = requestAnimationFrame(animationLoop);
}
function stop() {
if (requestId) {
cancelAnimationFrame(requestId);
}
}
</script>
</body>
</html>
There were several issues in your code and I'll share the changes I made to get the animation to work.
Errors
In your animationLoop, you referenced a variable named context which I believe you meant to reference ctx instead.
context.globalCompositeOperation = 'destination-out'
I can't say I've used this property of the CanvasRenderingContext2D, but I didn't notice any positive effects it produced for your code and the resulting animation. I first changed it to ctx.globalCompositeOperation and eventually removed it.
Another error was that you were declaring ctx and canvas in your init function even though you had variables declared outside the function. I opted to remove the declaration and just make it an assignment instead:
canvas = document.getElementById("myCanvas");
ctx = canvas.getContext("2d");
With these changes, the initial errors were resolved.
Issues
In init the shapes are drawn on the canvas and we have two identical lines using requestAnimationFrame:
requestId = requestAnimationFrame(animationLoop);
drawMoon(moonx, moony, moonAngle, "green", "yellow");
moonx += incrementX;
requestId = requestAnimationFrame(animationLoop);
I removed the first one (also removing the requestId assignment as it didn't seem necessary). Then, in order for the animationLoop to continue to animate, we need to call requestAnimationFrame(animationLoop) inside of the animationLoop function.
function animationLoop() {
// ...
requestAnimationFrame(animationLoop);
}
Then, in order to actually draw the shapes in each call of animationLoop, I moved the draw<shape> function calls inside of animationLoop. Also, we want to clear the canvas each time we draw on it to properly animate our shapes, so we'll need to use .clearRect. Now the animationLoop looks like this:
function animationLoop() {
moonx += incrementX;
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawMonster(260, 260);
drawCloud(150, 175);
drawMoon(moonx, moony, moonAngle, "green", "yellow");
requestAnimationFrame(animationLoop);
}
But the final reason the moon won't move when we press the left or right arrows is that we're not actually using the moonx and moony variables when drawing the moon. So, in drawMoon, instead of
ctx.arc(100, 75, 150, 0, Math.PI / .5);
this should be changed to the following
ctx.arc(moonx, moony, 150, 0, Math.PI / 0.5);
I believe I covered all of the major issues with your code to be able to draw all the shapes and move the moon with the left and right arrows. See the full code example below.
var canvas, ctx;
var moonx = 0;
var moony = 0;
var moonAngle = 0;
var incrementX = 0;
function init() {
canvas = document.getElementById("myCanvas");
ctx = canvas.getContext("2d");
window.addEventListener("keydown", handleKeydown, false);
window.addEventListener("keyup", handleKeyup, false);
requestAnimationFrame(animationLoop);
function handleKeydown(evt) {
if (evt.keyCode === 37) {
incrementX = -1;
} else if (evt.keyCode === 39) {
incrementX = 1;
}
}
function handleKeyup(evt) {
incrementX = 0;
}
function animationLoop() {
moonx += incrementX;
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawMonster(260, 260);
drawCloud(150, 175);
drawMoon(moonx, moony, moonAngle, "green", "yellow");
requestAnimationFrame(animationLoop);
}
}
function drawMonster(x, y) {
ctx.save();
ctx.beginPath();
ctx.arc(740, 750, 175, 0, Math.PI / 0.5);
ctx.fillStyle = "lightgrey";
ctx.fill();
ctx.lineWidth = 3;
ctx.stroke();
//mouth1
ctx.fillStyle = "black";
ctx.fillRect(x + 350, y + 550, 200, 20);
//mouth2
ctx.fillStyle = "black";
ctx.fillRect(x + 375, y + 540, 150, 20);
//mouth3
ctx.fillStyle = "black";
ctx.fillRect(x + 375, y + 560, 150, 20);
ctx.restore();
//eyes
addShadows2();
ctx.fillStyle = "lightslategrey";
ctx.fillRect(x + 350, y + 400, 40, 40);
ctx.fillRect(x + 450, y + 400, 40, 40);
//pupil
ctx.fillStyle = "black";
ctx.fillRect(x + 350, y + 400, 20, 20);
ctx.fillRect(x + 450, y + 400, 20, 20);
}
//moon
function drawMoon(moonx, moony) {
ctx.beginPath();
ctx.arc(moonx, moony, 150, 0, Math.PI / 0.5);
ctx.fillStyle = "lightgrey";
addShadows();
ctx.fill();
ctx.lineWidth = 3;
ctx.stroke();
}
//cloud
function drawCloud(x, y) {
ctx.beginPath();
ctx.arc(x, y, 60, Math.PI * 0.5, Math.PI * 1.5);
ctx.arc(x + 70, y - 60, 70, Math.PI * 1, Math.PI * 1.85);
ctx.arc(x + 152, y - 45, 50, Math.PI * 1.37, Math.PI * 1.91);
ctx.arc(x + 200, y, 60, Math.PI * 1.5, Math.PI * 0.5);
ctx.moveTo(x + 200, y + 60);
ctx.lineTo(x, y + 60);
ctx.strokeStyle = "#797874";
ctx.stroke();
ctx.fillStyle = "lightslategrey";
ctx.fill();
}
function addShadows() {
ctx.shadowColor = "beige"; // color
ctx.shadowBlur = 160; // blur level
ctx.shadowOffsetX = 15; // horizontal offset
ctx.shadowOffsetY = 15; // vertical offset
}
function addShadows2() {
ctx.shadowColor = "black";
ctx.shadowBlur = 40;
ctx.shadowOffsetX = 15;
ctx.shadowOffsetY = 10;
}
function addShadows3() {
ctx.shadowColor = "beige";
ctx.shadowBlur = 160;
ctx.shadowOffsetX = 10;
ctx.shadowOffsetY = 10;
}
init();
<canvas id="myCanvas" width="900" height="900">Your browser does not support the canvas tag.</canvas>
I made this graph using canvas. However this graph is not responsive and when I tried to make it responsive by drawing according to the new size The old lines remained on the screen along with the new lines. how can I resize each line without drawing them again and again?
function drawShape(a, b, c, d, e, f, g, h, i, j, k, l) {
var canvas = document.getElementById('linegraph1');
var value = new Array(a, b, c, d, e, f, g, h, i, j, k, l);
var ctx = canvas.getContext('2d');
for (i = 1; i < 13; i++) {
{
ctx.beginPath();
ctx.lineWidth = 9;
ctx.lineCap = 'round';
ctx.strokeStyle = '#FFFFFF';
ctx.moveTo(7 + i * 30, 50);
ctx.lineTo(7 + i * 30, 150);
ctx.stroke();
}
{
ctx.beginPath();
ctx.lineWidth = 9;
ctx.lineCap = 'round';
ctx.strokeStyle = '#EFF2FB';
ctx.moveTo(7 + i * 30, 50);
ctx.lineTo(7 + i * 30, 150);
ctx.stroke();
}
ctx.lineWidth = 9;
ctx.beginPath();
ctx.moveTo(7 + i * 30, 150);
if (value[i - 1] > 100) {
var buffer = 50;
} else {
var buffer = 150 - value[i - 1];
}
ctx.lineTo(7 + i * 30, buffer);
if (value[i - 1] > 80) {
ctx.strokeStyle = '#B60114';
} else {
ctx.strokeStyle = '#0093CF';
}
ctx.lineCap = 'round';
ctx.lineCap = 'round';
ctx.font = "15px Arial";
ctx.fillText(value[i - 1], 1 + i * 30, 180);
ctx.stroke();
}
ctx.beginPath();
ctx.font = "15px Arial";
ctx.fillText("0", 400, 150);
ctx.fillText("25", 400, 105);
ctx.fillText("50", 400, 60);
ctx.fillText("mb", 400, 180);
}
<div>
<canvas id="linegraph1" width="450" height="200" style="border:1px solid grey; border-radius: 10px;">
</div>
<button onclick="drawShape(10, 20, 80, 45, 55, 88, 74, 41, 45, 12, 21, 12)">Draw Graph</button>
You could just use css on the canvas element:
function drawShape(a, b, c, d, e, f, g, h, i, j, k, l) {
var canvas = document.getElementById('linegraph1');
var value = new Array(a, b, c, d, e, f, g, h, i, j, k, l);
var ctx = canvas.getContext('2d');
//Wipe canvas between draws
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (i = 1; i < 13; i++) {
{
ctx.beginPath();
ctx.lineWidth = 90;
ctx.lineCap = 'round';
ctx.strokeStyle = '#FFFFFF';
ctx.moveTo(7 + i * 300, 500);
ctx.lineTo(7 + i * 300, 1500);
ctx.stroke();
} {
ctx.beginPath();
ctx.lineWidth = 90;
ctx.lineCap = 'round';
ctx.strokeStyle = '#EFF2FB';
ctx.moveTo(7 + i * 300, 500);
ctx.lineTo(7 + i * 300, 1500);
ctx.stroke();
}
ctx.lineWidth = 90;
ctx.beginPath();
ctx.moveTo(7 + i * 300, 1500);
if (value[i - 1] > 100) {
var buffer = 50;
} else {
var buffer = 150 - value[i - 1];
}
ctx.lineTo(7 + i * 300, buffer);
if (value[i - 1] > 80) {
ctx.strokeStyle = '#B60114';
} else {
ctx.strokeStyle = '#0093CF';
}
ctx.lineCap = 'round';
ctx.lineCap = 'round';
ctx.font = "150px Arial";
ctx.fillText(value[i - 1], 1 + i * 300, 1800);
ctx.stroke();
}
ctx.beginPath();
ctx.font = "150px Arial";
ctx.fillText("0", 4000, 1500);
ctx.fillText("25", 4000, 1050);
ctx.fillText("50", 4000, 600);
ctx.fillText("mb", 4000, 1800);
}
#linegraph1 {
border: 1px solid grey;
border-radius: 10px;
/* Fit window */
width: 100%;
}
<div>
<canvas id="linegraph1" width="4500" height="2000"></canvas>
</div>
<button onclick="drawShape(10, 20, 80, 45, 55, 88, 74, 41, 45, 12, 21, 12)">Draw Graph</button>
EDIT
Enlarged the drawn canvas to avoid bad pixelation when stretching.
http://jsfiddle.net/wm7pwL2w/8/
How can I add border to the outer area of slice in pie? Please check my jsfiddle. I have implemented Polar Area Chart here. I need each border to be of different color which I can specify. For example refer to this image
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
console.log(ctx);
var center = {
x: 200,
y: 150
};
var myColor = ["#ccc", "#ccc", "#ccc", "#ccc", "#c01c3f"];
var myData = [20, 40, 50, 70, 100];
var myRadius = [150, 120, 80, 100, 70];
var myDistance = [5, 5, 2, 2, 2];
var myText = ['first', 'second', 'third', 'fourth', 'fifth'];
function getTotal(data) {
var myTotal = 0;
for (var j = 0; j < data.length; j++) {
myTotal += (typeof data[j] == 'number') ? data[j] : 0;
}
return myTotal;
}
function plotData() {
var lastend = 0;
var myTotal = getTotal(myData);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
//ctx.strokeStyle = 'rgba(255,255,255,0.5)';
ctx.lineWidth = 1;
ctx.font="15px Arial";
for (var i = 0; i < myData.length; i++) {
ctx.save();
ctx.fillStyle = myColor[i];
ctx.beginPath();
ctx.translate(center.x, center.y);
var thisAngle = (Math.PI * 2 * (myData[i] / myTotal));
ctx.rotate(lastend + thisAngle / 2);
ctx.translate(myDistance[i], 0);
ctx.moveTo(0, 0);
ctx.arc(0, 0, myRadius[i], -(thisAngle / 2), thisAngle / 2, false);
ctx.closePath();
ctx.fill();
// ctx.stroke();
ctx.fillStyle = '#fff';
ctx.translate(0.6 * myRadius[i], 0);
ctx.rotate(-(lastend + thisAngle / 2));
ctx.fillText(myText[i], 0, 0);
ctx.restore();
lastend += thisAngle;
}
}
plotData();
Thanks for all the help.
You need to do it in two steps, first fill the shape then stroke just an arc. To do so you need to use a beginPath() for the outer border after filling it so to not stroke the complete shape.
...
ctx.closePath();
ctx.fill();
// original code stops
// insert this code
ctx.beginPath();
ctx.strokeStyle = '#079';
ctx.lineWidth = 9;
ctx.arc(0, 0, myRadius[i], -(thisAngle / 2), thisAngle / 2);
ctx.stroke();
// original code continues...
// ctx.stroke();
ctx.fillStyle = '#fff';
...
Updated fiddle
Use strokeStyle. JSFiddle
var lineColor = ["blue", "green", "purple", "pink", "aqua"];
for (var i = 0; i < myData.length; i++) {
............................
ctx.strokeStyle = lineColor[i];
ctx.fillStyle = myColor[i];
........
.............
ctx.fill();
ctx.stroke();
......................
}
How to add another stroke with a different color and length into the same circle?
This script use Mootools lib. Can it be converted in pure JavaScript or jQuery?
fiddle: http://jsfiddle.net/xc4xnzcq/1/
Thanks :)
// SVG stuff
var ctx = document.id('counter').getContext('2d');
var circ = Math.PI * 2;
var quart = Math.PI / 2;
ctx.beginPath();
ctx.strokeStyle = '#ff00ab';
ctx.lineCap = 'square';
ctx.closePath();
ctx.fill();
ctx.lineWidth = 10;
var imd = ctx.getImageData(0, 0, 160, 160);
var draw = function(current) {
ctx.putImageData(imd, 0, 0);
ctx.beginPath();
ctx.arc(119, 70, 60, -(quart), ((circ) * current) - quart, false);
ctx.stroke();
}
var myFx = new Fx({
duration: 5500,
transition: 'bounce:out',
onStep: function(step){
draw(step / 100);
}
});
myFx.set = function(now){
var ret = Fx.prototype.set.call(this, now);
this.fireEvent('step', now);
return ret;
};
myFx.start(0, 80);
Drawing a second path seems to work fine for me.
// SVG stuff
var ctx = document.id('counter').getContext('2d');
var circ = Math.PI * 2;
var quart = Math.PI / 2;
var imd = ctx.getImageData(0, 0, 160, 160);
var draw = function(current) {
ctx.putImageData(imd, 0, 0);
ctx.beginPath();
ctx.strokeStyle = '#ff00ab';
ctx.lineCap = 'square';
ctx.lineWidth = 10;
ctx.arc(119, 70, 60, -(quart), ((circ) * current) - quart, false);
ctx.stroke();
ctx.beginPath();
ctx.strokeStyle = '#bb00bc';
ctx.lineCap = 'square';
ctx.lineWidth = 5;
ctx.arc(119, 70, 60, -(quart), ((circ) * current) - quart, false);
ctx.stroke();
}
var myFx = new Fx({
duration: 5500,
transition: 'bounce:out',
onStep: function(step){
draw(step / 100);
}
});
myFx.set = function(now){
var ret = Fx.prototype.set.call(this, now);
this.fireEvent('step', now);
return ret;
};
myFx.start(0, 80);
Is there any framework/engine that provide ability to draw 3d images on Canvas?
I am planning to draw some primitives (different shapes) located in one plane:
var dist = 2;
var hexHalfW = 35;
var lengthX = 20;
var hexR = Math.sqrt(lengthX*lengthX+hexHalfW*hexHalfW);//40.31128874
var hexDiag = 2*hexR;
var hexHeight = hexDiag;
var hexWidth = 2*hexHalfW;
function DrawHex(ctx, x, y)
{
var cx = x*(hexWidth + dist) - y*(hexWidth + dist)/2;
var cy = y*(hexR + lengthX + dist);
ctx.beginPath();
ctx.moveTo(cx, cy-hexR);
ctx.lineTo(cx+hexHalfW, cy-hexR+lengthX);
ctx.lineTo(cx+hexHalfW, cy+hexR-lengthX);
ctx.lineTo(cx, cy+hexR);
ctx.lineTo(cx-hexHalfW, cy+hexR-lengthX);
ctx.lineTo(cx-hexHalfW, cy-hexR+lengthX);
ctx.lineTo(cx, cy-hexR);
ctx.fill();
}
function draw()
{
var canvas = document.getElementById('tutorial');
if (canvas.getContext)
{
var ctx = canvas.getContext('2d');
//Pick Hexagon color, this one will be blue
ctx.fillStyle = "rgb(0, 0, 255)"; DrawHex(ctx, 1, 1);
ctx.fillStyle = "rgb(0, 0, 225)"; DrawHex(ctx, 3, 1);
ctx.fillStyle = "rgb(0, 0, 195)"; DrawHex(ctx, 4, 1);
ctx.fillStyle = "rgb(0, 0, 165)"; DrawHex(ctx, 6, 1);
ctx.fillStyle = "rgb(0, 255, 0)"; DrawHex(ctx, 3, 2);
ctx.fillStyle = "rgb(0, 225, 0)"; DrawHex(ctx, 4, 2);
ctx.fillStyle = "rgb(0, 195, 0)"; DrawHex(ctx, 5, 2);
}
}
I would like to draw these primitives in "perspective": closer shapes (in the bottom of the screen) will be bigger, shapes "far away" (in the top of the screen) needs to be smaller...
For this purpose shapes coordinates are needs to be recalculated.
Guess, I could find some formulas that allows to recalculate coordinates and write a proper functions... but, probably, there are some engines that already doing that?
Please advise.
Any thoughts are welcome!
Whatever framework you chose, you should learn to encapsulate your data into objects.
- View simple demo -
Hexagon
// Hexagon
function Hexagon(ctx, color, pos, size, scale) {
this.color = color;
this.ctx = ctx;
this.x = pos[0];
this.y = pos[1];
this.z = pos[2] || 0; // scale
this.width = size.width;
this.height = size.height;
}
Hexagon.draw
// Hexagon.draw
Hexagon.prototype.draw = function (x, y) {
if (x == null || y == null) {
x = this.x;
y = this.y;
}
var width = this.width + (this.width * this.z), // scaled width
height = this.height + (this.height * this.z), // scaled height
cx = x * (width + dist) - y * (width + dist) / 2,
cy = y * (3/4 * height + dist),
ctx = this.ctx;
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.moveTo(cx, cy - height/2);
ctx.lineTo(cx + width/2, cy - height/4);
ctx.lineTo(cx + width/2, cy + height/4);
ctx.lineTo(cx, cy + height/2);
ctx.lineTo(cx - width/2, cy + height/4);
ctx.lineTo(cx - width/2, cy - height/4);
ctx.lineTo(cx, cy - height/2);
ctx.fill();
};
Usage
var canvas = document.getElementById('tutorial');
var ctx = canvas.getContext('2d');
var dist = 2;
// Create Hexagons
var size = {
width: 70,
height: 80
};
var hexes = [
new Hexagon(ctx, "rgb(0, 0, 255)", [1, 1], size),
new Hexagon(ctx, "rgb(0, 0, 225)", [3, 1], size),
new Hexagon(ctx, "rgb(0, 0, 195)", [4, 1], size),
new Hexagon(ctx, "rgb(0, 0, 165)", [6, 1], size),
new Hexagon(ctx, "rgb(0, 225, 0)", [3, 2], size),
new Hexagon(ctx, "rgb(0, 225, 0)", [4, 2], size),
new Hexagon(ctx, "rgb(0, 195, 0)", [5, 2], size)
];
function draw() {
for (var i = hexes.length; i--;) {
hexes[i].draw();
}
}
You might want to look at mrdoob's three.js:
http://github.com/mrdoob/three.js/