Autor | Zpráva | ||
---|---|---|---|
kozusnik.jan Profil * |
#1 · Zasláno: 19. 1. 2013, 10:50:08
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 |
#2 · Zasláno: 19. 1. 2013, 14:41:49
Hledej "preloading image". Obrázky se načtou a po načtení stránky je můžeš vykreslit.
|
||
kozusnik.jan Profil * |
#3 · Zasláno: 19. 1. 2013, 15:37:39
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 |
#4 · Zasláno: 19. 1. 2013, 16:01:20
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 * |
#5 · Zasláno: 19. 1. 2013, 17:13:34
díky moc ;) k čemu je dobrý ten callback?
|
||
nevim Profil * |
#6 · Zasláno: 19. 1. 2013, 17:24:00
K tomu abys nezačal vykreslovat nenačtené obrázky.
|
||
kozusnik.jan Profil * |
#7 · Zasláno: 19. 1. 2013, 17:33:20
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 |
#8 · Zasláno: 19. 1. 2013, 17:52:19
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 * |
#9 · Zasláno: 19. 1. 2013, 18:00:44
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 |
#10 · Zasláno: 19. 1. 2013, 18:12:39
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 * |
#11 · Zasláno: 19. 1. 2013, 18:19:05 · Upravil/a: kozusnik.jan
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 * |
#12 · Zasláno: 19. 1. 2013, 19:39:57
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 |
#13 · Zasláno: 19. 1. 2013, 20:39:04
Chtělo by to živou ukázku. Takhle to je zbytečně složité.
|
||
kozusnik.jan Profil * |
#14 · Zasláno: 20. 1. 2013, 12:25:51
živá ukázka: http://e-shoppingpark.cz/test/index.php?view=EntranceNew heslo: honza, user: honza
|
||
1Pupik1989 Profil |
#15 · Zasláno: 20. 1. 2013, 16:37:33
Tam toho asi moc neuvidím. "Uncaught ReferenceError: load is not defined".
|
||
kozusnik.jan Profil * |
#16 · Zasláno: 20. 1. 2013, 17:11:33
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 * |
#18 · Zasláno: 21. 1. 2013, 16:06:43 · Upravil/a: kozusnik.jan
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 ////////////////////////////////////////////// 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 * |
#19 · Zasláno: 21. 1. 2013, 18:27:07
Děkuji za pomoc
|
||
1Pupik1989 Profil |
#20 · Zasláno: 21. 1. 2013, 20:38:04
Jak jsem psal. Proměnná nebyl Image Object, nýbrž jen textový řetězec.
|
||
kozusnik.jan Profil * |
#21 · Zasláno: 21. 1. 2013, 21:39:05
No když si ale teď nechám vypsat hodnotu např. toho NameShop17, tak mi to vypíše Object HTMLImageElement
|
||
kozusnik.jan Profil * |
#22 · Zasláno: 21. 1. 2013, 22:49:25
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 * |
#25 · Zasláno: 22. 1. 2013, 14:54:52
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 Profil * |
#27 · Zasláno: 22. 1. 2013, 17:10:32
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 |
#28 · Zasláno: 23. 1. 2013, 09:42:59
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 * |
#29 · Zasláno: 23. 1. 2013, 17:25:35 · Upravil/a: kozusnik.jan
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) { . . . . } omlouvám se, ve funkci zoomOut a zoomIn má být místo drawScene(images, zoomed) funkce drawZoomed(images) resp. drawNormal(images). |
||
1Pupik1989 Profil |
#30 · Zasláno: 23. 1. 2013, 18:28:02
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 .
|
||
Téma pokračuje na další straně.
|
0