How to rotate a particular element without affecting other elements in canvas? - javascript

I'm trying to move the tank when the user pressed the right/left key. When I use rotate() it is affecting all the elements of the canvas. Is there a way to only move the third rectangle of the tank when the user presses the right or left key?
The goal is to change the angle by a certain amount on pressing the keys. I searched, but couldn't find something basic enough for me to understand how to implement it.
var canvas=document.getElementById('canvas');
var ctx=canvas.getContext('2d');
var rightPressed=false;
var leftPressed=false;
var score1=0;
var score2=0;
var turn=0;
document.addEventListener("keydown",keyDownHandler,false);
document.addEventListener("keyup",keyUpHandler,false);
function keyDownHandler(e) {
if(e.keyCode==37)
leftPressed=true;
else if(e.keyCode==39)
rightPressed=true;
}
function keyUpHandler(e) {
if(e.keyCode==37)
leftPressed=false;
else if(e.keyCode==39)
rightPressed=false;
}
function drawMountain() {
ctx.beginPath();
ctx.moveTo(250, 400);
ctx.bezierCurveTo(250, 100, 500, 100, 500, 400);
ctx.fillStyle="green";
ctx.fill();
ctx.closePath();
}
function drawTanks() {
ctx.beginPath();
ctx.rect(20,360,50,40);
ctx.rect(620,360,50,40);
ctx.rect(30,340,30,20);
ctx.rect(630,340,30,20);
ctx.rect(40,300,10,40);
ctx.rect(640,300,10,40);
ctx.fillStyle="blue";
ctx.fill();
ctx.closePath();
}
function rotateTank() {
ctx.beginPath();
ctx.rect(20,20,130,40);
ctx.rect(560,20,130,40);
ctx.fillStyle="green";
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.fillStyle="white";
ctx.font="20px Verdana";
ctx.fillText('Player 1: '+ score1,28,45);
ctx.closePath();
ctx.beginPath();
ctx.fillStyle="white";
ctx.font="20px Verdana";
ctx.fillText('Player 2: '+ score2,570,45);
ctx.closePath();
}
function drawGame() {
ctx.clearRect(0,0,canvas.width,canvas.height);
drawMountain();
drawTanks();
rotateTank();
}
setInterval(drawGame,10);
#canvas {
background-color: black;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="game.css">
</head>
<body>
<center><canvas id="canvas" width="700" height="400"></canvas></center>
<script src="game.js">
</script>
</body>
</html>

Let's say that we have two rectangles.
ctx.fillStyle = "#F00";
ctx.fillRect(10, 10, 20, 10);
ctx.fillStyle = "#00F";
ctx.fillRect(50, 50, 20, 10);
And you want to rotate only the first one.
There are two ways to do it:
Move the red rectangle after the blue one and rotate it
ctx.fillStyle = "#00F";
ctx.fillRect(50, 50, 20, 10);
ctx.rotate(20*Math.PI/180);
ctx.fillStyle = "#F00";
ctx.fillRect(10, 10, 20, 10);
Just set ctx.rotate to a negative number (in our case -20) after the red rectangle
ctx.rotate(20*Math.PI/180);
ctx.fillStyle = "#F00";
ctx.fillRect(10, 10, 20, 10);
ctx.rotate(-20*Math.PI/180); //This "resets" the rotation.
ctx.fillStyle = "#00F";
ctx.fillRect(50, 50, 20, 10);
Here's a code snippet:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
function draw() {
ctx.rotate(20*Math.PI/180);
ctx.fillStyle = "#F00";
ctx.fillRect(10, 10, 20, 10);
ctx.rotate(-20*Math.PI/180);
ctx.fillStyle = "#00F";
ctx.fillRect(50, 50, 20, 10);
}
draw();
<canvas id="canvas" width=100 height=100 style="border: 1px solid #000"></canvas>

Related

Using a switch case statement state machine to draw shapes in javascript

I'm trying to modify some getElementById code I found on the internet to write a function that uses a switch/case statement so that I can draw different shapes using the same function. Basically, I want to create a tiny state machine for shape drawing commands. JavaScript is still new to me, so I'm probably missing something glaringly obvious. Cheers!
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Draw a circle</title>
<script src="draw_shapes.js"></script>
</head>
<body onload="draw01();">
<canvas id="circle" width="150" height="150"></canvas>
</body>
</html>
draw_shapes.js
function draw01() {
var canvas = document.getElementById('circle');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
var X = canvas.width / 2;
var Y = canvas.height / 2;
var R = 45;
ctx.beginPath();
ctx.arc(X, Y, R, 0, 2 * Math.PI, false);
ctx.lineWidth = 3;
ctx.strokeStyle = '#000000';
ctx.stroke();
}
}
function draw02() {
const canvas = document.getElementById(canvas.id);
const ctx = canvas.getContext('2d');
switch (canvas.id) {
case "circle":
var X = canvas.width / 2;
var Y = canvas.height / 2;
var R = 45;
ctx.beginPath();
ctx.arc(X, Y, R, 0, 2 * Math.PI, false);
ctx.lineWidth = 3;
ctx.strokeStyle = '#000000';
ctx.stroke();
break;
}
}
Second iteration. Still not quite working right, but I've got the setup more as I was envisioning.
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Draw a circle</title>
<script src="draw_shapes_02.js"></script>
</head>
<body onload="draw(CIRCLE);">
</body>
</html>
draw_shapes_02.js
//shape enumeration (an object with constant variables with immutable property values)
const shapes = {
CIRCLE: "circle",
RECTANGLE: "rectangle",
TRIANGLE: "triangle",
HOUSE: "house",
DEFAULT:"default",
}
Object.freeze(shapes);
// shape default setting and error
let shape = shapes.DEFAULT;
if (!shape) {
throw new Error("Shape is not defined");
}
// shape state machine
function draw(shapes) {
var canvas = document.getElementById("shape");
var ctx = canvas.getContext('2d');
switch ("shape") {
case shapes.CIRCLE:
ctx.beginPath();
ctx.fillStyle = "black";
ctx.arc(150, 60, 50, 0, 2 * Math.PI);
ctx.closePath();
ctx.fill();
break;
case shapes.RECTANGLE:
ctx.beginPath();
ctx.fillStyle = "green";
ctx.rect(100, 130, 100, 50);
ctx.fill();
ctx.closePath();
break;
case shapes.TRIANGLE:
ctx.beginPath();
ctx.fillStyle = "yellow";
ctx.moveTo(150, 200);
ctx.lineTo(200, 250);
ctx.lineTo(100, 250);
ctx.lineTo(150, 200);
ctx.fill();
ctx.closePath();
break;
case shapes.HOUSE:
ctx.lineWidth = 10;
ctx.strokeRect(75, 140, 150, 110);
ctx.fillRect(130, 190, 40, 60);
ctx.beginPath();
ctx.moveTo(50, 140);
ctx.lineTo(150, 60);
ctx.lineTo(250, 140);
ctx.closePath();
ctx.stroke();
break;
case shapes.DEFAULT:
break;
}
}
I have simplified a bit but you can complicate again as you wish :)
function draw(shape) {
var canvas = document.getElementById("CIRCLE");
var ctx = canvas.getContext('2d');
console.log(shape);
switch (shape) {
case "CIRCLE":
ctx.beginPath();
ctx.fillStyle = "black";
ctx.arc(150, 60, 50, 0, 2 * Math.PI);
ctx.closePath();
ctx.fill();
break;
case "RECTANGLE":
ctx.beginPath();
ctx.fillStyle = "green";
ctx.rect(100, 130, 100, 50);
ctx.fill();
ctx.closePath();
break;
case "TRIANGLE":
ctx.beginPath();
ctx.fillStyle = "yellow";
ctx.moveTo(150, 200);
ctx.lineTo(200, 250);
ctx.lineTo(100, 250);
ctx.lineTo(150, 200);
ctx.fill();
ctx.closePath();
break;
case "HOUSE":
ctx.lineWidth = 10;
ctx.strokeRect(75, 140, 150, 110);
ctx.fillRect(130, 190, 40, 60);
ctx.beginPath();
ctx.moveTo(50, 140);
ctx.lineTo(150, 60);
ctx.lineTo(250, 140);
ctx.closePath();
ctx.stroke();
break;
default:
ctx.fillStyle = "#FF0000";
ctx.fillRect(0,0,150,75);
break;
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Draw a circle</title>
</head>
<body onload="draw('HOUSE');">
<canvas width="240" height="297" style="border:1px solid #d3d3d3;" id="CIRCLE"></canvas>
</body>
</html>

Cube gets a little bigger when i draw it again. (Canvas, Javascript)

//Selectors
canvas = document.querySelector('.canvas');
canvas.setAttribute("tabindex", 0);
canvas.focus();
pointerImg = document.querySelector('.pointer');
//Variables
const pi = Math.PI;
const c = canvas.getContext('2d');
var grid = {
'x':60,
'y':20,
'size':20,
}
var pointerValues = {
37: {'x':-1, 'y':0},
38: {'x':0, 'y':-1},
39: {'x':1, 'y':0},
40: {'x':0, 'y':1},
}
//Event Listeners
window.addEventListener('resize', function() {
//init();
})
var cells = [];
for(let i=0;i<grid.x;i++) {
cells[i] = new Array(grid.y);
}
//Functions
function init() {
resizeGrid();
initCells();
}
init();
function update(){
requestAnimationFrame(update)
}
update();
function Cell(x, y, size) {
this.x = x;
this.y = y;
this.size = size;
this.color = 'white';
this.update = function() {
this.draw();
}
this.draw = function() {
c.beginPath();
c.rect(this.x*this.size, this.y*this.size, this.size, this.size);
c.strokeStyle = 'black';
c.stroke();
c.fillStyle=this.color; c.fill();
c.closePath();
}
this.resetCell = function() {
c.clearRect(this.x, this.y, this.size, this.size);
this.update();
}
}
function resizeGrid() {
let windowX = window.innerWidth;
windowX -= windowX*0.1;
grid.size = windowX/grid.x;
let canvasX = windowX, canvasY = grid.y * grid.size;
canvas.width = canvasX;
canvas.height = canvasY;
}
function initCells() {
cells = [];
for(let i=0;i<grid.x;i++) {
cells[i] = new Array(grid.y);
}
for(let i=0;i<grid.x;i++) {
for(let j=0;j<grid.y;j++) {
cells[i][j] = new Cell(i, j, grid.size);
cells[i][j].update();
}
}
}
<html>
<head>
<link rel="stylesheet" href="assets/css/main.css">
<div style="display:none;">
<img class='pointer' src="assets/img/pointer.svg">
</div>
<div class='nav'>
</div>
</head>
<body>
<div class="content">
<canvas class='canvas'></canvas>
</div>
<script src='assets/js/canvas.js'></script>
</body>
</html>
function Cell(x, y, size) {
this.x = x;
this.y = y;
this.size = size;
this.color = 'white';
this.update = function () {
this.draw();
}
this.draw = function () {
c.beginPath();
c.rect(this.x * this.size, this.y * this.size, this.size, this.size);
c.strokeStyle = 'black';
c.stroke();
c.fillStyle = this.color;
c.fill();
c.closePath();
}
this.resetCell = function () {
c.clearRect(this.x, this.y, this.size, this.size);
this.update();
}
This is my code for a single cell in a grid. After I draw it a single time, when I call resetCell(), it draws the cell just a little bit bigger.
In this picture, I call Update for the very first cell and it becomes a tiny bit bigger than the rest.
I've tried pretty much everything but nothing seems to work.
Also can someone recommend better way to draw and control grid.
I need it to demonstrate BFS algorithm.
You were tricked by the thickness of the border
The border has a thickness, which is easy to forget. If you draw a box which is X wide, its left and right border are in addition to the width of X.
So if you do NOT fill the interior, you get this nice appearance (left), but if you FILL, you get this ugly appearance (right).
When you draw a grid of these squares, each one covers over the right-hand and bottom sides of previous squares, so that it is not obvious what is happening.
Unless you redraw one that is not the last of the list, as I have done here (bottom-middle). Then it becomes obvious that something is wrong.
Here is the code to reproduce the above figures, and below I recommend a solution.
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
// With NO fill, it looks fine
ctx.beginPath();
ctx.rect(40, 40, 40, 40);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.rect(80, 80, 40, 40);
ctx.stroke();
ctx.closePath();
// With white fill, the inner half of each box gets covered up by the white fill.
ctx.beginPath();
ctx.rect(140, 40, 40, 40);
ctx.stroke();
ctx.fillStyle="white";
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.rect(180, 80, 40, 40);
ctx.stroke();
ctx.fillStyle="white";
ctx.fill();
ctx.closePath();
// Make Grid. This part looks OK initially.
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.rect(240, 40, 40, 40);
ctx.stroke();
ctx.fillStyle="white";
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.rect(240, 80, 40, 40);
ctx.stroke();
ctx.fillStyle="white";
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.rect(280, 40, 40, 40);
ctx.stroke();
ctx.fillStyle="white";
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.rect(280, 80, 40, 40);
ctx.stroke();
ctx.fillStyle="white";
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.rect(320, 40, 40, 40);
ctx.stroke();
ctx.fillStyle="white";
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.rect(320, 80, 40, 40);
ctx.stroke();
ctx.fillStyle="white";
ctx.fill();
ctx.closePath();
// Redraw one: this will look messed up.
ctx.beginPath();
ctx.rect(280, 80, 40, 40);
ctx.stroke();
ctx.fillStyle="white";
ctx.fill();
ctx.closePath();
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="400" height="150" ></canvas>
</body>
</html>
Solution 1. Don't fill the interiors
This is the neatest solution, if you can get away with it, and it works regardless of any (non-zero) border thickness.
Solution 2. Shrink the width to allow for border thickness
This is complicated because you need to manually set the border thickness, and realise that it is in addition to the numerical values you specify for the rectangle's size.
Look at this messy business at CSS-tricks, even when they are trying to make borders interesting! https://css-tricks.com/almanac/properties/b/border/

How do I copy line segment on HTML5 CANVAS tag rotate it and place it next to the original segment?

Firstly I have tried to find solution to my problem but I do not think that I know how to search online for solutions.
Okay so I have this image that is drawn via line segments : moveTo, lineTo etc.
As you can see we could divide the image into 4 parts that are essentially the same but rotated and placed next to other elements. What I mean by this if you draw 4 lines from the center with 90 angle you can notice the same pattern.
Basically what I am trying to do is to have one part of the canvas drawn manually by inserting moveTo and the rest to somehow generate to save some time ofc.
Not sure if I explained well my problem, excuse me this is my first stackoverflow question posted.
I mean I found a way to do this by having 4 different CANVAS elements and then rotate each canvas. I am looking for a way to do everything in one CANVAS element. But not sure if that is possible.
My code below:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Model 1</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body onload="draw();">
<canvas id="canvas_id" width="150" height="150" style="border:1px solid #000000;"></canvas>
<!-- 1---->
<script type="text/javascript">
function draw() {
var canvas = document.getElementById('canvas_id');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
//top left square
ctx.beginPath();
ctx.moveTo(10, 10);
ctx.lineTo(10, 40);
ctx.lineTo(40, 40);
ctx.lineTo(40, 10);
ctx.lineTo(10, 10);
ctx.fillStyle = "red";
ctx.fill();
//down left square
ctx.beginPath();
ctx.moveTo(10, 100);
ctx.lineTo(10, 130);
ctx.lineTo(40,130);
ctx.lineTo(40, 100);
ctx.lineTo(10, 100);
ctx.fillStyle = "red";
ctx.fill();
//top right square
ctx.beginPath();
ctx.moveTo(100, 10);
ctx.lineTo(130, 10);
ctx.lineTo(130, 40);
ctx.lineTo(100, 40);
ctx.lineTo(100, 10);
ctx.fillStyle = "red";
ctx.fill();
//down right square
ctx.beginPath();
ctx.moveTo(100, 100);
ctx.lineTo(130, 100);
ctx.lineTo(130, 130);
ctx.lineTo(100, 130);
ctx.lineTo(100, 100);
ctx.fillStyle = "red";
ctx.fill();
//center figure
//1
ctx.beginPath();
ctx.moveTo(70, 10);
ctx.lineTo(10, 70);
ctx.lineTo(70, 130);
ctx.lineTo(130, 70);
ctx.lineTo(70, 10);
// inside
ctx.moveTo(70, 30);
ctx.lineTo(30, 70);
ctx.lineTo(70, 110);
ctx.lineTo(110, 70);
ctx.lineTo(70, 30);
//square 1
ctx.moveTo(60, 60);
ctx.lineTo(80, 60);
ctx.lineTo(80, 80);
ctx.lineTo(60, 80);
ctx.lineTo(60, 60);
//square 2
ctx.moveTo(50, 50);
ctx.lineTo(90, 50);
ctx.lineTo(90, 90);
ctx.lineTo(50, 90);
ctx.lineTo(50, 50);
ctx.stroke();
}
}
</script>
</body>
</html>
I hope that I understood well what you need.
You can either parametrize your draw function with an angle, and a x, y position parameters, or copy, rotate and paste a part of the canvas. I assumed you would prefer the second solution.
Basically, copy your canvas, rotate it, draw something, then restore your changes.
You can use this function:
function draw(canvas, ctx, x, y, angle) {
ctx.save();
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.rotate(angle * Math.PI / 180);
ctx.translate(-(canvas.width / 2), -(canvas.height / 2));
// drawing begin
ctx.beginPath();
ctx.moveTo(10, 10);
ctx.lineTo(10, 40);
ctx.lineTo(40, 40);
ctx.lineTo(40, 10);
ctx.lineTo(10, 10);
ctx.lineTo(30, 30);
ctx.strokeStyle = "red";
ctx.stroke();
// drawing end
ctx.restore();
}
You can use it like this:
// draw something with a 90° angle
draw(canvas, ctx, 0, 0, 90);
// draw something with a 180° angle
draw(canvas, ctx, 0, 0, 180);
The x and y coordinates are the ones of the rotated canvas, so 0, 0 will be in the angle each time.
Here's a fiddle: https://jsfiddle.net/nmerinian/kt3f782o/19/

Animating an emoticon to wink with animation in HTML5 canvas

I am attempting to animate an emoticon that was previously drawn in canvas. I am attempting to do a draw and clear using frames following a tutorial but am not getting results. I have 6 frames of the emoticon coded and am unsure how to include this within the code. This is what I have so far:
<!DOCTYPE html>
<html>
<head>
<title>Adding Animation</title>
<style>
canvas {
border: 3px #CCC solid;
}
</style>
</head>
<body>
<div id="container">
<canvas id="myCanvas" height="1200" width="900"></canvas>
</div>
<script>
var mainCanvas = document.querySelector("#myCanvas");
var mainContext = mainCanvas.getContext("2d");
var canvasWidth = mainCanvas.width;
var canvasHeight = mainCanvas.height;
function drawCircle() {
mainContext.clearRect(0, 0, canvasWidth, canvasHeight);
// color in the background
mainContext.fillStyle = "#EEEEEE";
mainContext.fillRect(0, 0, canvasWidth, canvasHeight);
// draw the circle
ctx.beginPath();
ctx.strokeStyle = "000000";
ctx.lineWidth = 5;
ctx.fillStyle = "yellow";
ctx.arc(600, 450, 150, 0, Math.PI * 2, true);
ctx.stroke();
ctx.closePath();
ctx.fill();
//The smile
ctx.beginPath();
ctxstrokeStyle = "black";
ctx.lineWidth = 2;
ctx.arc(600, 475, 75, .1 * Math.PI, Math.PI * .9, false)
ctx.stroke();
ctx.closePath();
//The eyes
//Left
ctx.save();
ctx.scale(0.65, 1);
ctx.beginPath();
ctx.arc(850, 405, 40, 0 * Math.PI, Math.PI * 2, false);
ctx.fillStyle="black";
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.restore();
//Right
ctx.save();
ctx.scale(0.65, 1);
ctx.beginPath();
ctx.arc(1000,405,40, 0*Math.PI, Math.PI*2, false);
ctx.fillStyle="black";
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.restore()
}
drawCircle();
</script>
</body>
</html>
I am unsure if I am even on the right track as I have a difficult time with animation. Does anyone have any suggestions they can give me guidance on?
You have 2 names for the context: mainContext & ctx.
Change it to a single name and your face is "smiley" ! :-)
...
To animate:
Use a requestAnimationFrame loop to change the scaleY value in scale(scaleX,scaleY) over time.
Here's annotated code and a Demo:
var mainCanvas = document.querySelector("#myCanvas");
var ctx = mainCanvas.getContext("2d");
var canvasWidth = mainCanvas.width;
var canvasHeight = mainCanvas.height;
ctx.translate(-425,-275);
drawCircle(1);
// global var to hold pct the left eye is open
// 1==fully open, 0==fully closed
var scaley=1;
var direction=-1;
// request 1 animate() loop
requestAnimationFrame(animate);
function animate(time){
// draw smiley with the specified eye openness
drawCircle(scaley);
scaley+=.02*direction;
if(scaley<0){
scaley=0;
direction=1;
}
if(scaley>1){
scaley=1;
direction=-1;
}
requestAnimationFrame(animate);
}
function drawCircle(scaleY) {
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
// color in the background
ctx.fillStyle = "#EEEEEE";
ctx.fillRect(0, 0, canvasWidth, canvasHeight);
// draw the circle
ctx.beginPath();
ctx.strokeStyle = "000000";
ctx.lineWidth = 5;
ctx.fillStyle = "yellow";
ctx.arc(600, 450, 150, 0, Math.PI * 2, true);
ctx.stroke();
ctx.closePath();
ctx.fill();
//The smile
ctx.beginPath();
ctxstrokeStyle = "black";
ctx.lineWidth = 2;
ctx.arc(600, 475, 75, .1 * Math.PI, Math.PI * .9, false)
ctx.stroke();
//The eyes
//Left
ctx.save();
// move the [0,0] origin to the left eye's centerpoint
ctx.translate(550,405);
// close the left eye by the specified scaleY
ctx.scale(0.65, scaleY);
ctx.beginPath();
// draw the left eye (arc) at 0,0 because
// we translated the origin to [550,405] earlier
ctx.arc(0, 0, 40, 0 * Math.PI, Math.PI * 2, false);
ctx.fillStyle="black";
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.restore();
//Right
ctx.save();
ctx.scale(0.65, 1);
ctx.beginPath();
ctx.arc(1000,405,40, 0*Math.PI, Math.PI*2, false);
ctx.fillStyle="black";
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.restore()
}
<canvas id="myCanvas" height="1200" width="900"></canvas>
You never declared a ctx variable.
Change all your mainContext by ctx and it should be working fine.

ArcTo() not drawing arc

I've got the following HTML file:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Canvas Hello World</title>
<link href="default.css" rel="stylesheet" />
<script src="jquery-2.0.0.min.js"></script>
</head>
<body>
<h1>ArcTo</h1>
<h2>Two arcs</h2>
<canvas id="arcToNormalCanvas" width="500" height="500">HTML5 not supported
</canvas>
<hr />
<h1>Simple drawing:</h1>
<canvas id="rectangleCanvas" width="500" height="500">HTML5 not supported
</canvas>
<hr />
<script>
$(document).ready(function () {
doRectangleCanvas();
drawTwoArcs();
});
function doRectangleCanvas() {
var canvas = $('#rectangleCanvas')[0],
ctx = canvas.getContext('2d');
ctx.fillRect(50, 100, 150, 200);
ctx.stroke();
}
function drawTwoArcs() {
var canvas = $('#arcToNormalCanvas')[0],
ctx = canvas.getContext('2d');
ctx.strokeStyle = 'blue';
ctx.lineWidth = 5;
ctx.beginPath();
ctx.moveTo(100, 100);
ctx.lineTo(200, 200);
ctx.moveTo(300, 200);
ctx.lineTo(400, 100);
ctx.stroke();
ctx.beginPath();
ctx.strokeStyle = 'green';
ctx.moveTo(200, 200);
ctx.arcTo(200, 200, 300, 200, 100);
ctx.stroke();
}
</script>
</body>
</html>
However, the output is only the lines, with no arc!
Any ideas?
arcTo is only supported by Firefox and Safari. For full browser support, you should use arc:
ctx.beginPath();
ctx.arc(250,200,50,Math.PI,Math.PI*2,true);
ctx.strokeStyle = "green";
ctx.stroke();
Also, I have to ask, why on earth are you using $('#rectangleCanvas')[0] when you should be using document.getElementById('rectangleCanvas')?
If you want to connect the two lines, which is what I think you want, I have to change this lines...
//...
ctx.moveTo(200, 200);
ctx.arcTo(250, 250, 300, 200, 50);
// A radius of 100 is not what you want I believe.
// I used 50 for this example.
// You might want Math.cos(Math.Pi / 4) * 100, which is around 70.7
// You might also want to add here a line to actually connect with (300, 200). As if you use a too short or too long radius your arc will not be connected.
ctx.lineTo(300, 200);
ctx.stroke();
... As this function will define an arc between the two tangents not from point to point.
BTW, arcTo function is well supported in all major browsers that support the canvas element.

Categories