Kreslení složitého objektu do HTML5 canvas

mhi

  • ***
  • 240
    • Zobrazit profil
Kreslení složitého objektu do HTML5 canvas
« kdy: 14. 06. 2020, 20:01:05 »
Delam jednoduchy javascriptovy nastroj, ktery mi umozni zjistit co je v STL souboru (3D model). Mam to naprogramovane tak, ze nactu STL do pole poli, ktere potom javascriptem kreslim (jako cary do 2D canvas contextu; nize v obrazku cerne). Nad tim mam dalsi zindex+1 layer s dalsi canvas, ktery mi dela "kurzor" (nize v obrazku zeleny) a bude i kreslit koty + rez do dalsi osy. Nemusim tedy prekreslovat puvodni STL model pri pohybu kurzoru, coz muze trvat i velmi dlouho - radove vteriny pro tohoto typu model s 60k facety  https://pasteboard.co/Jd53wIP.png (nejake slozite 3D-scanovane objekty maji stovky tisic facetu trva to treba 5-10 vterin!).

Moje otazka je zda to kresleni do dvou vrstev nedelam nejak blbe (neni na to nejaka lepsi metoda?), pripadne jak vyresit lepe kresleni toho 3D objektu ze STL souboru. Planuju preoptimalizovat facety z trojuhelniku na slozitejsi utvary (provede se pri loadu), principielne mi ale jde hlavne o to vykreslovani, zde je kod:

Kód: [Vybrat]
  ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); 
     
  for (j=0;j<geometry.length;j++) {
             
    ctx.beginPath();
    ctx.moveTo((geometry[j][geometry[j].length-1][axisX]-min[axisX])*scale*mulX + addX,(geometry[j][geometry[j].length-1][axisY]-min[axisY])*scale*mulY + addY);
   
    for (i=1;i<geometry[j].length;i++) {
   
      ctx.lineTo((geometry[j][i][axisX]-min[axisX])*scale*mulX + addX,(geometry[j][i][axisY]-min[axisY])*scale*mulY + addY);
     
    }
    ctx.stroke();

promenne axisX/Y, mulX/Y, addX/Y, min[..], max[..] resi ruzna zobrazeni, nejaka dalsi rutina tyto promenne prednaplni.

Druha otazka je jak udelat dragovani + zoom, aby to bylo uzivatelsky privetive. Je nejaka lepsi cesta, nez ze transformuji puvodni canvas pres CSS canvas.style.xxx = ... (posun+zoom, u tabletu bude i rotace kdyz clovek zamatla dvema prsty) a kdyz uzivatel dokonci operaci nebo dobehne nejaky timer, tak vykreslim novou canvas? Pripadne uz pri nejakem timeoutu si muzu kreslit do schovane canvas a ty jen prohodit (zviditelnit "tu lepsi").

Javascript/HTML/CSS mne nezivi, tak se chci zeptat zkusenejsich nez to cele budu programovat cestou vedouci do slepe ulicky.

PS: Nejaky takovy nastroj na STLka jako delam by se mi hodil, jestli nekdo neco znate klidne poslete odkaz; nicmene mym cilem je se naucit spis to co tady programuju pro jiny, slozitejsi projekt. Takze ten STL inspektor je jen takovy bonus na kterem se ucim, protoze to je docela jednoducha aplikace. Musi to chodit jak na pocitaci tak tabletech, tzn mysi klikani i ruzne touch operace, ale to neni jadro dotazu.
« Poslední změna: 14. 06. 2020, 21:57:12 od Petr Krčmář »


Re:Kresleni sloziteho objektu do html5 canvas
« Odpověď #1 kdy: 14. 06. 2020, 20:30:09 »
proc to vykreslujete jako 2d obrazek? tohle jste zkousel? https://www.npmjs.com/package/three-stl-loader

urcite bych se podival na three.js, jestli uvazujete o 3d grafice. Najdete spousty prikladu pro ruzne prohlizece modelu. Ta knihovna se pouziva velice jednoduse.

https://threejs.org/
« Poslední změna: 14. 06. 2020, 20:35:39 od A.P.Hacker »

Re:Kresleni sloziteho objektu do html5 canvas
« Odpověď #2 kdy: 14. 06. 2020, 20:42:45 »
v prikladech v adresari examples three.js maji prohlizec stl souboru

https://github.com/mrdoob/three.js/blob/dev/examples/webgl_loader_stl.html

mhi

  • ***
  • 240
    • Zobrazit profil
Re:Kresleni sloziteho objektu do html5 canvas
« Odpověď #3 kdy: 14. 06. 2020, 20:46:42 »
THREE.js znam, nicmene pro ten dalsi projekt potrebuju to 2D (tam jde o slozitejsi strukturu vektorovych a bitmapovych objektu, ktere budu muset zobrazit bud pres nejake DIVy nebo canvasy, resp. kombinaci obojiho; to uz ale dost zabiham pryc od tematu). Navic jestli jsem spravne pochopil jak three.js funguje, stjene by mi to nepomohlo-chci ruzna zobrazeni toho STL a stejne bych v 3D musel prekreslovat vse co chci (napr. jen objekty "za" urcitou hranici v nezobrazovane ose, abych mohl udelat rez objektem, pripadne jen prumet rovinou rezu).

Pro to zoomovani mne jeste napadla cesta si udelat jeden obrovsky canvas nezavisly na rozliseni monitoru a s nim soupat,  ale nevim co by na to rekly prohlizece (uz takhle mam 2x canvas o rozmerech okna).

Re:Kresleni sloziteho objektu do html5 canvas
« Odpověď #4 kdy: 14. 06. 2020, 20:52:16 »
Druha otazka je jak udelat dragovani + zoom, aby to bylo uzivatelsky privetive. Je nejaka lepsi cesta, nez ze transformuji puvodni canvas pres CSS canvas.style.xxx = ... (posun+zoom, u tabletu bude i rotace kdyz clovek zamatla dvema prsty) a kdyz uzivatel dokonci operaci nebo dobehne nejaky timer, tak vykreslim novou canvas? Pripadne uz pri nejakem timeoutu si muzu kreslit do schovane canvas a ty jen prohodit (zviditelnit "tu lepsi").

urcite nezvetsujte cely canvas, transformujte jen souradnice uvnitr canvasu

https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/scale

https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setTransform


Re:Kresleni sloziteho objektu do html5 canvas
« Odpověď #5 kdy: 14. 06. 2020, 20:59:40 »
THREE.js znam, nicmene pro ten dalsi projekt potrebuju to 2D (tam jde o slozitejsi strukturu vektorovych a bitmapovych objektu, ktere budu muset zobrazit bud pres nejake DIVy nebo canvasy, resp. kombinaci obojiho; to uz ale dost zabiham pryc od tematu). Navic jestli jsem spravne pochopil jak three.js funguje, stjene by mi to nepomohlo-chci ruzna zobrazeni toho STL a stejne bych v 3D musel prekreslovat vse co chci (napr. jen objekty "za" urcitou hranici v nezobrazovane ose, abych mohl udelat rez objektem, pripadne jen prumet rovinou rezu).
canvas je asi jednodusi nez to skladat z divu. Mozna SVG by na to mohl byt vhodny.
Pro to zoomovani mne jeste napadla cesta si udelat jeden obrovsky canvas nezavisly na rozliseni monitoru a s nim soupat,  ale nevim co by na to rekly prohlizece (uz takhle mam 2x canvas o rozmerech okna).
to bych urcete nedelal. canvas podporuje transformace souradnic.

Re:Kresleni sloziteho objektu do html5 canvas
« Odpověď #6 kdy: 14. 06. 2020, 21:08:39 »
THREE.js znam, nicmene pro ten dalsi projekt potrebuju to 2D (tam jde o slozitejsi strukturu vektorovych a bitmapovych objektu

mozna by se dal pouzit jen three.js loader stl souboru a vykreslit to rucne
« Poslední změna: 14. 06. 2020, 21:10:31 od A.P.Hacker »

mhi

  • ***
  • 240
    • Zobrazit profil
Re:Kreslení složitého objektu do HTML5 canvas
« Odpověď #7 kdy: 14. 06. 2020, 23:41:47 »
STL javascript loader mam, to funguje OK. Jde mi skutecne o tu techniku jak takove veci do canvasu kreslit aby to nebyl zrout pameti nebo to nebylo moc pomale.

Cim vic o tom premyslim, tim vic mam intuitivni pocit, ze bude nutna nejaka kombinace DOM + canvas, tedy pri aktivni operaci uzivatele prioritne hybat existujicim canvasem nebo ho transformovat a na pozadi si v klidu prekreslit nove zobrazeni a to podstrcit uzivateli. Pri zoomu je stale asi jedno ze se objevi detaily az po chvili, pri pohybu staci dokreslit jen ty nove odkryte casti.

Re:Kreslení složitého objektu do HTML5 canvas
« Odpověď #8 kdy: 14. 06. 2020, 23:48:07 »
Cim vic o tom premyslim, tim vic mam intuitivni pocit, ze bude nutna nejaka kombinace DOM + canvas, tedy pri aktivni operaci uzivatele prioritne hybat existujicim canvasem nebo ho transformovat a na pozadi si v klidu prekreslit nove zobrazeni a to podstrcit uzivateli. Pri zoomu je stale asi jedno ze se objevi detaily az po chvili, pri pohybu staci dokreslit jen ty nove odkryte casti.

jakekoliv operace s DOMem jsou radove pomalejsi nez prekresleni celeho canvasu.

Kit

  • *****
  • 545
    • Zobrazit profil
    • E-mail
Re:Kreslení složitého objektu do HTML5 canvas
« Odpověď #9 kdy: 15. 06. 2020, 00:07:42 »
Pokud uvažuješ o DOM, tak to rovnou udělej v SVG. Vykreslí se to samo.

Re:Kreslení složitého objektu do HTML5 canvas
« Odpověď #10 kdy: 15. 06. 2020, 00:32:32 »
ten vas kod zrychlite pouzitim Path2D

pro rychle vykreslovani komplexnich tvaru je nejlepsi webGL.

Re:Kreslení složitého objektu do HTML5 canvas
« Odpověď #11 kdy: 15. 06. 2020, 10:25:10 »
Pro rychly posun/rotaci/zmensovani se da vyrenderovat do bitmapy, ale podle me je to zbytecna komplikace oproti webgl, ktere se da pouzit i pro 2d grafiku. Proste v tom three.js vypnete perspektivu a nepujde to rozeznat od 2d.
« Poslední změna: 15. 06. 2020, 10:27:02 od A.P.Hacker »