I'm attempting to draw boxes onto a canvas using JavaScript; my code works, but I'm having trouble with my arrays. Say I have a multi-demensional array called map and it is declared like so:
var map = [
[0,1,1],
[0,0,1],
[0,1,1],
];
Where 1 is a box and 0 is blank space, but when I run my code the output looks like the following:
0,0,0
1,0,1
1,1,1
Is there any way to fix this so the output matches map? My code looks like this:
var canvas = null;
var ctx = null;
var x,y,count,inc,ax,ay;
var map = [
[0,0,0],
[1,0,1],
[1,1,1],
];
window.onload = function () {
canvas = document.getElementById("gameArea");
ctx = canvas.getContext("2d");
y=0;
x=0;
ax=0;
ay=0;
count=0;
inc=0;
for(;count<3;count++){
if(count>0){
inc = inc + 40;
console.log("inc:"+inc);
console.log();
}
ay=count;
console.log("ay:"+ay);
console.log();
y = y + inc;
console.log("y:"+y);
console.log();
for(;ax<3;x=x+40,ax++){
if(map[ax][ay]==1){
console.log(ax+","+ay)
console.log(map[ax][ay]);
console.log();
ctx.strokeRect(x,y,40,40);
console.log("block:"+x+","+y);
}
}
console.log();
x=0;
y=0;
ax=0;
}
};
And the HTML is as follows:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Single Stage</title>
<script src="js/game.js" type="text/javascript">
</script>
<style type="text/css">
#gameArea{
display:block;
margin:0 auto;
background-color:#FFFFFF;
border: 1px solid black;
}
</style>
</head>
<body>
<canvas id="gameArea" width='800' height='480'></canvas>
</body>
</html>
You've just mixed up your rows and columns
try switching map[ax][ay]==1 to map[ay][ax]==1
Related
OpenStreetMap (OSM) have a Tile server. A tile is a 256x256 image of the world in a specific zoom.
I have longitude and latitude and I can find the correct tile by using this function.
function long2tile(lon,zoom) {return (Math.floor((lon+180)/360*Math.pow(2,zoom))); }
function lat2tile(lat,zoom) { return (Math.floor((1-Math.log(Math.tan(lat*Math.PI/180) + 1/Math.cos(lat*Math.PI/180))/Math.PI)/2 *Math.pow(2,zoom))); }
var zoom = 4;
var x= long2tile(13.393562,zoom);
var y = lat2tile(52.519582,zoom);
document.getElementById('a').src='https://tile.openstreetmap.org/'+zoom+'/'+ x+'/'+y+'.png';
<img src="" id="a" style="border:1px solid black"/>
My problem is that Id like to know what coordinate in the 256x256 pixel is the location i set.
How to get the x-y coordiaten inside this one tile?
The rounding makes the difference!
function lo2t(lon,zoom){
return (lon+180)/360*Math.pow(2,zoom);
}
function la2t(lat,zoom){
return (1-Math.log(Math.tan(lat*Math.PI/180) + 1/Math.cos(lat*Math.PI/180))/Math.PI)/2 *Math.pow(2,zoom);
}
function long2tile(lon,zoom) {return Math.floor(lo2t(lon,zoom)); }
function lat2tile(lat,zoom) {return Math.floor(la2t(lat,zoom)); }
function long2tfac(lon,zoom) {
return long2tile(lon,zoom)-lo2t(lon,zoom);
}
function lat2tfac(lat,zoom) {
return lat2tile(lat,zoom)-la2t(lat,zoom);
}
var zoom = 4;
var x= long2tile(13.393562,zoom);
var y = lat2tile(52.519582,zoom);
document.getElementById('a').src='https://tile.openstreetmap.org/'+zoom+'/'+ x+'/'+y+'.png';
var point = document.getElementById('point');
var pos=";"; pos+="left:"+long2tfac(13.393562,zoom)*-256;
pos+="px;top:"+lat2tfac(52.519582,zoom)*-256;
point.setAttribute('style',point.getAttribute('style')+pos+'px;');
<img src="" id="a" style="border:1px solid black"/>
<div id="point" style="display:block; position:absolute; width:30px; height:30px; border:1px solid black; border-radius:15px;"> </div>
You can use the OpenLayers library for that purpose, it can manage all sort of calculations and transformations for you:
const source = new ol.source.OSM();
const grid = source.getTileGrid();
const projectedCoordinate=ol.proj.fromLonLat([13.393562,52.519582], "EPSG:3857");
const tileCoord = grid.getTileCoordForCoordAndZ(projectedCoordinate, 4/*zoom-level*/);
const projectedExtent=grid.getTileCoordExtent(tileCoord);
const extent = ol.proj.transformExtent(projectedExtent, ol.proj.get('EPSG:3857'), ol.proj.get('EPSG:4326'));
const yWidth=extent[2]-extent[0];
const xWidth=extent[3]-extent[1];
const tileUrlFunction = source.getTileUrlFunction();
const url=tileUrlFunction(tileCoord, 1, ol.proj.get('EPSG:3857'))
function convertPixelToLonLat(xPixel,yPixel){
if(!(xPixel>=0 && xPixel<=256)){
throw new Error('invalid xPixel');
}
if(!(yPixel>=0 && yPixel<=256)){
throw new Error('invalid yPixel');
}
return {lon:extent[1]+xWidth/256*xPixel,lat:extent[2]-yWidth/256*yPixel}
}
document.querySelector('img').src=url;
console.log("top-left of tile:",convertPixelToLonLat(0,0))
console.log("bottom-right of tile:",convertPixelToLonLat(256,256))
console.log("middle of tile:",convertPixelToLonLat(128,128))
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
<title>Test</title>
</head>
<body>
<img />
</body>
</html>
This question already has answers here:
Why does jQuery or a DOM method such as getElementById not find the element?
(6 answers)
Closed 6 years ago.
I am facing error at append child as the object null value error is there infact i have created the object in the top of script with document get element
and i am trying to get the issue resolve as left side is in there in the div need some help try to figure it out. Please as u read
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Game</title>
<style>
imgg{
position: absolute;
}
div{
width: 500px;
height: 500px;
position: absolute;
}
#rightSide { left: 500px;
border-left: 1px solid black }
</style>
<script>
var numberOfFaces =5 ;
var theLeftSide = document.getElementById("leftSide");
function generateFaces(){
for(var i = 1 ; i <= numberOfFaces ; i++)
{
var imgg = document.createElement("img");
imgg.src = "smile.png";
imgg.style.height = "100px";
imgg.style.width = "100px";
imgg.style.top = Math.random() *400 ;
imgg.style.left = Math.random() *400 ;
theLeftSide.appendChild(imgg);
}
}
</script>
</head>
<body onload="generateFaces()">
<h2>Matching Game</h2>
<p>Click on the extra smiling face on the left.</p>
<div id="leftSide"></div>
<div id="rightSide"></div>
</body>
</html>
document.getElementById("leftSide"); will give error if you put your script inside head. The reason being when js will try to parse this line but there is no such DOM present .
You can resolve it by using
window.onload
put the script tag before closing body tag
<body>
// Dom
<script>
// Rest of code
</script>
</body>
Using window.onload
<head>
//Rest of code
<script>
window.onload = function(){
var numberOfFaces =5 ;
var theLeftSide = document.getElementById("leftSide");
function generateFaces(){
for(var i = 1 ; i <= numberOfFaces ; i++)
{
var imgg = document.createElement("img");
imgg.src = "smile.png";
imgg.style.height = "100px";
imgg.style.width = "100px";
imgg.style.top = Math.random() *400 ;
imgg.style.left = Math.random() *400 ;
theLeftSide.appendChild(imgg);
}
}
}
</script>
</head>
Check this JSFIDDLE , script is wrapped in the body
Place your <script> as last-child of <body> as by the time you are accessing the element using DOM-api, element is not in the DOM
Set position to absolute
Add unit as px(pixel) while assigning top and left
var numberOfFaces = 5;
var theLeftSide = document.getElementById("leftSide");
function generateFaces() {
for (var i = 1; i <= numberOfFaces; i++) {
var imgg = document.createElement("img");
imgg.src = "http://i185.photobucket.com/albums/x304/metalife/transmetropolitan-smile.png";
imgg.style.height = "100px";
imgg.style.width = "100px";
imgg.style.position = 'absolute';
imgg.style.top = Math.random() * 400 + 'px';
imgg.style.left = Math.random() * 400 + 'px';
theLeftSide.appendChild(imgg);
}
}
imgg {
position: absolute;
}
div {
width: 500px;
height: 500px;
position: absolute;
}
#rightSide {
left: 500px;
border-left: 1px solid black
}
<body onload="generateFaces()">
<h2>Matching Game</h2>
<p>Click on the extra smiling face on the left.</p>
<div id="leftSide"></div>
<div id="rightSide"></div>
I have a block of code as the following
<body id="main">
<h1>Matching Game</h1>
<p>Click on the extra smile face on the left</p>
<div id="left_side"></div>
<div id="right_side"></div>
<script>
var theLeftSide = document.getElementById("left_side");
var theRightSide = document.getElementById("right_side");
theLeftSide.lastChild.onclick = function nextLevel(event){
event.stopPropagation();
quan+=5;
dele();
generateFace();
}
</script>
</body>
This line theLeftSide.lastChild.onclickwill throw an error, saying that "cannot set property 'onclick' of null", because at the time javascript engine scans through it, it hasn't has any child yet. This problem can be solved by putting this code inside $(document).ready, I know.
However, I also tried IIFE, which means that wrapping all those code inside
(function(){
var theLeftSide = document.getElementById("left_side");
var theRightSide = document.getElementById("right_side");
theLeftSide.lastChild.onclick = function nextLevel(event){
event.stopPropagation();
quan+=5;
dele();
generateFace();
}
})()
and also see that the problem is fixed, but cannot figure out why. Any one can explain me ?
Here's the full original code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>part4</title>
<style>
div{
position:absolute;
}
#left_side{
width:500px; height: 500px; border-right:#000 thin inset;
float: left;
}
#right_side{
width:500px; height: 500px;
float:left; left:500px;
}
img{
position: absolute;
}
body{
margin:0px;
}
</style>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.11.3.min.js"></script>
</head>
<body onload="generateFace()" id="main">
<h1>Matching Game</h1>
<p>Click on the extra smile face on the left</p>
<div id="left_side"></div>
<div id="right_side"></div>
<script>
var theLeftSide = document.getElementById("left_side");
var theRightSide = document.getElementById("right_side");
var e = event;
var theBody= document.getElementById("main");
var post_left =0;
var post_top=0;
var quan = 4;
function generateFace(){
var i =0;
for(i=0; i<= quan; i++){
var img = document.createElement("img");
img.src="smile.png"; post_top=getRandom(); post_left=getRandom();
img.style.top = post_top + "px";
img.style.left = post_left +"px";
theRightSide.appendChild(img);
var clone = img.cloneNode(true);
theLeftSide.appendChild(clone);
}
//var clone = theRightSide.cloneNode(true);
//theLeftSide.appendChild(clone);
var extra = document.createElement("img");
extra.src="smile.png"; post_top=getRandom(); post_left=getRandom();
extra.style.top = post_top + "px";
extra.style.left = post_left +"px";
theLeftSide.appendChild(extra);
};
function getRandom(){
var i = Math.random() * 400 +1;
return Math.floor(i);
};
function dele(){
while(theLeftSide.firstChild != null){
theLeftSide.removeChild(theLeftSide.firstChild);
}
while(theRightSide.firstChild != null){
theRightSide.removeChild(theRightSide.firstChild);
}
};
theBody.onclick = function gameOver() {
alert("Game Over!");
dele();
theBody.onclick = null;
theLeftSide.lastChild.onclick = null;
};
function nextLevel(event){
event.stopPropagation();
quan+=5;
delse();
generateFace();
}
</script>
</body>
</html>
and with IIFE:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>part4</title>
<style>
div{
position:absolute;
}
#left_side{
width:500px; height: 500px; border-right:#000 thin inset;
float: left;
}
#right_side{
width:500px; height: 500px;
float:left; left:500px;
}
img{
position: absolute;
}
body{
margin:0px;
}
</style>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.11.3.min.js"></script>
</head>
<body id="main">
<h1>Matching Game</h1>
<p>Click on the extra smile face on the left</p>
<div id="left_side"></div>
<div id="right_side"></div>
<script>
(function(){
var theLeftSide = document.getElementById("left_side");
var theRightSide = document.getElementById("right_side");
var e = event;
var theBody= document.getElementById("main");
var post_left =0;
var post_top=0;
var quan = 4;
generateFace();
function generateFace(){
var i =0;
for(i=0; i<= quan; i++){
var img = document.createElement("img");
img.src="smile.png"; post_top=getRandom(); post_left=getRandom();
img.style.top = post_top + "px";
img.style.left = post_left +"px";
theRightSide.appendChild(img);
var clone = img.cloneNode(true);
theLeftSide.appendChild(clone);
}
//var clone = theRightSide.cloneNode(true);
//theLeftSide.appendChild(clone);
var extra = document.createElement("img");
extra.src="smile.png"; post_top=getRandom(); post_left=getRandom();
extra.style.top = post_top + "px";
extra.style.left = post_left +"px";
theLeftSide.appendChild(extra);
};
function getRandom(){
var i = Math.random() * 400 +1;
return Math.floor(i);
};
function dele(){
while(theLeftSide.firstChild != null){
theLeftSide.removeChild(theLeftSide.firstChild);
}
while(theRightSide.firstChild != null){
theRightSide.removeChild(theRightSide.firstChild);
}
};
theBody.onclick = function gameOver() {
alert("Game Over!");
dele();
//theBody.onclick = undefined;
//theLeftSide.lastChild.onclick = undefined;
};
theLeftSide.lastChild.onclick = function nextLevel(event){
event.stopPropagation();
quan+=5;
dele();
generateFace();
}
})();
</script>
</body>
</html>
In the original piece of code, generateFace() is called on page load. In the second piece of code, generateFace() is called directly. There is no relation with the IIFE. Please forget it! :-P Here is a simplified version of what you are doing in each case (open your browser console before running the snippets):
Original code (throws a TypeError)
console.log('attempting to initialize onclick');
document.getElementById('clickable').onclick = function () {
alert(this.id);
};
console.log('onclick initialized successfully');
function gendiv () {
console.log('gendiv was called');
document.body.innerHTML = '<div id="clickable">click me</div>';
}
<body onload="gendiv()"></body>
Modified code
gendiv();
console.log('trying to initialize onclick');
document.getElementById('clickable').onclick = function () {
alert(this.id);
};
console.log('onclick initialized successfully');
function gendiv () {
console.log('gendiv was called');
document.body.innerHTML = '<div id="clickable">click me</div>';
}
<body></body>
I am trying to make a basic sensor pad for HTML (JavaScript), which creates 500 small divs which then turn red on mouse hover. However, when I tried it, nothing was created
example.html
<!DOCTYPE html>
<html>
<head>
<title>SensorPad Test</title>
<link rel="stylesheet" href="styles.css" type="text/css">
<script type="text/javascript" src="SensorPad.js">
window.onload = createSensor;
</script>
</head>
</html>
styles.css
.sPad{
width: 0.4px;
height: 0.4px;
background-color: #EEE;
border: 0.1px solid #000;
}
.uPad{
background-color: #F00;
}
SensorPad.js
var sPos;
var count = 1;
function createSensor(){
for(var i = 0; i < 500; ++i){
var pad = document.createElement('div');
pad.className = 'sPad';
pad.id = 'pad' + count.toString();
pad.onmousehover = function(){sPos = parseInt(pad.id); clearPads(); pad.className = 'uPad';};
count++;
}
}
function clearPads(){
for(var i = 1; i <= count; ++i){
var n = 'pad' + i.toString();
var p = document.getElementById(n);
p.className = 'sPad';
}
}
You're missing
document.body.appendChild(pad);
First the code will not run because of the way you added the JavaScript
<script type="text/javascript" src="SensorPad.js">
window.onload = createSensor;
</script>
you can not have code inside and a src
<script type="text/javascript" src="SensorPad.js"></src>
<script type="text/javascript"
window.onload = createSensor;
</script>
First, you need to use separate script tags - one for the external reference and another for the onload.
As for the divs, you're creating them but you're not adding them to the DOM.
for(var i = 0; i < 500; ++i){
var pad = document.createElement('div');
pad.className = 'sPad';
pad.id = 'pad' + count.toString();
pad.onmousehover = function(){sPos = parseInt(pad.id); clearPads(); pad.className = 'uPad';};
document.body.appendChild(pad)
count++;
}
EDIT: Addressing Teemu's concern you might simply want to use CSS for that hover instead so:
for(var i = 0; i < 500; ++i){
var pad = document.createElement('div');
pad.className = 'sPad';
pad.id = 'pad' + i.toString();
document.body.appendChild(pad)
}
css
.sPad{
width: 0.4px;
height: 0.4px;
background-color: #EEE;
border: 0.1px solid #000;
}
.sPad:hover{
background-color: #F00;
}
As i was going through canvas tutorial, i am getting error:" Point is not defined" and My actual output differs from expected output.Iam not able to drag the circle with mouse.
ReferenceError: Point is not defined in logic.js
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Drawing Circles in Canvas</title>
<link rel="stylesheet" href="css/style.css"/>
</head>
<body width="100%" height="100%">
<header>
<h1>Drawing in Canvas</h1>
</header>
<canvas id="game" width="768" height="400">
Sorry, your web browser does not support
Canvas content.
</canvas>
<script src="js/jquery-1.10.2.min.js">
</script>
<script src="js/logic.js"></script>
</body>
</html>
logic.js
var untangleGame={
circle: [],
thinLineThickness: 1,
lines: []
};
function Circle(x,y,radius){
this.x=x;
this.y=y;
this.radius=radius;
}
function Line(startPoint,endPoint,thickness){
this.startPoint=startPoint;
this.endPoint=endPoint;
this.thickness=thickness;
}
function drawcircle(ctx,x,y,radius){
ctx.fillStyle="rgba(200,200,100,.9)";
ctx.beginPath();
ctx.arc(x,y,radius,0,Math.PI*2,true);
ctx.closePath();
ctx.fill();
}
function connectCircles(){
for(var i=0;i<untangleGame.circle.length;i++){
var startPoint=untangleGame.circle[i];
for(var j=0;j<i;j++){
var endPoint=untangleGame.circle[j];
untangleGame.lines.push(new
Line(startPoint,endPoint,untangleGame.thinLineThickness));
}
}
}
function drawLine(ctx,x1,y1,x2,y2,thickness){
ctx.beginPath();
ctx.moveTo(x1,y1);
ctx.lineTo(x2,y2);
ctx.lineWidth=thickness;
ctx.strokeStyle="#cfc";
ctx.stroke();
}
function clear(ctx){
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
}
$(function(){
var canvas=document.getElementById('game');
var ctx=canvas.getContext('2d');
var circleRadius=10;
var width=canvas.width;
var height=canvas.height;
var circlesCount=5;
for(var i=0;i<circlesCount;i++){
var x=Math.random()*width;
var y=Math.random()*height;
drawcircle(ctx,x,y,circleRadius);
untangleGame.circle.push(new Circle(x,y,circleRadius));
}
connectCircles();
$("#game").mousedown(function(e){
var canvasPosition=$(this).offset();
var mouseX=e.layerX || 0;
var mouseY=e.layerY || 0;
for(var i=0;i<untangleGame.circle.length;i++){
var circleX=untangleGame.circle[i].x;
var circleY=untangleGame.circle[i].y;
var radius=untangleGame.circle[i].radius;
if(Math.pow(mouseX-circleX,2)+Math.pow(mouseY-circleY,2)
<Math.pow(radius,2)){
untangleGame.targetCircle=i;
break;
}
}
});
$("#game").mousemove(function(e){
if(untangleGame.targetCircle != undefined){
var canvasPosition=$(this).offset();
var mouseX=e.layerX || 0;
var mouseY=e.layerY || 0;
var
radius=untangleGame.circle[untangleGame.targetCircle].radius;
untangleGame.circle[untangleGame.targetCircle]=new
Circle(mouseX,mouseY,radius);
}
connectCircles();
});
$("#game").mouseup(function(e){
untangleGame.targetCircle=undefined;
});
setInterval(gameloop,30);
});
function gameloop(){
var canvas=document.getElementById('game');
var ctx=canvas.getContext('2d');
clear(ctx);
for(var i=0;i<untangleGame.lines.length;i++){
var line=untangleGame.lines[i];
var startPoint=line.startPoint;
var endPoint=line.endPoint;
var thickness=line.thickness;
drawLine(ctx,startPoint.x,startPoint.y,endPoint.x,endPoint.y,thickness);
}
for(var i=0;i<untangleGame.circle.length;i++){
var circle=untangleGame.circle[i];
drawcircle(ctx,point.x,point.y,circle.radius);
}
}
style.css
canvas{
background: #333;
}
Output Expected:
Output expected of Image link O/p Expected link
Looks like you are using point instead of circle in the for loop in gameloop
for (var i = 0; i < untangleGame.circle.length; i++) {
var circle = untangleGame.circle[i];
drawcircle(ctx, circle.x, circle.y, circle.radius);
}
Demo: Fiddle