HTML5 Canvas Draw Rect - Got Border of Diff Width? - javascript

The result of the square border turns out to be different width, it seems that the right and the bottom border's width is 2x wider than the left and the top border's width. Why so weird? I want the border of all sides to have the same width.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>HTML5 Test</title>
<script type="text/javascript">
function draw () {
var canvas = document.getElementById('rectangle');
var ctx = canvas.getContext('2d');
ctx.save();
ctx.lineWidth = 30;
ctx.fillStyle = "black";
ctx.fillRect(0,0,100,100);
ctx.strokeStyle = "red";
ctx.strokeRect(0,0,100,100);
ctx.restore();
}
</script>
</head>
<body onload="draw()">
<canvas id="rectangle"></canvas>
</body>
</html>

That's because your border is being cut off at the top and the left, because that's where the canvas starts, and if your rectangle starts at (0,0), the left border's left end's x co-ordinate will be -30.
Make the starting co-ordinates anything above 30 (so that the end of your borders aren't negative), and it'll work fine.
Demo

Related

gpu.js how to find needed pixels in a canvas by rgb?

I'm new to image processing. I found the "gpu.js" package and it seems to be very powerful for any kind of image operations in the browser, but there is not much information on google about it and I don't understand how to use it properly.
What I'm trying to do now: I've drawn a canvas with a black (0,0,0) background. I also overlaid a few pixels of different colors on it. I want to get the coordinates (x, y) of all exact RGB pixels on the canvas but I am stuck on this and I don't even see is it possible.
The code for canvas:
const draw = async () => {
const canvas = document.createElement('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
canvas.style.backgroundColor = 'rgb(0,0,0)'
document.body.appendChild(canvas);
const ctx = canvas.getContext('2d');
ctx.fillStyle = "rgb(234,0,255)";
ctx.fillRect(100,100,1,1);
ctx.fillStyle = "rgb(0,0,255)";
ctx.fillRect(600,600,1,1);
ctx.fillStyle = "rgb(0,255,0)";
ctx.fillRect(600,450,1,1);
ctx.fillStyle = "rgb(0,254,253)";
ctx.fillRect(230,230,1,1);
ctx.fillStyle = "rgb(140,8,9)";
ctx.fillRect(230,118,1,1);
}
draw();
const gpu = new GPU({mode: "gpu"});
* {
margin: 0;
padding: 0;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>GPU</title>
<script src="https://cdn.jsdelivr.net/npm/gpu.js#latest/dist/gpu-browser.min.js"></script>
<style>
</style>
</head>
<body>
</body>
</html>
For example I'd like to find coordinates of pixels with colors rgb(234,0,255) and rgb(140,8,9)
What should I do to achieve it?

canvas.fillRect not displaying rectangle on browser window [duplicate]

This question already has answers here:
Size of HTML5 Canvas via CSS versus element attributes
(3 answers)
Closed 2 years ago.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Archade!</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div style="text-align: center;">
<canvas id="gameCanvas"></canvas>
</div>
<script>
var canvas;
var canvasContext;
window.onload = function () {
console.log("Game working!");
canvas = document.getElementById("gameCanvas");
canvasContext = canvas.getContext("2d");
canvasContext.fillStyle = "black";
canvasContext.fillRect(0, 0, canvas.width, canvas.height);
console.log("Loading red box");
canvasContext.fillStyle = "red";
canvasContext.fillRect(500, 500, 50, 25);
console.log("Red box should be loaded!");
};
</script>
</body>
</html>
This is my html code, [ in style.css i've just set width and height of the canvas ].
The black canvas is being displayed on the screen but the red box isn't displayed anywhere.
The console log above and below the red rectangle is also working fine.
Please help me fix this! I want the red rectangle to be displayed as well.
Thanks for your time :)
From this reference - https://www.w3schools.com/tags/canvas_fill.asp
You can do the following:
First draw the rectangle.
Then, set the fillStyle.
Then fill the rectangle.
Check the code below:
var canvas;
var canvasContext;
window.onload = function() {
console.log("Game working!");
canvas = document.getElementById("gameCanvas");
canvasContext = canvas.getContext("2d");
canvasContext.rect(0, 0, canvas.width, canvas.height);
canvasContext.fillStyle = "black";
canvasContext.fill();
console.log("Loading red box");
canvasContext.rect(500, 500, 50, 25);
canvasContext.fillStyle = "red";
canvasContext.fill();
console.log("Red box should be loaded!");
};
<div style="text-align: center;">
<canvas id="gameCanvas"></canvas>
</div>
Setting the canvas size in css might not be enough.
Try also setting the width/height attributes of the canvas element.
For example:
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
I think the red rectangle isn't displayed because it's position exceeds the default size of a canvas.

HTML5 Canvas: Replace Cursor with Crossing Lines

I'm trying to replace my cursor within the canvas with two perpendicular lines: one horizontal and one vertical. Example here: http://imgur.com/tUBkQn8
I need to do three things
1) Hide the cursor
2) Draw the crossing lines
3) Erase old lines on mouse move and draw new lines based on new mouse location
The following code is a non-performant way of achieving #2 and #3 (it's incredibly slow re-rendering the entire canvas every time the mouse moves):
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
canvas.addEventListener('mousemove', function(evt) {
// clear the canvas
ctx.clearRect(0, 0, xsize, ysize);
// re-draw the base
drawCanvas();
var mousePos = getMousePos(canvas, evt);
// draw vertical line
ctx.beginPath();
ctx.moveTo(mousePos.x,0);
ctx.lineTo(mousePos.x,ysize);
ctx.stroke();
ctx.closePath();
// draw horizontal line
ctx.beginPath();
ctx.moveTo(0,mousePos.y);
ctx.lineTo(xsize,mousePos.y);
ctx.stroke();
ctx.closePath();
}, false);
So my questions:
1) How do I hide the cursor but still display the lines?
2) Is there a way I can just re-render the crossing lines ONLY, rather than the whole canvas every time the mouse moves? Thanks!
Here's one way to create a custom cursor and maintain performance:
Create a second canvas on top of your main drawing canvas.
Hide the system mouse cursor on both the canvases.
Draw/Move your X-cursor and nothing else on the top canvas
Example code and a Demo: http://jsfiddle.net/m1erickson/abokzhn6/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
#wrapper{position:relative;}
#canvas,#cursor{position:absolute; cursor:none;}
#canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("cursor");
var ctx=canvas.getContext("2d");
var $canvas=$("#cursor");
var canvasOffset=$canvas.offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
$("#cursor").mousemove(function(e){handleMouseMove(e);});
function handleMouseMove(e){
e.preventDefault();
e.stopPropagation();
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.beginPath();
ctx.moveTo(mouseX,mouseY-15);
ctx.lineTo(mouseX,mouseY+15);
ctx.moveTo(mouseX-15,mouseY);
ctx.lineTo(mouseX+15,mouseY);
ctx.stroke();
}
}); // end $(function(){});
</script>
</head>
<body>
<div id='wrapper'>
<canvas id="canvas" width=300 height=300></canvas>
<canvas id="cursor" width=300 height=300></canvas>
</div>
</body>
</html>
Ad 1
I didn't test it but I think that you can hide cursor by changing cursor image in CSS to white 1x1 image.
Ad 2
Use http://kineticjs.com/

Canvas and events

Please help me to understand the events of the canvas.
Take for example two of the square. Each has its own area where you need to process such events:
Hover the square fills it with colour.
Click invokes filling the square third color and displays in a separate block, for example, the ID of the square.
Accordingly, it is possible to work with only one square. Click on the second square will reset the first square and output data from the second.
While moving the mouse in the area of one of the squares near the mouse, a pop-up window that displays the ID of the square.
And how can I make a link to a separate square? That is, to the user clicks a link that invokes the event, similar to a click on a separate square.
HTML code
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript" src="scripts/canvas.js"></script>
<script>
window.onload = function()
{
drawCanvas('mainCanvas');
};
</script>
</head>
<body style="margin: 0px;">
<canvas id="mainCanvas" width="300" height="200"></canvas>
<aside>ID of the square</aside>
</body>
</html>
JS code
function makeRect(x, y, w, h)
{
return { x: x, y: y, w: w, h: h };
}
function drawCanvas(canvasId)
{
//// General Declarations
var canvas = document.getElementById(canvasId);
var context = canvas.getContext('2d');
//// Color Declarations
var blackColor = 'rgba(0, 0, 0, 1)';
var whiteColor = 'rgba(255, 255, 255, 1)';
//// Frames
var frameOne = makeRect(64, 70, 50, 50);
var frameTwo = makeRect(194, 70, 50, 50);
//// RectangleOne Drawing
context.beginPath();
context.rect(frameOne.x, frameOne.y, 50, 50);
context.fillStyle = whiteColor;
context.fill();
context.strokeStyle = blackColor;
context.lineWidth = 1;
context.stroke();
//// RectangleTwo Drawing
context.beginPath();
context.rect(frameTwo.x, frameTwo.y, 50, 50);
context.fillStyle = whiteColor;
context.fill();
context.strokeStyle = blackColor;
context.lineWidth = 1;
context.stroke();
}
You ask a really broad question!
This will get you started:
About canvas rectangles
When you draw a rect on the canvas it becomes just “painted pixels” (like a painting of a rectangle on an artists canvas).
Nothing about the rect is “remembered” by canvas.
This means you can’t hit-test the rect to see if your mouse is hovering over that rect. The canvas doesn’t know anything about your rect.
Keeping track of rectangles
You must keep track of each rect’s properties yourself (x-coordinate, y-coordinate, width, height, color).
A convienient way to do this is creating a javascript object with the rect’s properties:
var rect1 = { x:30, y:30, width:50, height:25, color:"blue" };
Then use this rect1 object to draw the rect on your canvas
context.fillStyle=rect1.color;
context.fillRect( rect1.x, rect1.y, rect1.width, rect1.height );
Now you can always refer to rect1 to get the properties of your rectangle.
Mouse events
The canvas mouse events always relate to the canvas element itself, never to a rect drawn on the canvas.
Here’s how to listen to the mouse events on canvas:
// use jQuery to ask the browser to call `handleMouseMove` whenever the mouse is moved
$("#canvas").mousemove(function(e){handleMouseMove(e);});
// this is called every time your mouse moves
function handleMouseMove(e){
// get the mouses current X,Y position
// Note: offsetX/offsetY -- you must adjust for the offset of the canvas relative to the web page
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
}
Testing if the mouse is inside the rect
Remember that canvas knows nothing about your rect1, so use the rect1 object to “hit-test” whether the mouse is inside rect1:
if(
mouseX>=rect1.x &&
mouseX<=rect1.x+rect1.width &&
mouseY>=rect1.y &&
mouseY<=rect1.y+rect1.height
){
// the mouse is inside rect1
ctx.fillStyle="red";
ctx.fillRect(rect1.x,rect1.y,rect1.width,rect1.height);
}else{
// the mouse is not inside rect1
ctx.fillStyle=rect1.color;
ctx.fillRect(rect1.x,rect1.y,rect1.width,rect1.height);
}
This introduction should get you started coding…experiment for yourself!
Here’s a working demo: http://jsfiddle.net/m1erickson/tPjWX/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
#canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var $canvas=$("#canvas");
var canvasOffset=$canvas.offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var rect1 = { x:30, y:30, width:50, height:25, color:"blue" };
ctx.fillStyle=rect1.color;
ctx.fillRect(rect1.x,rect1.y,rect1.width,rect1.height);
function handleMouseMove(e){
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
if(
mouseX>=rect1.x &&
mouseX<=rect1.x+rect1.width &&
mouseY>=rect1.y &&
mouseY<=rect1.y+rect1.height
){
ctx.fillStyle="red";
ctx.fillRect(rect1.x,rect1.y,rect1.width,rect1.height);
}else{
ctx.fillStyle=rect1.color;
ctx.fillRect(rect1.x,rect1.y,rect1.width,rect1.height);
}
}
$("#canvas").mousemove(function(e){handleMouseMove(e);});
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
Canvas is only an element.
You can catch event for all canvas not for squares, circle, line...
But you can hold the position of square , line, circle and check "if ( mouse's position in square position) and redraw canvas
Personally, you can try to use SVG and you can catch the events for individual element.

Mouse position within HTML 5 Canvas

I am writing a simple drawing app to get an understanding of the HTML 5 canvas. The problem is that I simply can't seem to get the correct mouse position within the canvas element.I've looked at the other questions on stackoverflow like the one here getting mouse position with javascript within canvas that address this issue but their solutions don't seem to help me.
Here is my code:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Untitled Document</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js" type="text/javascript"></script>
<style type="text/css">
#test {
border: solid black 1px;
width: 500px;
height: 500px;
}
</style>
<script type="text/javascript">
$(function(){
var canvas=document.getElementById('test');
if(canvas.getContext){
var ctx =canvas.getContext('2d');
var draw = false;
ctx.strokeStyle = "rgb(200,0,0)";
ctx.lineWidth = 3;
ctx.lineCap = "round";
$('#test').mousedown(function(){draw=true;});
$('#test').mouseup(function(){draw=false;});
$('#test').mousemove(function(e){
if(draw){
var x , y;
x = e.layerX;
y = e.layerY;
ctx.moveTo(x,y);
ctx.lineTo(x+1,y+1);
ctx.stroke();
}
});
}
});
</script>
</head>
<body>
<canvas id="test"></canvas>
</body>
</html>
What am I doing wrong here? I have tested this in both Chrome/Firefox.
Your canvas is missing width and height properties. In the current solution it just scales the default to fit your CSS. This in turn breaks your mouse coords. Try something along
<canvas id="test" width=500 height=500></canvas>
as your canvas markup.
Suppose your canvas has already been declared...
var Mouse = { //make a globally available object with x,y attributes
x: 0,
y: 0
}
canvas.onmousemove = function (event) { // this object refers to canvas object
Mouse = {
x: event.pageX - this.offsetLeft,
y: event.pageY - this.offsetTop
}
}
Mouse will update when you mouse move on the canvas
You should add pixel dimenstion to your canvas element:
<canvas id="test" width='500px' height='500px' ></canvas>
Here is working example - http://jsfiddle.net/gorsky/GhyPr/.

Categories

Resources