Raphaël.js – Eine JavaScript Bibliothek für Vektorgrafiken – Aufbau des Vortrags



Raphaël.js – Eine JavaScript Bibliothek für Vektorgrafiken – Aufbau des Vortrags

0 1


nook2013

My talk about Raphael.js for the Nook2013

On Github runjak / nook2013

Raphaël.js

Eine JavaScript Bibliothek für Vektorgrafiken

https://github.com/runjak/nook2013 Jakob @sicarius

Aufbau des Vortrags

Was sind Raster-/Vektorgrafiken? Scalable Vector Graphics (SVG) Beispiele mit Raphaël.js Intro zu Raphaël.js Fragen

Was sind Rastergrafiken?

  • Rastergrafiken sind aus einzelnen Bildpunkten zusammengesetzt.
  • Diese Bildpunkte sind in einem Raster angeordnet.
  • Dieses Verfahren entspicht der Darstellungsweise auf Bildschirmen.
  • Ein typisches Problem mit Rastergrafiken ist das skalieren:

Was sind Vektorgrafiken?

  • Statt aus einzelnen Bildpunkten sind Vektorgrafiken aus Primitiven zusammengesetzt.
  • Primitive haben eine Position im Bild.
  • Primitive können skaliert oder rotiert werden.

Typische Primitive

  • Polygone
  • Kreise/Ellipsen
  • Linien, Pfade
  • Text
  • Rastergrafiken
  • Gruppen von Primitiven

Wesentliche unterschiede zu Rastergrafiken:

  • Rastergrafiken sind leichter darzustellen.
  • Vektorgrafiken können sehr gut skaliert werden.
  • Vektorgrafiken zu erstellen ist für manche Anwendungsfälle einfacher.
  • Vektorgrafiken lassen sich mit einem einfachen Editor erstellen.

Scalable Vector Graphics (SVG):

  • Viele Browser können SVG darstellen.
  • SVG ist ein XML format, und sieht z.B. so aus:
    <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
      <rect width="300" height="100" style="fill:rgb(0,0,255);stroke-width:2;stroke:rgb(0,0,0)"></rect>
    </svg>
  • Der Browser macht daraus soetwas…

  • Es bietet sich an, SVG im Browser zu manipulieren.

Beispiele

…um zu sehen, was mit Raphaël.js so gebaut werden kann.
http://raphaeljs.com/analytics.html
http://raphaeljs.com/chart.html
http://raphaeljs.com/polar-clock.html
http://raphaeljs.com/pie.html
http://raphaeljs.com/graffle.html
http://raphaeljs.com/hand.html
http://raphaeljs.com/gear.html

Intro zu Raphaël.js

Intro zu Raphaël.js

Wesentliche Klassen:
  • Raphael - Erstellt Paper, stellt Hilfsfunktionen bereit
  • Paper - Hierauf wird gezeichnet
  • Element - Befinden sich auf dem Paper

Ein Paper wird geboren

//Ein Paper, 320x200px groß.
var paper = Raphael(10, 50, 320, 200);
//Ein Paper, dass in einem Element mit der Id 'notepad' erzeugt wird:
var paper = Raphael(document.getElementById("notepad"), 320, 200);
var paper = Raphael("notepad", 320, 200);
//Das Paper für die folgenden Beispiele:
var w = $(window).width()
  , h = $(window).height()
  , paper = Raphael(10, 10, w-20, h-20);

Kreise:

var circle = paper.circle(100,100,50);
circle.attr('fill', '#ff0000');
// Verketten von Methodenaufrufen:
/*paper.circle(120,120,50).attr('fill', '#0000ff').attr('opacity','0.5');*/
Run!

Rechtecke:

// Ein Rechteck:
paper.rect(200, 100, 75, 75).attr('fill', 'red');
// Ein Rechteck mit runden Ecken:
paper.rect(100, 200, 75, 75, 10).attr('fill', 'green');
// Kein Rechteck, und attr mit mehreren Werten:
paper.ellipse(500, 400, 100, 50).attr({fill: 'white', opacity: '0.5'});
Run!

Text:

paper.text(100, 50, 'foo')
     .attr({'font-size': 20, 'text-anchor': 'start'});
paper.text(100, 70, 'bar')
     .attr({'font-size': 30, 'text-anchor': 'middle', fill: '#00ff00'});
paper.text(100, 100, 'baz')
     .attr({'font-size': 40, 'text-anchor': 'end', stroke: '#ff0000'});
/*Default text-anchor ist middle*/
Run!

Bilder:

paper.image('data/pea.jpg',25,25,500,500);
Run!

Pfade:

var ps = [
  'M50,50L100,100'
//, 'M50,50H100'
//, 'M50,50V100'
//, 'M100,20,H200,V40,H100,Z'
];
for(var i = 0; i < ps.length; i++)
  paper.path(ps[i]) // Was ist getColor?
       .attr({ stroke: Raphael.getColor()
             , 'stroke-width': 2.5});
Raphael.getColor.reset();
Run!

Format:

paper.path(Raphael.format('M{0},{1}V{2}H{2}V{3}Z',50,50,100,50))
     .attr({ stroke: Raphael.getColor(), 'stroke-width': 2.5});
Run!

Fullfill:

var stuff = { x: 50, y: 50
            , w: 200, h: 300};
paper.path(Raphael.fullfill('M{x},{y}H{w},V{h}Z', stuff))
     .attr({ stroke: Raphael.getColor()
           , 'stroke-width': 2.5})
     // Es leuchtet!
     .glow({color: Raphael.getColor()});
Run!

Sets:

// Dies kann unpraktisch sein
paper.rect(200, 200, 100, 100, 10)
     .attr({fill: '#ff0000', opacity: '0.125'});
for(var i = 0; i < 200; i += 10){
  paper.circle(i, 20 + 0.5*i, 0.5*i)
       .attr({fill: '#ff0000', opacity: '0.125'});
}
Run!
// Dies hilft dabei…
paper.setStart();
paper.circle(200, 200, 100);
for(var i = 0; i < 200; i += 10)
  paper.rect(i, 20 + 0.5*i, 0.5*i, 0.75*i);
paper.setFinish().attr({fill: '#00ff00', opacity: 0.125});
Run!

Transformationen:

// Verschieben:
paper.rect(100,100,50,50).attr('fill', 'red');
paper.rect(100,100,50,50).attr('fill', 'red').transform('t50,100');
Run!
// Rotieren:
for(var i = 0; i <= 90; i+=15)
  paper.rect(100,100,50,50).transform('r'+i+',100,100')
       .attr({fill: 'red', opacity: 0.25});
Run!
// Skalieren:
for(var i = 0; i <= 4; i+=0.4)
  paper.rect(25,100,50,50).transform('s1,'+i+',125,125t'+20*i+',0')
       .attr({fill: 'red', opacity: 0.25});
Run!

Click events:

var rect = paper.rect(25,100,50,50).attr({fill: Raphael.getColor()});
rect.click(function(){
  rect.attr({fill: Raphael.getColor()});
});
Run!

Drag&Drop:

var c = paper.circle(50,50,25).attr({fill: Raphael.getColor()});
var bbox = c.getBBox(); // BBox von c
var chColor = function(){ // Kleine Hilfsfunktion
  bbox = this.getBBox();
  this.attr({fill: Raphael.getColor()});
};
c.drag(
  function(dx, dy){ // Updates beim ziehen
    c.attr({cx: bbox.x + dx, cy: bbox.y + dy});
  }
, chColor // Anfang zu ziehen
, chColor // Ziehen zuende
, c,c,c // Kontext für Funktionen
);
Run!

Fragen?

…es war mir ein inneres Blumenessen :)