How do I create n canvases from within Javascript? - javascript

I am looking for a way to create canvases as I need them at run time. my code so far is
var isCanv = new Array();//bool array for which places in the arrays are/are not in use
var canv = new Array();//for the canvases
var ctx = new Array();//for the contexts
var inhtml = new Array();//for the html canvas tags for each canvas
var upperBound = -1;//the highest index used so far
function createCtx(){
var i = 0;
while(isCanv[i]){
i++;
}
inhtml[i] = '<canvas id="canv'+i+'" width="'+800+'px" height="'+800+'px" style="display:block;background:#ffffff+;"></canvas>';
isCanv[i] = true;
if(i>upperBound){
upperBound = i;
}
var tohtml = '';
for(var j = 0; j<= upperBound; j++){
if(isCanv[i]){
tohtml+=inhtml[j];
}
}
document.getElementById('game').innerHTML=tohtml;
canv[i] = document.getElementById('canv'+i);
ctx[i] = canv[i].getContext('2d');
return(i);
}
function keyEvent(event) {
var i = 0;
while(isCanv[i]){
ctx[i].fillStyle="#00FFFF";
ctx[i].fillRect(0,0,800,800);
i++;
}
}
and the html looks like this
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>redicated</title>
</head>
<body style="background:#333333;" onkeydown="keyEvent(event)">
<div id="game"></div>
<script src="game.js"></script>
</body>
</html>
This works for the first canvas, but any subsequent addition breaks it all.
Does anyone know how I could fix this, or of a better way of doing it?
Edit:
I figured it out. I need to recreate the context every time there is an addition. now my code looks like
function createCtx(){
var i = 0;
while(isCanv[i]){
i++;
}
inhtml[i] = '<canvas id="canv'+i+'" width="'+800+'px" height="'+800+'px" style="display:block;background:#ffffff+;"></canvas>';
isCanv[i] = true;
if(i>upperBound){
upperBound = i;
}
var tohtml = '';
for(var j = 0; j<= upperBound; j++){
if(isCanv[j]){
tohtml+=inhtml[j];
}
}
document.getElementById('game').innerHTML=tohtml;
for(var j = 0; j<= upperBound; j++){
if(isCanv[j]){
canv[j] = document.getElementById('canv'+j);
ctx[j] = canv[j].getContext('2d');
}
}
return(i);
}

The for loop:
for(var j = 0; j<= upperBound; j++){
if(isCanv[i]){
tohtml+=inhtml[j];
}
is only ran once since when it is first executed j == upperBound. To fix this try removing
if(i>upperBound){
upperBound = i;
}
and whats the point of upperBound anyways it will always be equivalent to i so why not just use that.

Related

Javascript: why is the alert saying undefined and not the letter "k"

I can get my array to work and display perfectly as a 2d array but the second I attempt to add another element it never shows it always stays undefined. I tried many different methods, in this version I attempted to duplicate the way that I add the 2d elements.
Ultimately I want to save data to the array to make the walls "#" that are displaying correctly to have further data stating "solid" and then I would be able to test for that before moving the "#"
I actually have a working version of this but using a second array which would get very cumbersome if I add further data.
Also as it is right now I am surprised the entire map is not getting overwritten with the letter k
function gameloop(){
var mainArray = [];
var mapSizeX = 32;
var mapSizeY = 128;
var arrayDepth = 10;
var idPos = {x:0, y:0};
function initMap(mainArray, mapSizeX, mapSizeY){
for (var i = 0; i < mapSizeX; i++) {
mainArray.push([0])
for (var j = 0; j < mapSizeY; j++) {
mainArray[i][j] = ".";
if(j == 0){mainArray[i][j] = "#";}
if(j == mapSizeY-1){mainArray[i][j] = "#";}
if(i == 0){mainArray[i][j] = "#";}
if(i == mapSizeX-1){mainArray[i][j] = "#";}
for (var k = 0; k < arrayDepth; k++) {
mainArray[i][j][k] = "k";
}
}
}
}
function nl(){GameScreen.innerText += "\n";}
function render() {GameScreen.innerText = mainArray.map(arr => arr.join("")).join("\n");
nl(); nl();}
function reposition(xChange,yChange,strA){
//mainArray[idPos.x][idPos.y] = ".";
//idPos.x = idPos.x + xChange;
//idPos.y = idPos.y + yChange;
//mainArray[idPos.x][idPos.y] = "#";
if(mainArray[idPos.x+xChange][idPos.y+yChange][1] === "Solid"){GameLog.innerText ="You can not travel in that direction"}
else{
mainArray[idPos.x][idPos.y] = ".";
idPos.x = idPos.x + xChange;
idPos.y = idPos.y + yChange;
mainArray[idPos.x][idPos.y] = "#";
GameLog.innerText = "You take a step to the " + strA
alert(mainArray[0][0][1]);
}
render();
}
//Startup
initMap(mainArray, mapSizeX, mapSizeY);
idPos.x = mapSizeX/2; idPos.y = mapSizeY/2;
mainArray[idPos.x][idPos.y] = "#";
//First Render
render();
document.addEventListener('keydown', function(event) {
if(event.keyCode === 38 ){reposition(-1,0,"North");}
if(event.keyCode === 40 ){reposition(1,0,"South");}
if(event.keyCode === 37 ){reposition(0,-1,"West");}
if(event.keyCode === 39 ){reposition(0,1,"East");}
//alert(event.keyCode);
});
}
gameloop();
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello</title>
</head>
<body>
<br>
<p style="color:#7d7d7d;font-family:Lucida Console;">Dungeon Valley.<br>
<font style="color:#ABABAB;font-family:Lucida Console;font-size:0.5em";>
Taming the Borderlands.<br>
v0.005 By heromedel. </P></font>
<P>
<section id="GameScreen" style="color:#000000;font-family:Lucida Console;"></section>
<P>
<section id="GameLog" style="color:#000000;font-family:Lucida Console;">Arrow Keys to move.<br></section>
<script src="main.js"></script>
</body>
</html>
If I'm understanding what you're trying to do, this is wrong:
for (var k = 0; k < arrayDepth; k++) {
mainArray[i][j][k] = "k";
}
mainArray is supposed to be a 2d array of strings, right? So why are you using var k to add a 3rd dimension to it? Unless you're trying to append to the string? In Javascript you append to strings with +, not with [].
By the way, this is also wrong:
mainArray.push([0])
You want to push an empty array [], not an array with a 0 in it [0].

How not to make <br> a tag

<script>
var y="<br>"
function repeater(num){
for (var i=0;i<num;i++)
{document.write(y) }
}
document.write(repeater(4))
</script>
My goal is to make the tag appear
4 times, not the actual breaks. The result shows undefined.
Since the question is asking for Javascript solution not JQuery (since no jQuery tags), I'll add the answer using Javascript.
<script>
var y = "<br>"
function repeater(num) {
for (var i=0; i < num; i++) {
document.body.innerText += y;
}
}
repeater(4);
</script>
or maybe you need to set a text into the spesific element (<div id="app"><div>)? no problem, we can improve the code a little bit.
<script>
var y = "<br>"
function repeater(el, num) {
for (var i=0; i < num; i++) {
el.innerText += y;
}
}
var el = document.getElementById('app');
repeater(el, 4);
</script>
<script>
var res = "";
var y="<br>";
function repeater(num){
for (var i=0;i<num;i++) {
res = res + y;
}
$('#customDiv').text(res);
}
(repeater(4))
You can put a custom <div id="customDiv"></div> inside your html file.

a dynamic js table not working

this code for javascript not working.can any one help me with this.i've tried a lot but couldn't find out what's wrong here!!checked every line .i dont know if the code is wrong or there is any problem with my browser
<html>
<head>
<title>table dynamic</title>
<style>
tr{width:100%;height:100%;border:1px solid black;}
td{height:33%;width:33%;padding:10px;}
.tableShape{
width:300px;
height:300px;
font-size:30px;
text-align:centre;
color:red;
}
table{border:1px solid black;padding:10px;}
</style>
</head>
<body>
<script>
var i, j;
var arr = new Array(3);
for (i = 0; i < 3; i++) {
arr[i] = new Array(3);
}
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
arr[i][j] = 1;
}
}
function tabs() {
var k, t;
var m = document.createElement("table");
m.setAttribute('class', "tableShape");
for (k = 0; k < 3; k++) {
var p = m.insertRow(k);
for (t = 0; t < 3; t++) {
var s = p.insertCell(t);
s.innerHTML += arr[i][j];
}
}
}
window.onLoad = tabs();
</script>
</body>
</html>
You have to append your created element to the DOM:
function tabs() {
var k, t;
var m = document.createElement("table");
m.setAttribute('class', "tableShape");
for (k = 0; k < 3; k++) {
var p = m.insertRow(k);
for (t = 0; t < 3; t++) {
var s = p.insertCell(t);
s.innerHTML += arr[i][j];
}
}
document.body.appendChild(m);
}
When you create DOM elements in javascript, they are created in memory detached from DOM, to see them you have to append it to some node in DOM.
document.body.appendChild(m);
You are doing a nested operation using variables k and t so use it inside the loop
s.innerHTML+=arr[k][t];
Here is a fiddle http://jsfiddle.net/AmH22/1/

Javascript Dynamically added HTML

Please Look at the following code only the last image moves.
http://jsfiddle.net/u8Bg3/
But second one works
http://jsfiddle.net/u8Bg3/1/
As pointed by the Er144 even this works with jquery
http://jsfiddle.net/u8Bg3/14/
I also found out appendchild works but not innerhtml
The difference between two is that in first one html exits in second one it's dynamically created
HTML
<body>
<div class="racetrack" id="racetrack"></div>
<div id="track-tmpl" class="hide">
<div class="track"><div id="player{{ x }}" class="runner"></div></div>
</div>
</body>
JS
var position = [0,40,80,120,80],
racetrack = document.getElementById('racetrack');
track_tmpl = document.getElementById('track-tmpl').innerHTML;
function Players(ele, ptimeout)
{
this.el = ele;
this.i = 0;
this.iterations = 0;
this.stop = 0;
this.timeout = ptimeout;
this.position = 0;
this.animate = function(){
if(this.i !== 0){
this.move((this.position + 5), this.i);
}
if(!this.stop){
if(this.i < 5){
setTimeout(function(_this){
_this.i++;
_this.animate();
},this.timeout,this);
}
if(this.i==5){
this.iterations ++;
if(this.iterations < 50){
this.i = 0;
this.animate();
}
else{
this.el.style.backgroundPosition = '120px 0px';
}
}
}
};
this.start = function(){
this.stop = 0;
this.animate();
};
this.move = function(to,positionIndex){
this.position = to;
this.el.style.backgroundPosition = '-'+position[positionIndex]+'px 0px';
this.el.style.webkitTransform = 'translate('+to+'px)';
this.el.style.mozTransform = 'translate('+to+'px)';
}
}
function Game(noOfPlayers){
this.noOfPlayers = noOfPlayers;
this.players = new Array();
for (var i = 0; i < this.noOfPlayers ; i++){
racetrack.innerHTML = racetrack.innerHTML + track_tmpl.replace('{{ x }}', i);
this.players.push(new Players(document.getElementById('player' + i), (120 + i)));
/* issue here with dynamic added content*/
}
this.start = function(){
for (var i = 0; i < this.noOfPlayers; i++){
this.players[i].start();
}
};
}
var game = new Game(3);
game.start();
Why is that in dynamically added html only the last one moves
The issue is with creating the player(n) object inside the for loop along with the assignments to innerHTML using `+='. The modified fiddle: http://jsfiddle.net/u8Bg3/15/ works fine. Cheers for a good question!
var finalized_tracks= "" ;
for (var i = 0; i < this.noOfPlayers ; i++){
finalized_tracks += track_tmpl.replace('{{ x }}', i);
}
racetrack.innerHTML = racetrack.innerHTML + finalized_tracks;
for (var i = 0; i < this.noOfPlayers ; i++){
this.players.push(new Players(document.getElementById('player'+ i),(120+i)));
}
If you use the jquery:
var element = track_tmpl.replace('{{ x }}', i);
$(racetrack).append(element);
instead of the line where you change the innerHtml of racetrack div, all elements are moving.
However, I'm not sure, why...
theCoder has pretty much nailed the issue with your code there.
Just as an additional thought, you could manually build the necessary divs using javascript instead, it's more long winded however...
for (var i = 0; i < this.noOfPlayers ; i++){
var newTrack = document.createElement("div");
newTrack.id = "track"+i;
newTrack.className = "track";
var newPlayer = document.createElement("div");
newPlayer.id = "player"+i;
newPlayer.className = "runner";
newTrack.appendChild(newPlayer);
racetrack.appendChild(newTrack);
this.players.push(new Players(document.getElementById('player' + i), (120 + i)));
}

Javascript doesn't work when have another one

I searched but I didn't find the answer.
I have a code that change the color of my wordpress template blocks and posts randomly. Actually it changes the classes of these blocks and so the colors. You can see the code here:
function inArray(array , exist) {
var rslt = false;
for (var j = 0; j < array.length; j++)
{
if (array[j] == exist)
{
rslt = true;
}
}
return rslt;
}
var colored = Array();
function changeColor(target) {
var blocks = document.getElementsByClassName(target);
var blockLength = blocks.length;
for (var i = 0; i < blockLength; i++)
{
if (colored.length >= 9)
{
colored = [];
}
var rand = 0;
while (rand == 0 || inArray(colored , rand))
{
rand = Math.floor(Math.random()*10)%10;
}
colored.push(rand);
blocks[i].className = target+' color'+rand ;
}
}
window.onload = function() {
changeColor('block');
changeColor('post');
}
the code you seen placed in an external file named 'colors.js' and included by:
<script src="<?php bloginfo('template_url'); ?>/scripts/colors.js"></script>
in my wordpress template.
the code works correctly til I add another code like this:
<script>var _mxvtmw_position = 'left', _mxvtmw_domain = 'icomp.ir'</script>
<script src="http://iwfcdn.iranwebfestival.com/js/mx.vtmw.min.js?12688" async="async"></script>
Why? And how can i fix this problem?
Thank you.
EDIT:
DEMO: http://tuts.icomp.ir/
IN CASE blocks.length IS 1 YOU HAVE TO ADD ONE MORE IF CONDITION
if (blocks.length==undefined){
//code
}

Categories

Resources