The Menu
I want to make it so when the user clicks play it takes you to another HTML page. I have placed a rect over the play area and want to make it so the rect is what the user is clicking as the play text is part of a single image.
This is the JS for my rect:
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
// Red rectangle
ctx.beginPath();
ctx.lineWidth = "6";
ctx.strokeStyle = "red";
ctx.rect(125, 140, 230, 90);
ctx.stroke();
You can achieve it like this
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var img = new Image();
img.onload = draw;
function draw() {
canvas.width = this.width;
canvas.height = this.height;
ctx.drawImage(this, 0, 0);
ctx.beginPath();
ctx.lineWidth = "6";
ctx.strokeStyle = "red";
ctx.rect(101, 114, 184, 71);
ctx.stroke();
}
img.src = 'https://i.stack.imgur.com/M3x29.jpg';
canvas.onclick = function(e) {
if (e.offsetX > 102 && e.offsetX < 286 && e.offsetY > 110 && e.offsetY < 182) {
window.location = 'http://stackoverflow.com'; // another html page location
}
};
<canvas id="canvas"></canvas>
Related
I want zoom images, lines, and text drawn on a canvas
Click plus button > zoom in
Click minus button > zoom out
I tried scale but only the image got bigger.
test.html
<canvas id="img"></canvas>
<input type="button" id="plus" value="plus">
<input type="button" id="minus" value="minus">
<script>
const canvas = document.getElementById('img');
const ctx = canvas.getContext('2d');
const img = new Image();
img.src = 'test.PNG';
img.onload = function() {
canvas.height = img.height;
canvas.width = img.width;
ctx.drawImage(img, 0, 0);
ctx.lineWidth = 3;
ctx.strokeStyle = 'red';
ctx.strokeRect(28, 26, 50, 50);
ctx.textBaseline = 'top';
ctx.font="15px Verdana";
ctx.fillStyle = 'red';
ctx.fillText("TEXT", 28, 25 + 50 + 5);
ctx.fill();
ctx.scale(2,2);
ctx.restore();
};
</script>
<script>
const plus = document.getElementById('plus');
const minus = document.getElementById('minus');
</script>
The problem is - as Kaiido implied in his comment - that the scale() method doesn't affect anything thas has been drawn onto the canvas prior the call to scale.
If you really want a context.scale driven zoom function you will have to redraw anything after calling scale.
Here's an example:
const canvas = document.getElementById('img');
const ctx = canvas.getContext('2d');
function zoomIn() {
myScale = myScale < 2.5 ? myScale += 0.5 : 2.5;
draw();
}
function zoomOut() {
myScale = myScale > 0.5 ? myScale -= 0.5 : 0.5;
draw();
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
ctx.translate(canvas.width / 2 - canvas.width / 2 * myScale, canvas.height / 2 - canvas.height / 2 * myScale);
ctx.scale(myScale, myScale);
ctx.drawImage(img, 0, 0);
ctx.lineWidth = 3;
ctx.strokeStyle = 'red';
ctx.strokeRect(28, 26, 50, 50);
ctx.textBaseline = 'top';
ctx.font = "15px Verdana";
ctx.fillStyle = 'red';
ctx.fillText("TEXT", 28, 25 + 50 + 5);
ctx.fill();
ctx.restore();
}
var img = new Image();
var myScale = 1;
img.onload = function() {
canvas.height = img.height;
canvas.width = img.width;
draw();
};
img.src = 'https://picsum.photos/id/1/200/300';
const plus = document.getElementById('plus');
const minus = document.getElementById('minus');
plus.addEventListener("click", zoomIn);
minus.addEventListener("click", zoomOut);
<canvas id="img"></canvas>
<input type="button" id="plus" value="plus">
<input type="button" id="minus" value="minus">
I have a canvas in my HTML id="myCanvas" and a button when clicked calls this function:
function writeCanvas(){
var can = document.getElementById("myCanvas");
var ctx = can.getContext("2d");
var xPos = 50;
var yPos = 50;
window.addEventListener('click', moveIt, true);
ctx.fillStyle= "red";
ctx.font = "30px Arial";
ctx.fillText("Kunal Sharma", xPos, yPos);
}
How do I make it so that each time the button is clicked the text moves right or down?
Here is a simple example:
<button onclick="drawText()">Move Text</button><br>
<canvas id="myCanvas"></canvas>
<script>
var can = document.getElementById("myCanvas");
var ctx = can.getContext("2d");
var xPos = 10;
var yPos = 20;
function drawText() {
xPos += 10
yPos += 10
ctx.clearRect(0, 0, 999, 999)
ctx.fillStyle = "red";
ctx.font = "30px Arial";
ctx.fillText("Kunal Sharma", xPos, yPos);
}
drawText()
</script>
The idea is to change the xPos & yPos inside the function.
And we clear and redraw on every call to drawText.
I am working on a project where user upload structural diagram(engineering diagram). When I user double click on the intended location on canvas the speech to text engine turns on and listen for user comments and then it draw a small circle with different colors and fill text (count) on that location. I am saving comments, counts, coordinates of arc and other things in react state and displaying the list in a component with edit and delete button. When user press the delete button. comment and other property gets deleted from the state.
I want to remove the drawn arc from the canvas. How can I do it?
I have tried clearRect. But it is not working in this case.
Please let me know.
componentDidMount() {
const img = this.refs.image;
const canvas = this.refs.canvas;
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
img.onload = () => {
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
ctx.font = "40px Courier";
ctx.fillText('Drawing 1', 200, 100);
}
}
drawCircle(x, y, getcolor) {
const canvas = this.refs.canvas;
const ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.arc(x, y, 8, 0, Math.PI * 2, false);
ctx.strokeStyle = "black";
ctx.stroke();
ctx.fillStyle = getcolor;
ctx.fill();
ctx.closePath();
// Text
ctx.beginPath();
ctx.font = "20px Arial"
ctx.fillStyle = "#00538a";
ctx.textAlign = "center";
ctx.fillText(this.state.count, x , y - 20);
ctx.fill();
ctx.closePath();
}
remove(id) {
this.setState({
comments: this.state.comments.filter(c => c.id !== id)
});
const canvas = this.refs.canvas;
const ctx = canvas.getContext('2d');
const arc = this.state.comments.filter(c => c.id === id);
let x = arc[0].coordinates.x;
let y = arc[0].coordinates.y
console.log("TCL: Drawing -> remove -> arc", arc[0].coordinates);
ctx.beginPath();
ctx.arc(x, y, 8, 0, Math.PI * 2, false);
ctx.clip();
ctx.clearRect(x-8, y-8, 16,16);
}
Thanks
Meet
As I mentioned in my comments the way you're trying to remove a circle from the canvas ain't gonna work.
If you call clearRect() on the canvas, it will essentially overwrite the target area including your original background image.
Instead you need to keep track of the circles - more precisely the position at which those should be drawn - using an array.
If you click the canvas -> add a circle element to an array -> clear the canvas -> draw the diagram again -> loop over the array to draw the circles on top
If you click the remove button of a circle -> search the array for this particular circle -> remove it from the array -> clear the canvas -> draw the diagram again -> loop over the array to draw the circles on top
Here's an example to illustrate what I'm talking about:
var comments = new Array();
var canvas = document.createElement("canvas");
canvas.style="float:left;"
canvas.width = 400;
canvas.height = 200;
document.body.appendChild(canvas);
var ctx = canvas.getContext("2d");
function updateCanvas() {
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
ctx.font = "40px Courier";
ctx.fillText('Drawing 1', 200, 100);
for (var a = 0; a < comments.length; a++) {
ctx.beginPath();
ctx.arc(comments[a].x, comments[a].y, 8, 0, Math.PI * 2, false);
ctx.strokeStyle = "black";
ctx.stroke();
ctx.fillStyle = "black";
ctx.fill();
ctx.closePath();
}
}
var img = new Image();
img.onload = () => {
updateCanvas();
}
img.src = "https://picsum.photos/id/59/400/200";
function addCircle(e) {
var div = document.createElement("div");
div.innerHTML = "remove" + comments.length;
document.body.appendChild(div);
div.addEventListener("click", function(e) {
for (var a = 0; a < comments.length; a++) {
if (comments[a].div == e.target) {
comments.splice(a, 1);
break;
}
}
document.body.removeChild(e.target);
updateCanvas();
});
comments.push({
x: e.clientX,
y: e.clientY,
div: div
});
updateCanvas();
}
canvas.addEventListener("click", addCircle);
Everytime you click on the picture a 'remove' div will be created to the right of the canvas. if you click it, the associated circle will be removed.
I'm trying to just make a rectangle but nothing will appear, just the background. I've tried ctx.fill, ctx.fillStyle etc. nothing works:
I'm refering to this part
fill(77, 66, 66);
rect(10,200,100,100);
Here is the whole code for the page
var ctx, W, H;
window.onload = function() {
var canvas = document.getElementById("canvas");
W = window.innerWidth;
H = window.innerHeight;
canvas.width = W;
canvas.height = H;
ctx = canvas.getContext("2d");
setInterval(draw, 1);
function draw() {
ctx.globalCompositeOperation = "source-over";
ctx.fillStyle = "#E6E6FF"; // this part does appear
ctx.fillRect(0, 0, W, H);
fill(77, 66, 66); // this doesn't appear
rect(10,200,100,100);
}
}
Thanks
You need to call fill and rect on the canvas context.
Also you need to change the fillStyle otherwise you're drawing a rectangle with the same color as the background and it won't show.
var ctx, W, H;
window.onload = function() {
var canvas = document.getElementById("canvas");
W = window.innerWidth;
H = window.innerHeight;
canvas.width = W;
canvas.height = H;
ctx = canvas.getContext("2d");
setTimeout(draw, 1);
function draw() {
ctx.globalCompositeOperation = "source-over";
ctx.fillStyle = "#E6E6FF";
ctx.fillRect(0, 0, W, H);
ctx.fillStyle = "red"; // need this otherwise the rect will be the same color as the background
ctx.rect(10, 200, 100, 100); // needs to be called on the canvas context
ctx.fill(); // needs to be called on the canvas context, it will fill any path not already filled in.
}
}
You are filling both areas with the same color, and you have to use the context to perform fill functions. you also need to create the rect BEFORE you fill it.
Try this on for size: https://jsfiddle.net/szbk6f67/3/
var ctx, W, H;
window.onload = function () {
var canvas = document.getElementById("canvas");
W = 400;
H = 400;
canvas.width = W;
canvas.height = H;
ctx = canvas.getContext("2d");
setInterval(draw, 1);
function draw() {
ctx.globalCompositeOperation = 'source-over';
ctx.fillStyle = 'gray';
ctx.fillRect(0, 0, W, H);
ctx.fillStyle = 'black';
ctx.rect(10, 200, 100, 100);
ctx.fill();
}
}
I have a canvas element:
<canvas id="canvas" width="100" height="100"></canvas>
And some JavaScript to make canvas full screen:
var canvas, ctx, w, h;
function start() {
canvas = $("#canvas")[0];
ctx = canvas.getContext("2d");
w = $('body').innerWidth();
$("#canvas").width(w);
$("#canvas").height(w);
w = $("#canvas").width();
h = $("#canvas").height();
if(typeof game_loop != "undefined") clearInterval(game_loop);
game_loop = setInterval(paint, 60);
}
function paint() {
ctx.fillStyle = "white";
ctx.fillRect(0, 0, w, h);
ctx.strokeStyle = "blue";
ctx.strokeRect(0, 0, 50, 50);
}
I don't know why I get one big square not 50x50. Can you help?
To actually resize the canvas (as in have more pixles) you'll need to set the width/height attributes. jQuerys width()/height() sets the css values. Resulting in a stretched canvas element consisting of the same number of pixels as before. Instead use:
$('#canvas').prop({
width: 400, // the 400 is just arbitrary
height: 400
});
Or, as per Alnitaks comment, you could of course just as well assign the values directly:
canvas.width = 400;
canvas.height = 400;
Here is a simple example of drawing a square on resize using width/height.
Example: http://jsfiddle.net/Ubv7X/
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var paint = function() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// Draw background
ctx.fillStyle = 'rgb(255, 255, 255)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Draw rect
var rect_size=50;
ctx.fillStyle = 'rgb(0, 0, 255)';
ctx.fillRect(canvas.width/2-(rect_size/2), canvas.height/2-(rect_size/2),
rect_size, rect_size);
}
setInterval(paint, 60);