Interaktivni grafički objekti na Web-u

Matejka Ivančić • Zagreb, lipanj 2012.

TO VIŠE NIJE TAKO...

Nove tehnologije

otvaraju mogućnosti izrade naprednih grafičkih aplikacija bez potrebe dodatnih priključaka

Teme rada:

Canvas

Canvas - osnove korištenja

-> Sada imamo prazan „papir“ za crtanje

    <canvas id="canvas" width="300" height="300"></canvas>
    

Canvas - ostvarivanje prikaza u kontekstu

Jednostavan primjer crtanja sa canvasom

  var canvas = document.getElementById('canvas');
  var ctx = canvas.getContext('2d');

  ctx.fillStyle = "rgb(4,113,196)";
  ctx.fillRect (10, 10, 55, 50);
  ctx.fillStyle = "rgba(196, 4, 4, 0.5)";
  ctx.fillRect (30, 30, 55, 50);  
Crtanje pravokutnika

fillRect(x,y,width,height) : crta ispunjeni
strokeRect(x,y,width,height) : crta obrub
clearRect(x,y,width,height) : obriše područje


Korištenje staza

omogućuje crtanje kompleksnijih oblika

Kako to izgleda u praksi...

Grafičko stanje

Transformacije

KineticJS

KineticJS

KineticJS je HTML5 Canvas JavaScript biblioteka koja proširuje 2D kontekst omogućujući canvas interaktivnost za desktop i mobilne aplikacije

Kako KineticJS radi?

  • 4. Rezultat

    Rezultat je mješavina korisničkih slojeva.

  • 3. Korisnički slojevi

    Korisnički slojevi su slojevi koje programeri mogu koristiti kako god hoće. KineticJS aplikacije zahtijevaju barem jedan sloj.

  • 2. Sloj iza pozornice

    Sloj iza pozornice je skriveni sloj koji koristi prilagođeni canvas kontekst za crtanje nevidljivih oblika radi visokih performansi detekcija staza i izvršavanje rukovatelja događaja oblika.

  • 1. Sloj spremnika

    Sloj spremnika je skriveni sloj koji se koristi za detekciju slikovnih elemenata i canvas kompozicije.

Stvaranje pozornice

      var stage = new Kinetic.Stage({
        container: "container",
        width: 578,
        height: 200
      });
      var layer = new Kinetic.Layer();

      stage.add(layer);
  

Crtanje oblika

Svi oblici se zadaju na sličan način: instanciranje željenog objekt sa željenim svojstvima (konfiguracija objekta).

     var rect = new Kinetic.Rect({
        x: 20,
        y: 50,
        width: 100,
        height: 50,
        fill: "#00D2FF",
        stroke: "black",
        strokeWidth: 4
     });

     layer.add(rect); // dodaj objekt sloju
   

Događaji

     shape.on('mousedown mouseover', function(evt){
        // do something
      });
   
Detekcija slikovnih elemenata
Povuci i pusti operacija
   var shape = new Kinetic.Circle({
    draggable: true;
   });
   shape.draggable(true);
   

Prijelazi

Linearan prijelaz

Ostali prijelazi

Easing prijelazi: linear, ease-in, ease-out, ease-in-out, back-ease-in, back-ease-out, back-ease-in-out, elastic-ease-in, elastic-ease-out, elastic-ease-in-out, bounce-ease-in, bounce-ease-out, bounce-ease-in-out, strong-ease-in, strong-ease-out, i strong-ease-in-out
    shape.transitionTo({
      x: 100,
      duration: 1,
      easing: 'bounce-ease-out'
    });
   
Zaustavljanje i nastavljanje prijelaza
Svaki prijelaz se može zaustaviti i nastaviti s stop() i resume() metodama
    trans.stop();    // stop transition
    trans.resume();  // resume transition
   

Easing prijelazi


WebGL

WebGL

WebGL prednosti


No WebGL je API niske razine (eng. low-level), pa tako i jednostavne stvari u WebGL-u rezultiraju u velikoj količini koda, te za razliku od crtanja u canvasu nije jednostavno za korištenje.

Priprema za prikaz u 3D-u

      var canvas;
      var gl;
      
      function start() {
        canvas = document.getElementById("glcanvas");
        initWebGL(canvas); // inicijalizacija GL konteksta
        // nastavlja se samo ako je WebGL dostupan i radi
        if (gl) {
          gl.clearColor(0.0, 0.0, 0.0, 1.0);  // Postavi boju za brisanje
          gl.clearDepth(1.0);                 // Čisti kontekst
          gl.enable(gl.DEPTH_TEST);           // Omogućiti testianje dubine
          gl.depthFunc(gl.LEQUAL);            // Bliže stvari skrivaju dalje
        }
      }
  

Inicijalizacija konteksta

    function initWebGL(canvas) { 
      gl = null; 
    
      try {
        gl = canvas.getContext("webgl") 
            || canvas.getContext("experimental-webgl"); 
      }
      catch(e) {}
      if (!gl) { 
        alert("Neuspješnja inicijalizacija WebGL."); 
      } 
    }
  

Osvjetljavanje scene

Crtamo u 3D prostoru -> potrebno je postaviti programe za sjenčanje koji govore WebGL-u gdje treba crtati i što

Inicijalizacija programa za sjenčanje:
Program za sjenčanje fragmenata
    
   
Program za sjenčanje vrhova
    
   

Kreiranje objekta

Prije crtanja objekta kreiramo spremnik svih vrhova
      function initBuffers() {
        // spremnik vrhova
        squareVerticesBuffer = gl.createBuffer();
        
        // vezanje spremnika za kontekst
        gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesBuffer);
        
        var vertices = [
          1.0,  1.0,  0.0,
          -1.0, 1.0,  0.0,
          1.0,  -1.0, 0.0,
          -1.0, -1.0, 0.0
        ];
        
        gl.bufferData(gl.ARRAY_BUFFER, 
            new Float32Array(vertices), gl.STATIC_DRAW);
      }
   

Crtanje scene

      function drawScene() {
        // brisanje konteksta 
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
        
        // perspektiva kamere (pogled na scenu)
        // vidno polje od 45° s omjerom širine i visine 640/480
        // crtamo predmete između 0.1 i 100 jedinica
        perspectiveMatrix = makePerspective(45, 640.0/480.0, 0.1, 100.0);
        
        // postavljanje pozicije objekta
        loadIdentity(); // mvMatrix = Matrix.I(4);
        mvTranslate([-0.0, 0.0, -6.0]);
        
        gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesBuffer);
        gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
        setMatrixUniforms();
        gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); // crta 0bjekt
      }
   

Primjena boje na vrhovima

Bojanje fragmenata
    
    
Crtanje koristeći boje

Three.js

Three.js

Kreiranje prikaza scene
  var renderer = new THREE.WebGLRenderer({antialias: true});
  renderer.setSize(document.body.clientWidth,
                  document.body.clientHeight);
  
Dodavanje prikaza scene u HTML dokument
  document.body.appendChild(renderer.domElement);
  
Rezultat:

Kreiranje kamere
  // new THREE.PerspectiveCamera( FOV, viewAspectRatio, zNear, zFar );
  var camera = new THREE.PerspectiveCamera(45, width/height, 1, 10000);
  camera.position.z = 300;
  
Kreiranje scene s kuglom
  var scene = new THREE.Scene();
  var sphere = new THREE.Mesh(new THREE.SphereGeometry(50, 16, 16),
      new THREE.MeshLambertMaterial({color: 0xCC0000}));
  scene.add(sphere);    
  
Prikaz scene iz kamere
  renderer.render(scene, camera);
  
Kreiranje svijetla
  var light = new THREE.SpotLight();
  light.position.set( 10, 50, 130 );
  scene.add(light);
  
Sjene
  // omogućiti sijene za prikaz scene
  renderer.shadowMapEnabled = true;
  
  // omogućiti sjene za svijetlo
  light.castShadow = true;
  
  // omogućiti sjene za objekt
  sphere.castShadow = true;
  sphere.receiveShadow = true; 
  
Odabir objekata
Projektiramo zraku u scenu i pronalazimo sjecišta s objektima
  var projector = new THREE.Projector();
  window.addEventListener('mousedown', function (ev){
    if (ev.target == renderer.domElement) {
      var x = ev.clientX;
      var y = ev.clientY;
      var v = new THREE.Vector3((x/width)*2-1, -(y/height)*2+1, 0.5);
      projector.unprojectVector(v, camera);
      var ray = new THREE.Ray(camera.position, 
                              v.subSelf(camera.position).normalize());
      var intersects = ray.intersectObjects(controller.objects);
      if (intersects.length > 0) {
        controller.setCurrent(intersects[0].object);
      }
    }
  }, false);
  

Zaključak

Uvođenje novih tehnologija canvas i WebGL omogućuje

Your browser doesn't support the features required by impress.js, so you are presented with a simplified version of this presentation.

For the best experience please use the latest Chrome, Safari or Firefox browser.