Arc is drawing over rect - javascript

First, I draw a circle using arc and fill it. (button 1)
Then, I draw a rect over it and another arc and fill it red. (button 2)
However, after the second function, the first arc stays there and turns red, all of a sudden. Help?
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
function function1() {
context.fillStyle = "black";
context.fillRect(0, 0, 400, 400);
context.fillStyle = "white";
context.arc(100, 200, 50, 0, 2*Math.PI);
context.fill();
}
function function2() {
context.fillStyle = "black";
context.fillRect(0, 0, 400, 400);
context.fillStyle = "red";
context.arc(300, 200, 50, 0, 2*Math.PI);
context.fill();
}
<canvas id="canvas" width="400" height="400" style="border: 1px solid black"></canvas>
<button onClick="function1()">Button 1</button>
<button onClick="function2()">Button 2</button>

OH. WOW. I just had the same exact error as a question I posted literally like over a year ago, where I forgot to put context.beginPath();. Stupid me.
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
function function1() {
context.fillStyle = "black";
context.fillRect(0, 0, 400, 400);
context.fillStyle = "white";
context.beginPath();
context.arc(100, 200, 50, 0, 2*Math.PI);
context.fill();
}
function function2() {
context.fillStyle = "black";
context.fillRect(0, 0, 400, 400);
context.fillStyle = "red";
context.beginPath();
context.arc(300, 200, 50, 0, 2*Math.PI);
context.fill();
}
<canvas id="canvas" width="400" height="400" style="border: 1px solid black"></canvas>
<button onClick="function1()">Button 1</button>
<button onClick="function2()">Button 2</button>

Related

html5 canvas - how to use 'destination-out' to clear out the most recently drawn shape only?

Suppose I have drawn a green rectangle and then a blue rectangle over it. I want to draw a circular hole in the blue rectangle so that the green rectangle underneath is visible through the hole.
I have tried using destination-out but it clears all shapes underneath:
const ctx = document.querySelector("#canvas").getContext("2d");
ctx.fillStyle = "green";
ctx.fillRect(0, 0, 50, 100);
ctx.fillStyle = "blue";
ctx.fillRect(0, 0, 50, 50);
ctx.globalCompositeOperation = "destination-out";
ctx.beginPath();
ctx.arc(50 / 2 - 10 / 2, 50 / 2, 10, 0, Math.PI * 2);
ctx.fill();
ctx.globalCompositeOperation = "source-over";
<canvas
id="canvas"
width="500"
height="200"
style="background: black"
></canvas>
Create second canvas, add your blue rectangle to it, cut out circle and than merge it into first canvas:
const ctx = document.querySelector("#canvas").getContext("2d");
ctx.fillStyle = "green";
ctx.fillRect(0, 0, 50, 100);
const canvasTemp = document.createElement("canvas");
const ctxTemp = canvasTemp.getContext("2d");
ctxTemp.fillStyle = "blue";
ctxTemp.fillRect(0, 0, 50, 50);
ctxTemp.globalCompositeOperation = "destination-out";
ctxTemp.beginPath();
ctxTemp.arc(50 / 2 - 10 / 2, 50 / 2, 10, 0, Math.PI * 2);
ctxTemp.fill();
ctxTemp.globalCompositeOperation = "source-over";
ctx.drawImage(canvasTemp, 0, 0);
<canvas
id="canvas"
width="500"
height="200"
style="background: black"
></canvas>
To draw behind the current content use the destination-over composite mode:
const ctx = document.querySelector("#canvas").getContext("2d");
ctx.fillStyle = "blue";
ctx.fillRect(0, 0, 50, 50);
ctx.globalCompositeOperation = "destination-out";
ctx.beginPath();
ctx.arc(50 / 2 - 10 / 2, 50 / 2, 10, 0, Math.PI * 2);
ctx.fill();
ctx.globalCompositeOperation = "destination-over";
ctx.fillStyle = "green";
ctx.fillRect(0, 0, 50, 100);
<canvas
id="canvas"
width="500"
height="200"
style="background: black"
></canvas>

How do I make something Rotate towards mouse?

I am trying to solve a question which has been bugging me for a while, can someone explain to me how to make the *red rectangle face/aim towards my mouse and explain to me how it works it would be awesome!!!
Here is the Fiddle
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var player = {
x: 200,
y: 200,
}
drawPlayer = function(something) {
context.beginPath();
context.fillStyle = "blue";
context.arc(something.x, something.y, 30, 0, 2 * Math.PI);
context.fill();
context.fillStyle = "red";
context.fillRect(something.x, something.y - 10, 50, 20);
context.restore();
}
update = function() {
context.clearRect(0, 0, 500, 500)
drawPlayer(player);
}
setInterval(update, 20);
<canvas id="canvas" style="outline: 1px solid #ccc" width="500" height="500"></canvas>
Use context.translate to translate coordinates to the center of your player and then context.rotate to rotate the rectangle.
To find the angle between the mouse position and the center of the player you can use Math.atan2 function.
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var player = {
x: 200,
y: 200,
}
drawPlayer = function(something, angle) {
context.clearRect(0, 0, 500, 500);
context.beginPath();
context.fillStyle = "blue";
context.arc(something.x, something.y, 30, 0, 2 * Math.PI);
context.fill();
// save the untranslated context
context.save();
context.beginPath();
// move the rotation point to the center of the player
context.translate(something.x, something.y);
context.rotate(angle);
context.fillStyle = "red";
// note that coordinates are translated,
// so 0 is player.x and -10 is player.y - 10
context.fillRect(0, - 10, 50, 20);
// restore the context to its untranslated state
context.restore();
}
drawPlayer(player, 0);
document.onmousemove = function(e) {
var angle = Math.atan2(e.pageY - player.y, e.pageX - player.x)
drawPlayer(player, angle);
}
<canvas id="canvas" style="outline: 1px solid #ccc" width="500" height="500"></canvas>

html5 canvas drawing partially

I want to create the logo above using the html5 canvas but at the end of the day, it displayed only a triangle.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Coa</title>
</head>
<body>
<canvas id="logo" width="900" height="80">
<h1>COA</h1>
</canvas>
<script>
//function that draw the logo. I create a JavaScript function for drawing the
var drawLogo = function(){
var canvas = document.getElementById('logo');
var context = canvas.getContext("2d");
//applying gradient
var gradient = context.createLinearGradient(0, 0, 0, 40);
gradient.addColorStop(0, "#aa0000");
gradient.addColorStop(1, "#ff0000");
// use the strokepath,beginPath() and closePath() methods to start drawing a line, stroke and close when finish
context.fillStyle = gradient;
context.strokeStyle = gradient;
context.lineWidth = 2;
context.beginPath();
context.moveTo(0, 40);
context.lineTo(30, 0);
context.lineTo(60, 40);
context.lineTo(285, 40);
context.fill();
context.closePath();
//adding text
context.font = "italic 40px 'Arial'";
context.fillText("Coa", 60,36);
//Moving the Origin so as to fit the square under the triangle
context.save();
context.translate(20, 20);
context.fillRect(0, 0, 20, 20);
//use a path to draw the inner triangle
context.fillStyle("#ffffff");
context.strokeStyle("#ffffff");
context.lineWidth = 2;
context.beginPath();
context.moveTo();
context.lineTo(0, 20);
context.lineTo(10, 0);
context.lineTo(20, 20);
context.lineTo(0, 20);
context.fill();
context.closePath();
context.restore();
};
//Then invoke this method after first checking for the existence of the <canvas> element
var canvas = document.getElementById("logo");
if(canvas.getContext){
drawLogo();
}
</script>
</body>
</html>
I don't know what am doing wrong that makes the the code not working properly.
I have searched the internet and couldn't find anything tangible that solve the problem. Any help will be appreciated.
UPDATE: Try this:
if (document.getElementById('logo')) {
var canvas = document.getElementById("logo");
var context = canvas.getContext("2d");
//applying gradient
var gradient = context.createLinearGradient(0, 0, 0, 40);
gradient.addColorStop(0, "#aa0000");
gradient.addColorStop(1, "#ff0000");
context.strokeStyle = gradient;
context.fillStyle = gradient;
context.lineWidth = 2;
context.beginPath();
context.moveTo(0, 40);
context.lineTo(30, 0);
context.lineTo(60, 40);
context.lineTo(285, 40);
context.stroke();
context.fillRect(20, 20, 20, 20);
context.beginPath();
context.moveTo(30, 20);
context.lineTo(37, 28);
context.lineTo(35, 40);
context.lineTo(25, 40);
context.lineTo(23, 28);
context.lineTo(30, 20);
context.fillStyle="#ffffff";
context.fill();
context.fillStyle="#000000";
context.font = "italic 40px Arial";
context.fillText("coa", 60,36);
}
I moved around some of your code and it works now for me on Firefox. It looks like you haven't put the pentagon in the canvas yet. Here is a JSFillde:
https://jsfiddle.net/o289buyk/
if (document.getElementById('logo')) {
var canvas = document.getElementById("logo");
var context = canvas.getContext("2d");
//applying gradient
var gradient = context.createLinearGradient(0, 0, 0, 40);
gradient.addColorStop(0, "#aa0000");
gradient.addColorStop(1, "#ff0000");
// use the strokepath,beginPath() and closePath() methods to start drawing a line, stroke and close when finish
context.fillStyle = gradient;
context.strokeStyle = gradient;
context.lineWidth = 2;
context.beginPath();
context.moveTo(0, 40);
context.lineTo(30, 0);
context.lineTo(60, 40);
context.lineTo(285, 40);
context.fill();
context.closePath();
//adding text
context.font = "italic 40px 'Arial'";
context.fillText("Coa", 60,36);
//Moving the Origin so as to fit the square under the triangle
context.save();
context.translate(20, 20);
context.fillRect(0, 0, 20, 20);
//use a path to draw the inner triangle
context.fillStyle("#ffffff");
context.strokeStyle("#ffffff");
context.lineWidth = 2;
context.beginPath();
context.moveTo();
context.lineTo(0, 20);
context.lineTo(10, 0);
context.lineTo(20, 20);
context.lineTo(0, 20);
context.fill();
context.closePath();
context.restore();
}

how can use a loop to draw it multiple times in random places in my canvas?

I've drawn a leaf in canvas, but now i want to draw it multiple times on my canvas and in random places. I've mostly used bezier curves to draw my leaf, is and i do not know how to use a loop to create more of them in random places, because of the coordinates.
My code:
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="800" height="800" style="border:1px solid #c3c3c3;">
</canvas>
<script>
var c = document.getElementById("myCanvas");
var context = c.getContext("2d");
context.lineWidth = 5;
context.beginPath();
context.moveTo(100, 150);
context.strokeStyle="#009900";
context.bezierCurveTo(170, 110, 400, 10, 500, 150);
context.stroke();
context.moveTo(100, 150);
context.strokeStyle="#009900";
context.bezierCurveTo(170, 130, 430, 310, 500, 150);
context.stroke();
context.fillStyle = '#99FF66';
context.fill();
context.strokeStyle="#009900";
context.moveTo(250, 150);
context.bezierCurveTo(400, 100, 400, 180, 500, 150);
context.stroke();
context.closePath();
context.beginPath();
context.strokeStyle="#996633";
context.moveTo(500, 150);
context.lineTo(580,150);
context.stroke();
context.closePath();
</script>
</body>
</html>
The simplest solution that I can come up with is to use the context.translate function to move to where you want to draw the leaf before drawing it:
//Generate x y coords, offset by the x,y of the leaf:
var x = (Math.random()*500) - 250;
var y = (Math.random()*500) - 150;
//Translate
context.translate(x, y);
//Draw leaf
//Translate back
context.translate(-x,-y)
Code to draw two leaves at random positions:
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="800" height="800" style="border:1px solid #c3c3c3;">
</canvas>
<script>
var c = document.getElementById("myCanvas");
var context = c.getContext("2d");
context.lineWidth = 5;
for(var i = 0; i < 2; i++) {
//Generate x y coords, offset by the top x,y of the leaf:
var x = (Math.random()*500) - 250;
var y = (Math.random()*500) - 150;
//Translate
context.translate(x, y);
//Draw
context.beginPath();
context.moveTo(100, 150);
context.strokeStyle="#009900";
context.bezierCurveTo(170, 110, 400, 10, 500, 150);
context.stroke();
context.moveTo(100, 150);
context.strokeStyle="#009900";
context.bezierCurveTo(170, 130, 430, 310, 500, 150);
context.stroke();
context.fillStyle = '#99FF66';
context.fill();
context.strokeStyle="#009900";
context.moveTo(250, 150);
context.bezierCurveTo(400, 100, 400, 180, 500, 150);
context.stroke();
context.closePath();
context.beginPath();
context.strokeStyle="#996633";
context.moveTo(500, 150);
context.lineTo(580,150);
context.stroke();
context.closePath();
//Translate Back
context.translate(-x, -y);
}
</script>
</body>
Since you want to re-use some of your code -> isolate the parameters and build a function out of it.
Then any pattern will be easy to build.
http://jsbin.com/mimisuziyi/1/
function drawLeaf(x,y, size, rotation) {
context.lineWidth = 5;
context.save();
context.translate(x,y);
context.scale(size/400, size/400);
context.rotate(rotation);
context.beginPath();
context.moveTo(0, 0);
context.strokeStyle="#009900";
context.bezierCurveTo(70, -40, 300, 10-150, 400, 0);
context.stroke();
context.moveTo(0, 0);
context.strokeStyle="#009900";
context.bezierCurveTo(70, -20, 330, 160, 400, 0);
context.stroke();
context.fillStyle = '#99FF66';
context.fill();
context.strokeStyle="#009900";
context.moveTo(150, 0);
context.bezierCurveTo(300, -50, 300, 30, 400, 0);
context.stroke();
context.closePath();
context.beginPath();
context.strokeStyle="#996633";
context.moveTo(400, 0);
context.lineTo(480,0);
context.closePath();
context.stroke();
context.restore();
}
used with :
drawLeaf(100, 150, 400, 0);
or :
var leafCount = 5;
for (var i=0; i<leafCount; i++) {
drawLeaf(150, 300, 100, 2*i*Math.PI/leafCount)
}

Trying to get a mouseclick in canvas to add an Image

The teacher has asked us to create a Canvas with some quick interactive features (The Class is interactive 101. Go figure) So I decided to create a quick idea using my favourite sports team, the Montreal Canadians. I will separate the HTML from the JavaScript.
HTML(Named: MontrealSymbol.html):
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h1>Say Hello To...</h1>
<h2>The MONTREAL CANADIENS!</h2>
<canvas id="mCanvas" width="320" height="240">
<p>Sorry, The Canvas element is not supported in this browser :(</p>
</canvas>
<!-- Don't load/run Javascript until Canvas has loaded -->
<script src="MontrealSymbol.js">
</script>
<br/>
<button type="button" onclick="mSymbol()">Draw the Symbol of the Greats!</button>
<button type="button" onclick="clearBoard()">Clear The Board</button>
</body>
</html>
JavaScript(Named: MontrealSymbol.js):
//test to see if we're connected.
console.log("Javascript Initialized");
//1. set up the canvas as an object with 2D context
var canvas = document.getElementById("mCanvas");
var context = canvas.getContext("2d");
//2. setting up font for later use
context.font = '24pt Verdana';
//Red Background
context.fillStyle = "#eb1919";
context.fillRect(0, 0, 320, 240);
//---------------X, Y---W, H
//White bar
context.fillStyle = "white";
context.fillRect(0, 75, 320, 85);
//Blue Bar
context.fillStyle = "blue";
context.fillRect(0, 80, 320, 75);
//border
context.fillStyle = "black";
context.fillRect(0, 0, 320, 5);
context.fillStyle = "black";
context.fillRect(0, 0, 3, 240);
context.fillStyle = "black";
context.fillRect(0, 235, 320, 5);
context.fillStyle = "black";
context.fillRect(317, 0, 3, 240);
function mSymbol(){
console.log("Drawing Montreal Canadiens Symbol");
base_image = new Image();
base_image.src = 'images/mCanadiens3.jpg';
base_image.onload = function(){
context.drawImage(base_image, 75, 62);}
}
function clearBoard(){
console.log("Clearing the Board");
context.clearRect(0, 0, 640, 480);
drawBack();
}
function drawBack(){
//Background
context.fillStyle = "#eb1919";
context.fillRect(0, 0, 320, 240);
//---------------X, Y---W, H
//layer one
context.fillStyle = "white";
context.fillRect(0, 75, 320, 85);
//layer two
context.fillStyle = "blue";
context.fillRect(0, 80, 320, 75);
//border
context.fillStyle = "black";
context.fillRect(0, 0, 320, 5);
context.fillStyle = "black";
context.fillRect(0, 0, 3, 240);
context.fillStyle = "black";
context.fillRect(0, 235, 320, 5);
context.fillStyle = "black";
context.fillRect(317, 0, 3, 240);
}
context.beginPath();
context.arc(20, 20, 10, 0, 2 * Math.PI, false);
context.fillStyle = 'black';
context.fill();
context.lineWidth = 2;
context.strokeStyle = '111';
context.stroke();
This runs fine. And I apologize that I don't have the code I've been attempting to use to do the mouse event. I've used a couple different people's ideas, but nothing seems to work. I just keep getting errors. I probably forgot something. But If someone could come up with a quick solution, What I want is a Mouse Click event that draws the last 7 lines of the JavaScript on click, and won't repeat when holding the mouse down.
HTML:
<canvas id="mCanvas" width="320" height="240" onclick="canvasClick()">
<p>Sorry, The Canvas element is not supported in this browser :(</p>
</canvas>
JavaScript:
var canvas = document.getElementById("mCanvas");
var context = canvas.getContext("2d");
function canvasClick(){
context.beginPath();
context.arc(20, 20, 10, 0, 2 * Math.PI, false);
context.fillStyle = 'black';
context.fill();
context.lineWidth = 2;
context.strokeStyle = '111';
context.stroke();
}

Categories

Resources