Html5 canvas loading images with JCanvasScript - javascript

hello guys I want to load multiple images with JCanvasScript in html5 canvas, but I can't do it. I want to load images side by side in each row. for that I have function loadx(numX, numY) numX - is number of images in a row and numY is number of rows. for example loadX(5,4) or loadX(10,3) is giving me the same result only 1 image.
here is a code
<script>
function init(){
loadx(5, 4);
}
function loadx(numX, numY){
var numTotal = numX * numY;
var imgBMPs = [];
var sliceImg = new Image();
sliceImg.src = "abstract.jpg";
var sliceBmp;
var imgBmp = [];
imgBmp['width'] = sliceImg.width / numX;
imgBmp['height'] = sliceImg.height / numY;
imgBmp['row'] = 0;
imgBmp['y'] = 0;
sliceImg.onload = function(){
for (i = 0; i < numY; i++){
imgBmp['y'] = i * imgBmp['height'];
for (a = 0; a < numX; a++){
jc.start('canvas');
imgBmp = new jc.image(sliceImg, a * imgBmp['width'], imgBmp['y'], imgBmp['width'], imgBmp['height']);
imgBMPs.push(imgBmp);
jc.start('canvas');
}
}
}
}
</script>
when I tried to debug the code I found out something:
after this
sliceImg.onload = function(){
for (i = 0; i < numY; i++){
imgBmp['y'] = i * imgBmp['height'];
I added the code
alert (imgBmp['height']);
and when I refreshed the page First result was the number but other were "Undefined" so what is wrong?

Within your inner for loop you're reassigning the variable imgBmp to an instance of js.image. This means that the properties of the original object are lost by the time the loop iterates the second time.
Try updating your code as follows:
<script>
function init(){
loadx(5, 4);
}
function loadx(numX, numY){
var numTotal = numX * numY;
var imgBMPs = [];
var sliceImg = new Image();
sliceImg.src = "abstract.jpg";
var sliceBmp;
/*
// imgBmp is being used as an object not an array
// so the following syntax is usually preferred
var imgBmp = {
width: sliceImg.width / numx,
height: sliceImg.height / numy
}
// and to retrieve a property:
console.log(imgBmp.width);
*/
var imgBmp = [];
imgBmp['width'] = sliceImg.width / numX;
imgBmp['height'] = sliceImg.height / numY;
imgBmp['row'] = 0;
imgBmp['y'] = 0;
sliceImg.onload = function(){
for (i = 0; i < numY; i++){
imgBmp['y'] = i * imgBmp['height'];
for (a = 0; a < numX; a++){
jc.start('canvas');
// create a new variable to hold the instance of jc.image
// so the original object reference is preserved
var jcImage = new jc.image(sliceImg, a * imgBmp['width'], imgBmp['y'], imgBmp['width'], imgBmp['height']);
imgBMPs.push(jcImage);
//imgBmp = new jc.image(sliceImg, a * imgBmp['width'], imgBmp['y'], imgBmp['width'], imgBmp['height']);
//imgBMPs.push(imgBmp);
jc.start('canvas');
}
}
}
}
</script>

Related

Adding duplicate tiles from different arrays PIXI.js

I'm trying to create a slot game;
I have some images that I put into an array
var createSlots = function(){
//setup images as tilingSprites
var slot1 = new PIXI.extras.TilingSprite(t1, 200, 200);
var slot2 = new PIXI.extras.TilingSprite(t2, 200, 200);
var slot3 = new PIXI.extras.TilingSprite(t3, 200, 200);
var slot4 = new PIXI.extras.TilingSprite(t4, 200, 200);
var slot5 = new PIXI.extras.TilingSprite(t5, 200, 200);
var slot6 = new PIXI.extras.TilingSprite(t6, 200, 200);
var slot7 = new PIXI.extras.TilingSprite(t7, 200, 200);
var slot8 = new PIXI.extras.TilingSprite(t8, 200, 200);
var slot9 = new PIXI.extras.TilingSprite(t9, 200, 200);
var slot10 = new PIXI.extras.TilingSprite(t10, 200, 200);
//push slots into array; images, sprites etc.
mainSlotArr.push(slot1, slot2, slot3, slot4, slot5, slot6, slot7, slot8, slot9, slot10);
};
for the moment I have 2 functions (will combine them once I get this working)
createReels1 and createReels2
what they do is copy the mainSlotArray use a shuffle function
Then populate to 2 columns (reels) each (at the moment createReels2 only does one reel)
it then removes the array element from the array it's using
The trouble I'm having is that whatever image tiles are used in createReels2, disappear if they are being used in createReels1 function, e.g if image1.png used in createReels2 and createReels1, then it is not visible in the first 2 reels
createReels functions below (alot of hard coding!)
var createReels1 = function(){
slotArr1 = mainSlotArr.slice();
shuffle(slotArr1);
var counter = 0;
var num = 0
for(var i = 0; i <2; i++){
var slotContainer = new PIXI.Container();
slotContainer.width = 100;
slotContainer.height = 400;
slotContainer.y = 100;
slotContainer.x = i*130;
stage.addChild(slotContainer);
slotContainerArr.push(slotContainer);
for(var j = 0; j < 3; j++){
var slot = slotArr1[j];
var toDel = slotArr1.indexOf(slot);
slot.scale.y = slot.scale.x = .5;
console.log(slot);
var nextY = j*(slot.height/2);
slot.y = nextY;
slotContainerArr[i].addChild(slot);
slotArr1.splice(toDel, 1);//remove from array
}
}
}
var createReels2 = function(){
slotArr2 = mainSlotArr.slice();
shuffle(slotArr2);
var counter = 0;
var num = 0
for(var i = 0; i <1; i++){
var slotContainer = new PIXI.Container();
slotContainer.width = 100;
slotContainer.height = 400;
slotContainer.y = 100;
slotContainer.x = 260;
stage.addChild(slotContainer);
slotContainerArr.push(slotContainer);
for(var j = 0; j < 3; j++){
var slot = slotArr2[j];
var toDel = slotArr2.indexOf(slot);
slot.scale.y = slot.scale.x = .5;
var nextY = j*(slot.height/2);
slot.y = nextY;
slotContainerArr[2].addChild(slot);
slotArr2.splice(toDel, 1);//remove from array
}
}
}
If I understood the code correctly, with quick check:
Sprites can have only one parent. If you check the Sprite object, it actually has a parent property. So slotArr1 and slotArr2 have identical Sprites and that fact doesn't change id you slice them. Then when you are assigning them to different containers, they get moved from one container to the other. You can reuse textures sure, but one Sprite can only have on parent.

why wont function testIfIdExist load page before continue onto next instruction

here is all the my code
var dublist = [];
var linkList = [];
var lodeIn;
function testIfIdExist(){
var currentAnime;
for(var ia = 0; ia < linkList.length - 1 ; ia++) {
console.log('http://www.ryuanime.com'+ linkList[ia])
window.location = 'http://www.ryuanime.com'+ linkList[ia]
lodeIn = setTimeout(function(){console.log('http://www.ryuanime.com'+ linkList[ia])}, 1500);
var element = document.evaluate( '//*[#id="anime-episode-list-dub"]/li[1]' ,document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue;
if (element != null) {
var currentAnime = document.evaluate( '//*[#id="content"]/div[1]/h1' ,document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue.outerHTML;
var X = currentAnime.length - 5;
dublist.push(currentAnime.substring(5,X))
}
}
loopdublist()
}
function loopAnlist(){
var longAssString = document.getElementById("animeList").outerHTML;
var linkstart = 1;
var linkend = 1;
var i = 0;
do {
linkstart = longAssString.search('<a href="');
longAssString = longAssString.substring(linkstart+9,longAssString.length)
var linkend = longAssString.search('">');
linkList.push(longAssString.substring(0,linkend))
longAssString = longAssString.substring(linkend+2,longAssString.length)
} while (linkstart >= 1);
testIfIdExist()
}
loopAnlist()
function loopAnlistArray(){
for(var i = 0; i < linkList.length - 1 ; i++) {
console.log(linkList[i])
}
}
function loopdublist(){
for(var i = 0; i < linkList.length - 1 ; i++) {
console.log(dublist[i])
}
}
I seem to just skip over window.location and only runs it after it has run every thing else.
I need the code to go to the link check if the xpath exist, if so add the page header to another array, then move on to the next link in the array and do the same to the end of the array.

JavaScript - Improve my grid search algorithm

I have made my own "GhettoSearch," which is used to find the closest path between 2 given coordinates over a Grid, AKA a "list of coordinates."
The grid is an array like this:
var grid [ [somedata, [x,y,z], somedata], [somedata, [x,y,z], somedata] ]etc..
My start and stop positions is only coordinates, the Z coordinate is irrelevant at the moment.
I can almost get to the end, but some detoures are made because of my cost function.
Here is how the search looks complete: http://i.imgur.com/2ZjQBrh.png
Here is the code I currently use for the search:
var Main = {
GhettoSearch: function(Start, Stop, Grid){
var Pgreed = 1; //From current position to next nearby nodes
var Tgreed = 0.25; //from current position to target node
var Pcost = 0;
var Tcost = 0;
var open = [];
var closed = [];
var aReturn = [];
for (i = 0; i < Grid.length; i++) {
Worldmap.GetNode("Node_" + Grid[i][0]).style.backgroundColor = "#FFFFFF";
Pcost = Heuristics.Distance.Manhattan(Grid[i][1], Start, Pgreed);
Tcost = Heuristics.Distance.Manhattan(Grid[i][1], Stop, Tgreed);
open.push([i, (Pcost + Tcost)]);
}
do {
var TmpData = [0, Infinity];
var TmpForI = null;
for (i = 0; i < open.length; i++) {
if (open[i][1] < TmpData[1]) {
TmpData[0] = open[i][0];
TmpData[1] = open[i][1];
TmpForI = i;
}
}
closed.push(TmpData);
open.splice(TmpForI, 1);
for (i = 0; i < open.length; i++) {
Start = Grid[TmpData[0]][1]; //is now the start for recently closed node
Pcost = Heuristics.Distance.Manhattan(Grid[open[i][0]][1], Start, Pgreed);
Tcost = Heuristics.Distance.Manhattan(Grid[open[i][0]][1], Stop, Tgreed);
open[i] = [open[i][0], (Pcost + Tcost)];
}
} while (open.length > 0);
var PathID = null;
var TmpDist = Infinity;
for (i = 0; i < closed.length; i++) {
var NodeID = Grid[closed[i][0]][0];
var NodeCoords = Grid[closed[i][0]][1];
var NodeCost = closed[i][1];
aReturn.push([NodeID, NodeCoords, NodeCost]);
//var Dist = Heuristics.Distance.Manhattan(NodeCoords, Stop, 1);
if (NodeCost < TmpDist) {
TmpDist = NodeCost;
PathID = i;//Because you will remove the closest cord elese. OR? will u xD
}
}
aReturn.splice(PathID, closed.length);
return aReturn;
}
};
As you can see on the image, while going upwards it goes back and fills the empty spots besides the straight path up, how can I avoid this?
Yes, I have looked at different search aproaches such as BFS and a star, but I have problems implementing this in my own search function

Why can't I get my images to appear in table cells/nodes.. maybe I can get some closure?

I want to add a new image in each cell of the new table and give it the same source as the old table, and then make it clickable. Firstly, I did this:
function showData() {
if (localStorage.getItem(name) !== null) {
var showme = localStorage.getItem(name);
alert("I got the table");
var newTable = document.createElement('table');
newTable.innerHTML = showme;
newTable.id = "newTable";
newNumRows = newTable.getElementsByTagName('tr').length;
newNumCells = newTable.getElementsByTagName('td').length;
newNumCols = newNumCells / newNumRows;
alert(newNumRows);
alert(newNumCells);
alert(newNumCols);
var newImages = newTable.getElementsByTagName('img');
for (var i = 0; i < newImages.length; i += 1) {
var picSource = newImages[i]['src'];
console.log(picSource);
}
function addNewImage(newNumCols) {
var newImg = new Image();
newImg.src = picSource;
col.appendChild(newImg);
newImg.onclick = function() {
alert("WOW");
};
}
for (r = 0; r < newNumRows; r++) {
row = newTable.insertRow(-1);
for (c = 0; c < newNumCols; c++) {
col = row.insertCell(-1);
addNewImage(newNumCols);
}
}
var showIt = document.getElementById('holdTable');
showIt.appendChild(newTable);
}
}
This works to a certain extent, but, unfortunately, only the last image was displaying. So, I did a bit of looking around and I think it has to do with closure (apologies for any duplication), but it's a concept I am really struggling to understand. So then I tried this:
function showData() {
if (localStorage.getItem(name) !== null) {
hideTaskForm();
var showme = localStorage.getItem(name);
var oldTable = document.createElement('table');
oldTable.innerHTML = showme;
newTable = document.createElement('table');
newTable.id = "newTable";
var i, r, c, j;
newNumRows = oldTable.getElementsByTagName('tr').length;
newNumCells = oldTable.getElementsByTagName('td').length;
newNumCols = newNumCells / newNumRows;
var newTableCells = newTable.getElementsByTagName('td');
var getImages = oldTable.getElementsByTagName('img');
for (r = 0; r < newNumRows; r++) {
row = newTable.insertRow(-1);
for (c = 0; c < newNumCols; c++) {
makeNodes = row.insertCell(-1);
}
}
for (var j = 0; j < newTableCells.length; j++) {
var theNodeImage = document.createElement("img");
newTableCells[j].appendChild(theNodeImage);
alert(newTableCells[j].innerHTML); //This gives me img tags
}
for (i = 0; i < getImages.length; i += 1) {
var oldSource = getImages[i]['src']; //gets the src of the images from the saved table
console.log(oldSource);
//alert(oldSource);//successfully alerts the image paths
var newPic = new Image(); //creates a new image
(function(newPic, oldSource) {
newPic.src = oldSource;
alert(newPic.src); //gives the same image paths
newTable.getElementsByTagName('img').src = newPic.src; //This doesn't work - table is blank???
})(newPic, oldSource);
}
var showIt = document.getElementById('holdTable');
showIt.appendChild(newTable);
}
}
Now, this doesn't throw any errors. However, nor does it fill the table. It does give me the source and I think I have created the new image objects to attach to the img tags in the newTableCells, but the table is showing up blank. I don't know where I am going wrong. All help really welcome.
Note: Even as a hobbyist, even I know there are probably tons of more efficient ways to do this, but I purposely did it this way to try and help me understand the logic of each step I was taking.
In your code you have:
var newImages = newTable.getElementsByTagName('img');
for (var i = 0; i < newImages.length; i += 1) {
var picSource = newImages[i]['src'];
console.log(picSource);
}
At the end of this, picSource has the value of the last image's src attribute. Then there is:
function addNewImage(newNumCols) {
var newImg = new Image();
newImg.src = picSource;
col.appendChild(newImg);
newImg.onclick = function() {
alert("WOW");
};
}
A value is passed to newNumCols but not used in the function. The value of picSource comes from the outer execution context and is not changed, so it's still the last image src from the previous for loop.
for (r = 0; r < newNumRows; r++) {
row = newTable.insertRow(-1);
for (c = 0; c < newNumCols; c++) {
col = row.insertCell(-1);
addNewImage(newNumCols);
}
}
This loop just keeps calling addNewImage with a single parameter that isn't used in the function, so you get the same image over and over.
For the record, the addNewImage function does have a closure to picSource, but it also has a closure to all the variables of the outer execution contexts. This isn't the issue, though it perhaps masks the fact that you aren't setting a value for picSource on each call, so you get the left over value from the previous section of code.
You haven't provided any indication of the content of showme, so it's impossible to determine if this approach will work at all.
Note
Where you have:
var showme = localStorage.getItem(name);
alert("I got the table");
var newTable = document.createElement('table');
newTable.innerHTML = showme;
newTable.id = "newTable";
IE does not support setting the innerHTML property of table elements, though you can create an entire table as the innerHTML of some other element and set the innerHTML of a cell (tr, th). If you want to use this approach, consider:
var div = document.createElement('div');
div.innerHTML = '<table id="newTable">' + showme + '<\/table>';
var newTable = div.firstChild;

Faulty Logic in this image color equalization algorithm

Somewhere in my code, I seem to be doing something wrong and I cannot tell which part is going awry. I've printed to console the values I'm getting from the various arrays and it seems to match up. Then when I run the equalization function (a la Wikipedia-Histogram Equalization) my output image is close to total black. I was trying to interpret this guy's php into javascript just to test some stuff out and figured I did a decent job. But I'm not an expert.
The pertinent parts:
function imageLoaded(ev) {
element = document.getElementById("canvas1");
c = element.getContext("2d");
im = ev.target; // the image
// read the width and height of the canvas
width = element.width;
height = element.height;
// stamp the image on the left of the canvas:
c.drawImage(im, 0, 0);
// get all canvas pixel data
imageData = c.getImageData(0, 0, width, height);
w2 = width / 2;
var reds = new Array();
var greens = new Array();
var blues = new Array();
var freqR = new Array();
var freqG = new Array();
var freqB = new Array();
if (imageData){
buildHistograms(reds, greens,blues);
buildFrequencies(reds, greens, blues, freqR, freqG, freqB);
}
var alpha = 255/(w2*height);
// run through the image
for (y = 0; y < height; y++) {
inpos = y * width * 4; // *4 for 4 ints per pixel
outpos = inpos + w2 * 4;
for (x = 0; x < w2; x++) {
//reads pixel data(of img c)to each channel of rgb
r = imageData.data[inpos++];
g = imageData.data[inpos++];
b = imageData.data[inpos++];
a = imageData.data[inpos++];
//using histogram eqalization formula:
adjR = freqR[r]*alpha;
adjG = freqG[g]*alpha;
adjB = freqB[b]*alpha;
//assigns pixel data of output image
imageData.data[outpos++] = adjR;
imageData.data[outpos++] = adjG;
imageData.data[outpos++] = adjB;
imageData.data[outpos++] = a;
}
}
// put pixel data on canvas
c.putImageData(imageData, 0,0);
}
im = new Image();
im.onload = imageLoaded;
im.src = "Lenna.png";
function buildHistograms(reds,greens,blues){
//run through image building histogram
for (y=0; y < height; y++){
inpos = y * width *4;
for (x=0; x < w2; x++){
rd = imageData.data[inpos++];
g = imageData.data[inpos++];
b = imageData.data[inpos++];
a = imageData.data[inpos++];
// Add counts to our histogram arrays for each color.
reds.push(rd);
greens.push(g);
blues.push(b);
}
}
// Sort them by keys into order
reds.sort(function(a,b){return a-b});
greens.sort(function(a,b){return a-b});
blues.sort(function(a,b){return a-b});
}
function buildFrequencies(reds, greens, blues, freqR, freqG, freqB){
// Build frequency charts for all colors: takes REDS GREENS BLUES from buildHistograms and places them on top of each other accordingly
for(i=0; i<=255; i++){
sumR=0;
sumG=0;
sumB=0;
for(j=0; j<= i; j++){
if (reds[j]){sumR+=reds[j];}
if (greens[j]){sumG+=greens[j];}
if (blues[j]){sumB+=blues[j];}
}
freqR[i] = sumR;
freqG[i] = sumG;
freqB[i] = sumB;
}
}
Any help is appreciated, Thanks.
Looks like my build frequencies section was all wrong. I modified it in this way:
var len = reds.length;
for (j=0; j < len; j++) {
var rCurrVal = reds[j];
var gCurrVal = greens[j];
var bCurrVal = blues[j];
if (freqR.hasOwnProperty(rCurrVal)) {
freqR[rCurrVal] += 1;
} else {
freqR[rCurrVal] = 1;
}
if (freqG.hasOwnProperty(gCurrVal)) {
freqG[gCurrVal] += 1;
} else {
freqG[gCurrVal] = 1;
}
if (freqB.hasOwnProperty(bCurrVal)) {
freqB[bCurrVal] += 1;
} else {
freqB[bCurrVal] = 1;
}
}
for (i=0; i<255; i++){
if ($.inArray(i,reds)===-1){freqR[i]=0;}
if ($.inArray(i,greens)=== -1){freqG[i]=0;}
if ($.inArray(i,blues)=== -1){freqB[i]=0;}
if (i>0){
freqR[i]+=freqR[i-1];
freqG[i]+=freqG[i-1];
freqB[i]+=freqB[i-1];
}
}

Categories

Resources