« 1 2 »
Autor Zpráva
kozusnik.jan
Profil *
Ahoj, potřeboval bych poradit s načítáním více obrázků do canvasu přes JS. Na stránce mám na vykreslení zatím kolem 20 obrázků, některé vykresluji 1, některé vícekrát... problém je, že se stává (hlavně v mozille), že se některé z nich někdy prostě nenačtnou nebo nevykreslí, což je docela problém. Nevíte, jak to vyřešit?
1Pupik1989
Profil
Hledej "preloading image". Obrázky se načtou a po načtení stránky je můžeš vykreslit.
kozusnik.jan
Profil *
no hledal jsem, ale našel jsem akorát věci ve stylu : http://neteye.github.com/activity-indicator.html - prostě jen ty animace, které jsou při načítání, ale nenašel jsem nějaký skript, který by nahrál ty obrázky dopředu... nemáte nějaký odzkoušený?
1Pupik1989
Profil
Třeba zde.

function preloader() 
 {
 
     // counter
     var i = 0;
 
     // create object
     imageObj = new Image();
 
     // set image list
     images = new Array();
     images[0]="image1.jpg"
     images[1]="image2.jpg"
     images[2]="image3.jpg"
     images[3]="image4.jpg"
 
     // start preloading
     for(i=0; i<=3; i++) 
     {
          imageObj.src=images[i];
     }
 
 }

Já tedy mám preloader i s callbackem, je to jistější. Je to něco na styl tohoto
kozusnik.jan
Profil *
díky moc ;) k čemu je dobrý ten callback?
nevim
Profil *
K tomu abys nezačal vykreslovat nenačtené obrázky.
kozusnik.jan
Profil *
chci se ještě zeptat, tak funkce z odkazu mi vytváří proměnné s obrázky ve stylu newimages[1], newimages[2]... ale já používám jiné "názvosloví" obrázků - obrázky pojmenovávám konkrétně podle toho, kde jsou použity a potom je i takhle v canvasu volám. Tudíž asi budu muset v canvasu obrázky přejmenovat že?
Nedalo by se to vyřešit nějak ve stylu, že bych měl vytvořené pole, kde by byly uloženy názvy proměnných, pod jakými volám obrázky v canvasu a potom bych ty názvy v té funkce tahal z toho?
Nějak takhle:
imageName[1] = "shop1Background";
imageName[2] = "shop2Background";
imageName[3] = "floorBackground";
....

a potom při procházení obrázků by se mi ve funkci místo takového ukládání:
newImages[1] = ......;
newImages[2] = ......;
newImages[3] = ......;
ukládaly takhle:
shop1Background = ......;
shop2Background = ......;
floorBackground = ......;
1Pupik1989
Profil
Pokud se použije ta s callbackem, tak se obrázky přímo do callbacku.

preloadimages("earth.jpg","earth2.jpg").done(function(images){
  alert(images);
});

V tomto případě jsou uloženy v proměnné images.
Další možnost je definovat si proměnnou s libovolným názvem.

var shop1Background = newImages[0];

nebo

window["shop1Background"] = newImages[0];

Šlo by uložit název souboru i přímo do pole nebo objektu.

newImages["shop1Background"]
kozusnik.jan
Profil *
a to var Shop1Background = newImages[0] stačí vložit až za zavolání funkce? takhle? ↓
preloadimages(['1.gif', '2.gif', '3.gif']).done(function(images){
 //call back codes, for example:
 vykresli();
})
Shop1Background = newImages[0];
1Pupik1989
Profil
Dovnitř. Všechno se musí odehrávat až od callbacku.

preloadimages(['1.gif', '2.gif', '3.gif']).done(function(images){
 Shop1Background = newImages[0];
 vykresli();
});

Nebo se to může dát dovnitř funkce vykresli

Já osobně používám následující funkci.

function preloadimages(arr,callback){
    var newimages=[], loadedimages=0
    var postaction=function(){}

    function imageloadpost(){
        loadedimages++;
        if (loadedimages==Object.keys(arr).length){
            callback(newimages) //call postaction and pass in newimages array as parameter
        }
    }
    for (var i in arr){
      if(arr.hasOwnProperty(i)){
        newimages[i]=new Image();
        newimages[i].src=arr[i];
        newimages[i].onload=function(){
            imageloadpost();
        };
        newimages[i].onerror=function(){
            imageloadpost();
        };
      }
    }
};

//spuštění
preloadimages({
  Shop1Background:"Shop1Background.jpg",
  Shop2Background:"Shop2Background.jpg"
},function(images){
  alert(images.Shop1Background);  //vrátí HTML ImageElement
});

Čili by stačilo jen napsat název objekt před tu proměnou.

Shop1Background

//nahradit za

images.Shop1Background

Ná názvu proměnné už nezáleží.

Jediný problém té mé funkce je, že Internet Explorer nemá metodu Object.keys. Ta už se dá ale snadno dodělat.
kozusnik.jan
Profil *
no asi použiji tu první variantu :) ta funkce vypadá sice lépe, ale vůbec ji nechápu...


jak se dá zpravit ten problém s Object.keys v IE?
kozusnik.jan
Profil *
už to funguje. dá se to ale nějak použít na vytvoření patterns?
zkusil jsem to udělat takhle:
var pillarsFillImage = images[15];
.
.
.

pillarsFillRepeatOption = "repeat"; // values: repeat, no-repeat, repeat-x, repeat-y
var pillarsFill = ctx.createPattern(pillarsFillImage, pillarsFillRepeatOption);
.
.
.
ctx.fillStyle = pillarsFill;
.
.
.
ale nefunguje, tak nevím...
1Pupik1989
Profil
Chtělo by to živou ukázku. Takhle to je zbytečně složité.
kozusnik.jan
Profil *
živá ukázka: http://e-shoppingpark.cz/test/index.php?view=EntranceNew heslo: honza, user: honza
1Pupik1989
Profil
Tam toho asi moc neuvidím. "Uncaught ReferenceError: load is not defined".
kozusnik.jan
Profil *
Jak to myslíte? Mi to jede v pohodě, teda až na ten pattern
1Pupik1989
Profil
Už to vidím. Chyba na řádku 1900 v souboru "mainEntranceNew.js". Ta je z jediného prostého důvodu. V NameShop17 se totiž nenachází HTMLImageElement ale jen jeho url.

NameShop17 = 'images/entrance/categories/kuchyne.png';

Konzole to i hlásí.

Uncaught TypeError: Type error 
kozusnik.jan
Profil *
jak to myslíte?
Mám to tam takhle:
////////////////////////// EXPENSE //////////////////////////////////////////////////
var NameShop17 = new Image();
NameShop17.onload = function() {
keystoneAndDisplayImageUpdate(ctx, NameShop17, shop17FromXup+8, shop17FromYup+35, NameShop17.width * 0.9, 1 , NameShop17.height, -0.04);
}
NameShop17.src = 'images/entrance/categories/kuchyne.png';
////////////////////////// END EXPENSE //////////////////////////////////////////////
Obdobně je tě u dalších 17 obrázků. Žádnou chybu mi to nikde nechází. Ani v Chrome, ani v NetBeans, ani v Mozille jsem si toho nevšiml


Pardon, moje chyba. Udělal jsem blbost... špatně jsem se zorientoval. Jak to teda mám udělat?
Mám to zatím v tomto stylu:
function preloadimages(arr){
    var newimages=[], loadedimages=0
    var postaction=function(){}
    var arr=(typeof arr!="object")? [arr] : arr
    function imageloadpost(){
        loadedimages++
        if (loadedimages==arr.length){
            postaction(newimages) //call postaction and pass in newimages array as parameter
        }
    }
    for (var i=0; i<arr.length; i++){
        newimages[i]=new Image()
        newimages[i].src=arr[i]
        newimages[i].onload=function(){
            imageloadpost()
        }
        newimages[i].onerror=function(){
            imageloadpost()
        }
    }
    return { //return blank object with done() method
        done:function(f){
            postaction=f || postaction //remember user defined callback functions to be called when images load
        }
    }
}
.
.
.
.
function draw() {
pillarsFillImage = 'images/entrance/pillarsFill.png';
.
.
. 
imagesarray[15] = pillarsFillImage;
.
.
.
preloadimages(imagesarray).done(function(images){
 drawThan(images);
})


function drawThan(images) { 
var pillarsFillImage = images[15];
.
.
.
pillarsFillRepeatOption = "repeat";  //  values: repeat, no-repeat, repeat-x, repeat-y
var pillarsFill = ctx.createPattern(pillarsFillImage, pillarsFillRepeatOption);

ctx.beginPath();
ctx.moveTo(Pillar1FromX, Pillar1FromY);
ctx.lineTo(Pillar1ToX, Pillar1FromY2);
ctx.lineTo(Pillar1ToX, Pillar1ToY2);
ctx.lineTo(Pillar1FromX, Pillar1ToY);
ctx.lineTo(Pillar1FromX, Pillar1FromY);
ctx.fillStyle = pillarsFill;
ctx.fill();
ctx.closePath();

}
 



nevím proč to předtím nejelo, nicméně teď už to jede. každopádně rozveďte prosím tu chybu, co jste tam našel, to s tou konzolí. Děkuji
kozusnik.jan
Profil *
Děkuji za pomoc
1Pupik1989
Profil
Jak jsem psal. Proměnná nebyl Image Object, nýbrž jen textový řetězec.
kozusnik.jan
Profil *
No když si ale teď nechám vypsat hodnotu např. toho NameShop17, tak mi to vypíše Object HTMLImageElement
kozusnik.jan
Profil *
nicméně, stránka se mi vykreslí v pořádku. jenže poté mám na stránce 2 odkazy - přiblížit a oddálit. po stisknutí každého z odkazů volámdrawScene. v té mám 2 podmínky - pokud je proměnná zoomed = 1, tak se mi zavolá funkce drawZoomed. Pokud je zoomed = 0, tak se mi zavolá drawNormal. Řeším ale problém, jak těmto funkcím mám předat hodnotu pole images, kde mám uložené přednačtené obrázky. Jak mám té funkci drawNormal, resp. drawZoomed předat ty images? přes parametry nemůžu, nebo teda aspoň je problém s tím předávat je při volání funkce drawScene, když ji volám přes kliknutí na odkaz. Jak byste to vyřešili?
1Pupik1989
Profil
Koukám, že to bude taky pseudo 3d výtvor. Zrovna se tím zabývám. Já si to jednoduše rozvrhl. Mám Model, ten načtu ze souboru. Vytvořím podle faců (tváří - většinou 3 až 4 body) trojúhelníky a nakonec k němu načtu texturu. Nenačítám je tedy najednou, ale postupně až když je potřebuji. Samozřejmě jsou načteny už před vykreslením. Pak je akorát v cyklu vykresluji, pokud se změnila scéna.

Já se zase zasekl u matic.


Koukám, že ve zdrojovém kódu je funkce keystoneAndDisplayImageUpdate. To není moc hezká funkce, pokud se často překresluje scéna.

Kouknětě na stackoverflow. Je tam funkce, která vlastně pracuje s maticí 3x3 a namapuje texturu do trojúhelníku. Při dostatečném rozdělení obrázku už to vypadá koukatelně a je to značně rychlejší.

Viz moje vlákno úplně dole ten pes z Residenta Evila..
_es
Profil
kozusnik.jan:
mám na stránce 2 odkazy - přiblížit a oddálit. po stisknutí každého z odkazů volámdrawScene.
Odkazy s protokolom javascript:? Prečo na ten účel účel používaš odkazy, keď to vo výsledku nemá slúžiť ako odkaz? Môžeš použiť tlačítko, alebo aj iný vhodný element a priradiť do jeho vlastnosti onclick ľubovolnú funkciu.
kozusnik.jan
Profil *
1Pupik1989:
no zatím to udělám ve 3D a pokusím se tam hodit nějaký 3D efekt pomocí obrázků - nebude se to hýbat, takže to bude relativně snadné snad. Nicméně musím tam udělat nějakého panáčka, který se bude pohybovat a toho chci ve 3D, což bude trochu problém. Ten tvůj tip vypadá zajímavě, ale moc se v tom neorijentuji. Mohl bys mi to trochu vysvětlit? Děkuji

_es:
To mě nenapadlo. Udělám to při kliknutí na ten canvas a nebudou tam žádné odkazy. Díky moc!
1Pupik1989
Profil
kozusnik.jan:
Viz. moje předešlé téma.

Je to vlastně namapování textury (obrázku) na trojúhelník.
kozusnik.jan
Profil *
prostuduji. vypadá to ale brutálně teda :D koukám, že tam je i kamera... no pořádně to prostuduji a nejspíš se ještě ozvu :D zatím děkuju
1Pupik1989
Profil
Vlastně ta funkce spočítá jen zkosení a transformuje canvas. Poté se vrátí do původní transformace.

Pro bod objektu máte definovány souřadnice x, y a z. K num přibydou ještě u a v. To jsou souřadnice obrázku. Toť vše. To počítání je vlastně matice 3x3.
kozusnik.jan
Profil *
aha. tak to nezní až tak složitě zase :) asi to použiji na toho panáčka a pak budu pomalu předělávat i prostředí do 3D ;)

No tak dělám ten zoom pomocí toho kliknutí, ale prostě nevím, jak to vyřešit, abych mohl vykreslit to přiblížené resp. oddálené prostředí... nevím jak předat funkci na vykreslení ty přednačtené obrázky. mám to zatím takhle:
preloadimages(imagesarray).done(function(images){
 drawNormal(images);

})

function zoomIn(images, zoomed) {
    if(zoomed == 1) {
 ctx.scale(2,2);
drawScene(images, zoomed);
    zoomed = 1; 
    }
    else alert("více už nelze přiblížit");
}
function zoomOut(images, zoomed) {
    if(zoomed == 0) {
  ctx.scale(0.5, 0.5);
drawScene(images, zoomed);
}
    else alert("více už nelze oddálit");
}



function onClick() {
if(zoomed == 0){ 
   drawNormal();
}

else {
    zoomed = 0;
    drawZoomed();
}
}

function drawNormal(images) {  
.
.
.
}

function drawZoomed(images) { 
.
.
.
.
}
Nevím jestli jsem blbý nebo tak, ale nemůžu na to prostě ani za nic přijít...


omlouvám se, ve funkci zoomOut a zoomIn má být místo drawScene(images, zoomed) funkce drawZoomed(images) resp. drawNormal(images).
1Pupik1989
Profil
No já bych z drawNormal a drawZoomed udělal jednu funkci, třeba draw.

Já tedy mám funkci na vykreslení v objektu Scene.

Takže volám Scene.render(). Při zoomu akorát nastavuji matici scale a při vykreslení jí pak násobím body.

Nešlo by to třeba
ctx.drawImage(image,x*zoom,y*zoom);?

Zkrátka násobit body místo používání ctx.scale.
« 1 2 »

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: