Error when trying to make a canvas - javascript

I'm trying to use <canvas> to construct a grid. Please note - the code below is not my code and I remember finding it on stack overflow somewhere:
Here is my error:
Cannot call method 'getContext' of undefined
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
body {
background: lightblue;
}
canvas {
background: #fff;
margin: 20px;
}
</style>
<!-- JQ Lib -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js"></script>
<script type="text/javascript">
//grid width and height
var bw = 400;
var bh = 400;
//padding around grid
var p = 10;
//size of canvas
var cw = bw + (p*2) + 1;
var ch = bh + (p*2) + 1;
var canvas = $('#canvas').attr({width: cw, height: ch}).appendTo('body');
var context = canvas.get(0).getContext("2d");
function drawBoard(){
for (var x = 0; x <= bw; x += 40) {
context.moveTo(0.5 + x + p, p);
context.lineTo(0.5 + x + p, bh + p);
}
for (var x = 0; x <= bh; x += 40) {
context.moveTo(p, 0.5 + x + p);
context.lineTo(bw + p, 0.5 + x + p);
}
context.strokeStyle = "black";
context.stroke();
}
drawBoard();
</script>
</head>
<body>
<canvas id="canvas"> </canvas>
</body>
</html>
The error is originating on this line:
var canvas = $('#canvas').attr({width: cw, height: ch}).appendTo('body');
I have tried many different ways of doing this, but I keep getting the above error. Am I just making a mindless mistake here?

You haven't defined $, which is a common (but meaningless) variable name used by a variety of different libraries including Protoype.js, Mootools and jQuery.
That syntax looks like jQuery so you will need to include the script for that library or rewrite it using built-in functions.

Related

Trying to get javascript to animate a canvas element on the click of a button. But the canvas shows itself for a second and then disappears.

The code I'm using is :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>I don't know</title>
</head>
<body>
<p>What do you want? Max Limit. 100 X 100 . 0 for white. 1 for black. enter for newline</p>
<form id="main">
<input type="text" name="string"><br>
<button onclick="drawBoard()">Click Me</button>
</form>
<br>
<canvas id="canvas" width="420px" height="420px" style="background: #fff; margin:20px"></canvas>
<script>
function drawBoard(){
var bw = 400;
// Box height
var bh = 400;
// Padding
var p = 0;
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
for (var x = 0; x <= bw; x += 40) {
context.moveTo(0.5 + x + p, p);
context.lineTo(0.5 + x + p, bh + p);
}
for (var x = 0; x <= bh; x += 40) {
context.moveTo(p, 0.5 + x + p);
context.lineTo(bw + p, 0.5 + x + p);
}
context.strokeStyle = "black";
context.stroke();
}
</script>
</body>
</html>
When I click on the button, the grid shows itself for a second and then disappears. What is causing the issue?
When I opened console view, I saw an error stating "Failed to execute ‘postMessage’ on ‘DOMWindow’: The target origin provided (‘null’) does not match the recipient window’s origin (‘null’)."
When you submit a form, the page will reload as part of the submit process. You either need to prevent this default behavior with JavaScript...
function drawBoard(e){
e.preventDefault() // stops default form submission
...
}
or just remove that form element. For just a button click with no inputs, a form is not needed.

How to draw line between points using click event handler?

I'm using a event handler on a HTML canvas to track the coordinates of where a user clicks, and my idea is to connect coordinates together with a line.
The code below creates an Array and keeps a list of coordinates within the canvas element that the user has clicked on, and also contains logic to draw a line between the currently clicked point and the point that's been previously clicked on.
The problem I'm encountering is that, no matter how many times I click, even though my Array is being populated with coordinates, the lines are not being drawn between the points.
I'm not entirely sure what I am doing wrong, or if there is some re-rendering being done that might be wiping away the drawings I make on the canvas.
var coords = [];
var canvas = document.getElementById('canvas');
canvas.addEventListener('click', function (event) {
var coord = { "x": event.screenX, "y": event.screenY };
document.getElementById("coords").innerText = "{" + coord.x + ", " + coord.y + "}";
coords.push(coord);
var max = coords.length - 1;
if (typeof coords[max - 1] !== "undefined") {
var curr = coords[max], prev = coords[max - 1];
var context = canvas.getContext("2d");
context.beginPath();
context.moveTo(prev.x, prev.y);
context.lineTo(curr.x, curr.y);
context.stroke();
}
});
<!doctype html>
</html>
<head>
<title>Drawing canvas</title>
<style>
canvas {
width: 200px;
height: 200px;
border: 2px solid black;
border-radius: 5px;
}
</style>
</head>
<body>
<p id='coords'></p>
<canvas id='canvas'></canvas>
</body>
</html>
Move your context outside the click event and use canvas coordinates instead of screen one: event.x and event.y
Do not use CSS dimensions for the canvas. Check this post
var coords = [];
var canvas = document.getElementById('canvas');
var context = canvas.getContext("2d");
canvas.addEventListener('click', function (event) {
var coord = { "x": event.x, "y": event.y};
document.getElementById("coords").innerText = "{" + coord.x + ", " + coord.y + "}";
coords.push(coord);
var max = coords.length - 1;
if (typeof coords[max - 1] !== "undefined") {
var curr = coords[max], prev = coords[max - 1];
context.beginPath();
context.moveTo(prev.x, prev.y);
context.lineTo(curr.x, curr.y);
context.stroke();
}
});
<style>
canvas {
border: 1px solid black;
border-radius: 0px;
}
body {
margin: 0;
padding: 0;
}
</style>
<canvas id='canvas' width="200" height="200"></canvas>
<p id='coords'></p>

Working with .clientX example in JS any idea why you can not check a given argument?

<!DOCTYPE html>
<html>
<head>
<style>
div {
width: 100vw;
height: 100vh;
border: 1px solid black;
text-align: center;
}
</style>
</head>
<body>
<p>Click in the div element below to get the x (horizontal) and y (vertical) coordinates of the mouse pointer, when it is clicked.</p>
<div onmousemove="showCoords(event)"><p id="demo"></p></div>
<p><strong>Tip:</strong> Try to click different places in the div.</p>
<script>
function showCoords(event) {
var cX = event.clientX;
var sX = event.screenX;
var cY = event.clientY;
var sY = event.screenY;
var coords1 = "client - X: " + cX + ", Y coords: " + cY;
var coords2 = "screen - X: " + sX + ", Y coords: " + sY;
document.getElementById("demo").innerHTML = coords1 + "<br>" + coords2;
console.log(cX * 0.5);
if(cX < 0.5 * cX){
document.getElementById("demo").style.color = "red";
}
/*else if(cX > cX * 0.5 ){
document.getElementById("demo").style.color = "yellow";
}*/
else{
document.getElementById("demo").style.color = "black";
}
}
</script>
</body>
</html>
Hello, I have attached the given example I have been working on via W3schools. I can log cX to the screen dividing it by two. However when I then try to use it in an argument it will not work. Has anyone else came across a similar issue or have I made a fatal error in markup? Please let me know. If I find solution will be sure to post here. Thank you.
if(cX < 0.5 * cX){
This is always false, you probably meant cX < 0.5 * document.body.clientWidth.

Why doesn't my canvas animation show?

I have been working on a canvas animation of a circle that moves in a random direction, and every second the direction changes. I do that by changing a velocity vector every second by repeatedly calling a function using setInterval, while changing the position of the circle's center and drawing it in another function using requestAnimationFrame. The result is an empty canvas, and I'm not sure why. The code is split into the following three files:
random_ball.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Random Ball</title>
<link rel="stylesheet" href="random_ball.css">
</head>
<body>
<canvas id="canvas"></canvas>
<script src="random_ball.js"></script>
</body>
</html>
random_ball.css
html, body{
height: 100%;
width: 100%;
position: absolute;
top: 0;
left: 0;
overflow: hidden;
margin: 0;
padding: 0;
}
canvas{
position: absolute;
width: 50vw;
height: 50vh;
top: 25vh;
left: 25vw;
border-style: solid;
margin: 0;
padding: 0;
}
random_ball.js
const canvas = document.getElementById('canvas')
const bounds = canvas.getBoundingClientRect()
const TWO_PI = 2*Math.Pi
const R = 25
const MAX_Y = bounds.height - R
const MAX_X = bounds.width - R
const ctx = canvas.getContext('2d')
function randomInterval(min, max){
return Math.random()*(max - min) + min
}
function randomVelocity(){ // velocity is pixels/sec
VEL.X = randomInterval(-POS.X + R, MAX_X - POS.X)
VEL.Y = randomInterval(-POS.Y + R, MAX_Y - POS.Y)
console.log('VEL: ' + JSON.stringify(VEL))
}
var POS = {X: bounds.height/2, Y: bounds.width/2}
var VEL = {X: 0, Y: 0}
var LAST_TIME = window.performance.now()
function drawCircle(color){
ctx.strokeStyle = color
ctx.beginPath()
ctx.moveTo(POS.X, POS.Y)
ctx.arc(POS.X, POS.Y, R, 0, TWO_PI, true)
ctx.stroke()
}
function draw(timestamp){
var dt = (timestamp - LAST_TIME)/1000
var dx = VEL.X*dt
var dy = VEL.Y*dt
drawCircle('#FFFFFF') // erase the old drawing by making it white
POS.X += dx
POS.Y += dy
//console.log('POS: ' + JSON.stringify(POS))
drawCircle('#000000')
LAST_TIME = timestamp
requestAnimationFrame(draw)
}
randomVelocity()
drawCircle('#000000')
setInterval(randomVelocity, 1000) //change velocity every second
requestAnimationFrame(draw)
I suspect that drawing white over the old circle means the picture is changing too fast for me to see it.
You might want to familiarize yourself with JavaScript syntax rules, and possibly a code checker like JSHint.
The main problem with your code is that you're referencing a nonexistent property of the Math object. Math has no Pi property. It's spelled PI (all caps). JavaScript is case sensitive about these things.
Next: a more common practice for clearing the canvas is to use ctx.clearRect(0, 0, width, height). Here's a JSFiddle to help you see the difference: https://jsfiddle.net/Hatchet/dy2dognp/

Get Canvas X and Y coordinates and show on screen

I'm currently learning canvas touch event function,I 'm able to draw line on the canvas, now I want to get the x and y coordinates when I draw any lines and show on the screen.please help and teach me how to get the x and y values, thank You!
here is the coding
<!DOCTYPE html>
<html><head>
<style>
#contain {
width: 500px;
height: 120px;
top : 15px;
margin: 0 auto;
position: relative;
}
</style>
<script>
var canvas;
var ctx;
var lastPt=null;
var letsdraw = false;
var offX = 10, offY = 20;
function init() {
var touchzone = document.getElementById("layer1");
touchzone.addEventListener("touchmove", draw, false);
touchzone.addEventListener("touchend", end, false);
ctx = touchzone.getContext("2d");
}
function draw(e) {
e.preventDefault();
if (lastPt != null) {
ctx.beginPath();
ctx.moveTo(lastPt.x, lastPt.y);
ctx.lineTo(e.touches[0].pageX - offX,
e.touches[0].pageY - offY);
ctx.stroke();
}
lastPt = {
x: e.touches[0].pageX - offX,
y: e.touches[0].pageY - offY
};
}
function end(e) {
var touchzone = document.getElementById("layer1");
e.preventDefault();
// Terminate touch path
lastPt = null;
}
function clear_canvas_width ()
{
var s = document.getElementById ("layer1");
var w = s.width;
s.width = 10;
s.width = w;
}
</script>
</head>
<body onload="init()">
<div id="contain">
<canvas id="layer1" width="450" height="440"
style="position: absolute; left: 0; top: 0;z-index:0; border: 1px solid #ccc;"></canvas>
</div>
</body>
</html>
Still not entirely confident I understand your question.
In the code you posted, you are already obtaining coordinates using e.touches[0].pageX/Y. The main problem with that is that the pageX/Y values are relative to the page origin. You are then subtracting fixed offX/Y in your code to try and convert these to canvas-relative coordinates. Right idea, wrong values. You need to subtract off the position of the canvas element which can be obtained by summing the offsetX/Y values as you traverse the tree upward using the offsetParent reference.
Something like:
offX=0;offY=0;
node = document.getElementById ("layer1");
do {
offX += node.offsetX;
offY += node.offsetY;
node = node.offsetParent;
} while(node);
should give you a better value for offX and offY.
If you just want to locate the actual drawing at the end, it would be easiest just to track a bounding box while the user draws.

Categories

Resources