Can't Refer to Window Width/Height in Canvas - javascript

I'm a novice to html/css/js and am trying to learn canvas. I want to make a canvas that is the size of the window, no matter the size of the window, then I want to draw an additional rectangle within that window on which to start drawing a maze game. I got the canvas resize with window to work, but only by setting the body's overflow:hidden (when I didn't have that set, the height was always too large). I'm wondering if this is what is now causing a problem. When I try to create a smaller rectangle inside the main canvas rectangle, I set the rectangle width to half the window size but it goes far off the screen. What am I doing wrong? I just want the rectangle to be clearly within the perimeter of the main canvas so I can see all edges.
JS:
$(document).ready(function() {
var ctx;
var ww;
var wh;
drawcanvas();
$(window).resize(function() {
ctx.clearRect(0, 0, ww, wh); //won't this clear only the bottom rectangle?
drawcanvas();
});
function drawcanvas() {
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ww = window.innerWidth;
wh = window.innerHeight;
ctx.canvaswidth = ww;
ctx.canvas.height = wh;
ctx.fillStyle ="blue";
ctx.fillRect(0, 0, ww, wh);
ctx.strokeStyle = 'orange';
ctx.strokeRect(10, 20, ww/2, wh/2);
}
});
HTML:
<html>
<head>
<link href="maze2.css" rel="stylesheet" type="text/css"/>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css" type="text/css"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js" type="text/javascript" ></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js" type="text/javascript"></script>
<script src="maze2.js" type="text/javascript"></script>
<title>Maze</title>
</head>
<body>
<canvas id="canvas">Your browser does not support Canvas.</canvas>
</body>
</html>
CSS:
body {
width: 100%;
height: 100%;
margin:0px;
overflow:hidden;
}
#canvas {
width:100%;
height:100%;
margin:0px;
}

If you have set up your css correctly to have the canvas take the entire physical screen (inner screen) then the below will work.
Basically dont use window width and height, size the canvas properly with css and use the canvas clientWidth and height
$(document).ready(function() {
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var cW;
var cH;
size();
drawcanvas();
$(window).resize(function() {
size();
drawcanvas();
});
function size(){
cW = canvas.clientWidth; // if you did your css correctly this will work
cH = canvas.clientHeight;
canvas.width = cW, // if the size has changed the canvas will be blanked out automatically
canvas.height = cH;
}
function drawcanvas() {
ctx.fillStyle ="blue";
ctx.fillRect(0, 0, cW, cH);
ctx.strokeStyle = 'orange';
ctx.strokeRect(10, 20, cW/2, cH/2);
}
});
P.S. format your code better next time

Related

Keep canvas object in one place against changing size of the entire canvas

l was wondering about the logic required in-order to position a canvas object, in this instance it is a image, in the bottom right corner of the canvas persistently. l essentially need help with the canvas object staying in one place without it moving up,down,left,right due to the resizable canvas.
l also have tested using event listeners to constantly update the position of the canvas object depending on the window size of the canvas but l believe it would end up becoming an inefficient solution.
To see it working, full screen/expand the code snippet and change your window size by double clicking your browser's tab or simply resize it, then you should be able to see it in action.
var canvas = document.getElementById("c");
var ctx = canvas.getContext("2d");
var the_button = document.getElementById("the_button");
var the_background = document.getElementById("the_background");
var button_imageX = 115;
var button_imageY = 85;
window.onload = function() {
ctx.drawImage(the_background, 0, 0, canvas.width, canvas.height);
ctx.drawImage(the_button, button_imageX, button_imageY, 130, 75);
}
initialize();
function initialize() {
window.addEventListener('resize', resizeCanvas, false);
resizeCanvas();
}
function redraw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(the_background, 0, 0, canvas.width, canvas.height);
ctx.drawImage(the_button, button_imageX, button_imageY, 130, 75);
}
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
redraw();
}
html,
body {
width: 100%;
height: 100%;
margin: 0px;
border: 0;
overflow: hidden;
display: block;
}
<html>
<canvas id="c"></canvas>
<img style="display: none;" id="the_button" src="https://i.imgur.com/wO7Wc2w.png" />
<img style="display: none;" id="the_background" src="https://img.freepik.com/free-photo/hand-painted-watercolor-background-with-sky-clouds-shape_24972-1095.jpg?size=626&ext=jpg" />
</html>
This is all about rectangle geometry.
Basically the culprit is this line that is present at 2 different places.
ctx.drawImage(the_button, button_imageX, button_imageY, 130, 75);
When you want the button to be a certain fixed position when you resize, you should provide fixed values as the 2nd and 3rd params for the drawImage function.
Change it to this,
ctx.drawImage(the_button, button_imageX, canvas.height - button_imageY, 130, 75);
The 2nd param button_imageX is already fixed.
But the 3rd param is the value of y from the top of the canvas where your button should be. Not from the bottom. You must be confused with cartesian coordinate system.
So if you want your button to be always a fixed position from bottom. you should canvas.height.
So canvas.height - button_imageY means that the top left point of your button will always be button_imageY pixels above the bottom of the canvas.
You might also want to consider the height of the button, so the new 3rd parameter will become canvas.height - button_imageY - button_height
Check the snippet for full code.
var canvas = document.getElementById("c");
var ctx = canvas.getContext("2d");
var the_button = document.getElementById("the_button");
var the_background = document.getElementById("the_background");
var button_imageX = 25;
var button_imageY = 25;
window.onload = function() {
ctx.drawImage(the_background, 0, 0, canvas.width, canvas.height);
drawButton();
}
initialize();
function initialize() {
window.addEventListener('resize', resizeCanvas, false);
resizeCanvas();
}
function drawButton() {
ctx.drawImage(the_button, button_imageX, canvas.height - button_imageY - 75, 130, 75);
}
function redraw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(the_background, 0, 0, canvas.width, canvas.height);
drawButton();
}
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
redraw();
}
html,
body {
width: 100%;
height: 100%;
margin: 0px;
border: 0;
overflow: hidden;
display: block;
}
<html>
<canvas id="c"></canvas>
<img style="display: none;" id="the_button" src="https://i.imgur.com/wO7Wc2w.png" />
<img style="display: none;" id="the_background" src="https://img.freepik.com/free-photo/hand-painted-watercolor-background-with-sky-clouds-shape_24972-1095.jpg?size=626&ext=jpg" />
</html>

How to get my image drawn on a canvas proportionally, yet not leave any borders when the window is resized

I am currently in the process of making my website. I would like it to be interactive and have a nice design.
What I am currently doing is just drawing an image onto my canvas, with a bit of JavaScript that will resize my image proportionally as the window is resized. However, when I resize it to the smallest browser size, or the largest browser size, since it is proportional, it leaves a white border at the side.
I have already tried using CSS to fill the webpage by using 'width: 100%' and 'height: 100%' or 'width / height: auto' but that doesn't seem to change anything. I have also tried other resize functions (to below). but they are all very similar, if not the same.
img.onload = function () {
ctx.canvas.width = img.width;
ctx.canvas.height = img.height;
ctx.drawImage(img, 0, 0);
resize();
};
function resize()
{
var ratio = canvas.width / canvas.height;
var canvas_height = window.innerHeight;
var canvas_width = canvas_height * ratio;
if(canvas_width>window.innerWidth)
{
canvas_width=window.innerWidth;
canvas_height=canvas_width/ratio;
}
canvas.style.width = canvas_width + 'px';
canvas.style.height = canvas_height + 'px';
}
Taken from: https://codepen.io/anon/pen/VNjwYE
What should happen is that the image takes up the whole canvas with no borders at the sides. However, as I said, there are white borders at the side of image.
This imgur album has two screenshots of the problem. https://imgur.com/a/CDbKGjL
The rest of the code (i.e. CSS and HTML) can be found on my Codepen: https://codepen.io/DreamingInsanity/pen/aPoJEK
Thanks,
Dream.
just add body{ margin:0px; } in your css,
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var img = new Image();
img.src = "https://source.unsplash.com/2000x1000/?trees,nature,forest";
img.onload = function () {
ctx.canvas.width = img.width;
ctx.canvas.height = img.height;
ctx.drawImage(img, 0, 0);
resize();
};
function resize() {
var ratio = canvas.width / canvas.height;
var canvas_height = window.innerHeight;
var canvas_width = canvas_height * ratio;
if(canvas_width>window.innerWidth)
{
canvas_width=window.innerWidth;
canvas_height=canvas_width/ratio;
}
canvas.style.width = canvas_width + 'px';
canvas.style.height = canvas_height + 'px';
}
window.onresize = resize;
html, body {
background-color: #1A1919;
overflow-x: hidden;
overflow-y: hidden;
margin: 0px;// do it
}
#canvas {
width: auto;
height: auto;
filter: grayscale(0%);
}
#top_bar {
background-color: transparent;
position: absolute;
width: 100%;
height: 80px;
top: 0px;
}
<html>
<head runat="server">
<title>My Website</title>
<link rel="stylesheet" type="text/css" href="Home/Stylesheet.css">
<link rel="stylesheet" type="text/css" href="Home/Buttons.css" />
</head>
<body>
<canvas id="canvas"></canvas>
<script src="Scripts/Canvas.js"></script>
<div id="top_bar"></div>
</body>
</html>
I changed what code editor I was using and at the same time, neetened up my file structure. As you can see in the HTML I am looking for the CSS under /Home/ whereas now, I am looking for it under /CSS/.

Avoiding Javascript Memory Leaks from the Creation of Canvas

I have some HTML and Javascript code that draws a 2D canvas in the page. In the task manager, I can see memory increasing rapidly until the web page freezes.
Please let me know how I can prevent memory leaks or provide me with some alternative code that is able to draw canvas on the browser without creating such leaks.
function setup() {
// insert setup code here
}
function draw() {
// insert drawing code here
var canvas = document.createElement('canvas');
canvas.id = "CursorLayer";
canvas.width = 1224;
canvas.height = 600;
canvas.style.zIndex = 8;
canvas.style.position = "absolute";
canvas.style.border = "1px solid";
document.body.appendChild(canvas);
var c2 = canvas.getContext('2d');
var centerX=canvas.width/2-100;
var centerY=canvas.height/2-100;
c2.fillStyle = '#696969';
c2.beginPath();
c2.moveTo(centerX, centerY);
c2.lineTo(centerX+200,centerY);
c2.lineTo(centerX+200, centerY+200);
c2.lineTo(centerX, centerY+200);
c2.closePath();
c2.fill();
// adding source location
var ctx = canvas.getContext("2d");
ctx.fillStyle = '#008000';
ctx.beginPath();
ctx.arc( 20, canvas.height-20, 10, 0, 2 * Math.PI);
ctx.stroke();
ctx.closePath();
ctx.fill();
// adding destination location
var ctx1 = canvas.getContext("2d");
ctx1.fillStyle = '#f00';
ctx1.beginPath();
ctx1.arc( canvas.width-20, 20, 10, 0, 2 * Math.PI);
ctx1.stroke();
ctx1.closePath();
ctx1.fill();
}
<!DOCTYPE html>
<html>
<head>
<title>Robot Path Planning</title>
<style>
body {
padding: 0;
margin: 0;
}
</style>
<script src="../p5.min.js"></script>
<script src="../addons/p5.dom.min.js"></script>
<script src="../addons/p5.sound.min.js"></script>
<script src="sketch.js"></script>
</head>
<body>
</body>
</html>
Browser
Memory consumption
Apparently your code is creating a new canvas entity for each draw call and this doesn't make sense.
You should instead create the canvas only once and then just do drawing on it in the draw call. If you need to clear the previous frame you can just reset the width/height properties or call clearRect.

How to detect if a mouse pointer hits a line already drawn on an HTML 5 canvas

I am trying to figure out how one can detect if the user's mouse hits a line on an HTML 5 canvas with jQuery.
Here is the code that generates the canvas lines:
<canvas id="myCanvas" width="400" height="400" style="border:1px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>
<script type="text/javascript" src="js/jquery-1.4.2.min.js"></script>
<script type="text/javascript">
window.onload = function(){
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.moveTo(40,0);
ctx.lineTo(40,360);
ctx.stroke();
ctx.moveTo(80,400);
ctx.lineTo(80,40);
ctx.stroke();
ctx.moveTo(120,0);
ctx.lineTo(120,360);
ctx.stroke();
ctx.moveTo(160,400);
ctx.lineTo(160,40);
ctx.stroke();
};
</script>
I'm using a modified jQuery script that I actually found in another question on here, but now I can't figure out how to detect the line, mainly the difference in color from white to black, in the canvas. I know that this can be done with images, but I haven't seen anyone with something like this.
I guess my real question is, is there a way to detect color changes on a canvas element with jQuery?
Its possible to do with javascript. In fact you aren't using any jQuery in your example above. An easy way to do it is by grabbing the pixel data from the canvas, and checking the alpha at the specified x and y position. If the alpha isn't set to 0, then you have something drawn on the canvas. Below is a function I put together real quick that does that.
Live Demo
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
width = 400;
height = 400;
canvas.width = canvas.height = 200;
// draw
ctx.moveTo(40, 0);
ctx.lineTo(40, 360);
ctx.stroke();
ctx.moveTo(80, 400);
ctx.lineTo(80, 40);
ctx.stroke();
ctx.moveTo(120, 0);
ctx.lineTo(120, 360);
ctx.stroke();
ctx.moveTo(160, 400);
ctx.lineTo(160, 40);
ctx.stroke();
function detectLine(x, y) {
var imageData = ctx.getImageData(0, 0, width, height),
inputData = imageData.data,
pData = (~~x + (~~y * width)) * 4;
if (inputData[pData + 3]) {
return true;
}
return false;
}
canvas.addEventListener("mousemove", function(e){
var x = e.pageX,
y = e.pageY;
console.log(detectLine(x, y));
});
console.log(detectLine(40, 100));
console.log(detectLine(200, 200));

Make canvas fill the whole page

How can I make canvas be 100% in width and height of the page?
Well I have it working here: Are Google's Bouncing Balls HTML5? by using the following CSS:
* { margin: 0; padding: 0;}
body, html { height:100%; }
#c {
position:absolute;
width:100%;
height:100%;
}
Where #c is the id of the canvas element.
you can use these codes without jquery
var dimension = [document.documentElement.clientWidth, document.documentElement.clientHeight];
var c = document.getElementById("canvas");
c.width = dimension[0];
c.height = dimension[1];
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
maybe that easy?
This has something to do with <canvas> tag.
when create fullscreen canvas, <canvas> will cause scrollbar if not set to display:block.
detail: http://browser.colla.me/show/canvas_cannot_have_exact_size_to_fullscreen
You can programatically set the canvas width + height:
// Using jQuery to get window width + height.
canvasObject.width = $(window).width();
canvasObject.height = $(window).height();
I've tested this and it as long as you redraw what's on the canvas after you've resized it won't change the scaling.
on my observations this runs effectively, and gives a blue shade
var c = document.getElementById('can');
var ctx = canvas.getContext('2d');
ctx.rect(0, 0, canvas.width, canvas.height);
// add linear gradient
var g = ctx.createLinearGradient(0, 0, c.width, c.height);
// light blue color
g.addColorStop(0, '#8ED6FF');
// dark blue color
g.addColorStop(1, '#004CB3');
context.fillStyle = g;
context.fill();
<script>
var c = document.getElementById('can');
var ctx = canvas.getContext('2d');
ctx.rect(0, 0, canvas.width, canvas.height);
// add linear gradient
var g = ctx.createLinearGradient(0, 0, c.width, c.height);
// light blue color
g.addColorStop(0, '#8ED6FF');
// dark blue color
g.addColorStop(1, '#004CB3');
context.fillStyle = g;
context.fill();
</scrip
html,body
{
height:98.0%;
width:99.5%;
}
canvas
{
display:block;
width:100%;
height:100%;
}
<html>
<body>
<canvas id="can"></canvas>
</body>
</html>
Does this work for you?
<html>
<body style="height: 100%; margin: 0;">
<canvas style="width: 100%; height: 100%;"></canvas>
</body>
</html>
from Force canvas element in html to take up the entire window?

Categories