Fabric.js @ Falsy Values

kangax 13,508 views 42 slides May 23, 2011
Slide 1
Slide 1 of 42
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21
Slide 22
22
Slide 23
23
Slide 24
24
Slide 25
25
Slide 26
26
Slide 27
27
Slide 28
28
Slide 29
29
Slide 30
30
Slide 31
31
Slide 32
32
Slide 33
33
Slide 34
34
Slide 35
35
Slide 36
36
Slide 37
37
Slide 38
38
Slide 39
39
Slide 40
40
Slide 41
41
Slide 42
42

About This Presentation

Presentation on Fabric.js at Falsy Values, Warsaw, 2011


Slide Content

fabric.js
Building a canvas library
Warsaw 2011

who is kangax?
kangax.com

Common Feature Tests
perfectionkills.com ES5 compat tables
HTML minifier
PrototypeJS
DOMLint
fabric.js
who is kangax?

History
Why fabric?
How it works. Features.
Canvas libraries
Future plans
Game Plan

History
printio.ru

History
printio.ru
All Javascript, no Flash
Free drawing
Vectors & images
Performance

Canvas vs SVG

Why fabric?
There was an excruciating need for
interactive object model
for canvas elementCanvas API sucks is too low level

Why fabric?
var canvas = new fabric.Element('canvas');
var rect = new fabric.Rect({
top: 100,
left: 100,
fill: 'red',
width: 20,
height: 20
});
canvas.add(rect);
var canvasEl = document.getElementById('canvas');
var ctx = canvasEl.getContext('2d');
ctx.strokeStyle = '';
ctx.fillStyle = 'red';
ctx.fillRect(100, 100, 20, 20); native fabric

Why fabric?
var canvas = new fabric.Element('canvas');
var rect = new fabric.Rect({
top: 100,
left: 100,
fill: 'red',
width: 20,
height: 20,
angle: 45
});
canvas.add(rect);
var canvasEl = document.getElementById('canvas');
var ctx = canvasEl.getContext('2d');
ctx.strokeStyle = '';
ctx.fillStyle = 'red';
ctx.save();
ctx.translate(100, 100);
ctx.rotate(Math.PI / 180 * 45);
ctx.fillRect(-10, -10, 20, 20);
ctx.restore();native fabric

Why fabric?
rect.set(‘left’, 20).set(‘top’, 50);
canvas.renderAll();
ctx.fillRect(20, 50, 20, 20); native fabric

Why fabric?
rect.set(‘left’, 20).set(‘top’, 50);
canvas.renderAll();
ctx.fillRect(20, 50, 20, 20);
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.fillRect(20, 50, 20, 20); native fabric

Demo
http://kangax.github.com/fabric.js/test/demo

Under the hood
Upper <canvas>
Lower <canvas>
Group selection
All objects

Under the hood
fabric.Triangle
fabric.Circle
fabric.Rect
fabric.Element
render()
render()
render()
renderAll()

Under the hood
fabric.Triangle
fabric.Circle
fabric.Rect
fabric.Elementrender() render() renderAll() render()

Under the hood
fabric.Element
fabric.Object
fabric.Line
fabric.Circle
fabric.Triangle
fabric.Ellipse
fabric.Rect
fabric.Polyline
fabric.Polygon
fabric.Group
fabric.Text
fabric.Image
fabric.PathRoot “class”. 2D objects Container Concrete “subclasses”
fabric.Color
fabric.Point
fabric.Intersection

Under the hood
fabric.ObjectRoot “class”. 2D objects
clone
cloneAsImage
complexity
get
getCenter
getWidth
getElement
getHeight
intersectsWithObject
isActive
isType
scale
scaleToHeight
scaleToWidth
set
setActive
setElement
straighten
toDataURL
toJSON
toGrayscale
...Inherited by all subclasses

Features — Animation
fabric.util.animate fxCenterObjectV: function (...) {
...
fabric.util.animate({
startValue: object.get('top'),
endValue: this.getCenter().top,
duration: this.FX_DURATION,
onChange: function(value) {
object.set('top', value);
_this.renderAll();
onChange();
},
onComplete: function() {
object.setCoords();
onComplete();
}
});

...
}
fxCenterObjectV
fxCenterObjectH
fxStraightenObject
fxRemove
...

Features — Animation
Or just use new, fancy window.requestAnimationFrame
(function animate() {
canvas.forEachObject(function(obj) {
obj.left += (obj.movingLeft ? -1 : 1);
obj.top += 1;
if (obj.left > 900 || obj.top > 500) {
canvas.remove(obj);
}
else {
obj.setAngle(obj.getAngle() + 2);
}
});
canvas.renderAll();
window.requestAnimationFrame (animate);
})();

Features — Events
fabric.util.observeEvent('object:moved', function(e) {
var activeObject = e.memo.target;
console.log(activeObject.left, activeObject.top);
});
object:scaled
object:selected
object:moved
group:modified
group:selected
before:group:destroyed
after:group:destroyed
mouse:up
selection:cleared
path:created
Will be made more consistent!

Features — Text
var myText = new fabric.Text(' Hello world', {
fontfamily: 'delicious'
});
canvas.add(myText);
fontsize
fontweight
fontfamily
fontStyle
textDecoration
textShadow
lineHeight
backgroundColor
strokeStyle
strokeWidth
Will be made more consistent!

Features — Text
Multiline supporttext aligning coming soon

Features — Text
Multiline support
Relies on Cufon.js
http://kangax.github.com/jstests/canvas_fillText_test

Features — Text
Multiline support
Relies on Cufon.js
Renders using any
OTF, TTF, etc. font Each font is a JS file with glyph definitions

Features — SVG Parser
Q: How to render SVG shapes on canvas?
A: Transform them to fabric objects.

Features — SVG Parser
<path d="M-122.304 84.285C-122.304
84.285 -122.203 86.179 -123.027
86.16C-123.851 86.141 -140.305
38.066 -160.833 40.309C-160.833
40.309 -143.05 32.956 -122.304
84.285z" />
{
path: [
[ "M", -122.304, 84.285 ],
[ "C", -122.304, 84.285,
-122.203, 86.179,
-123.027, 86.16 ],
[ "C", -123.851, ... ],
[ ... ],
...
]
}
Step 1

Features — SVG Parser
{
path: [
[ "M", -122.304, 84.285 ],
[ "C", -122.304, 84.285,
-122.203, 86.179,
-123.027, 86.16 ],
[ "C", -123.851, ... ],
[ ... ],
...
]
}
case 'C': // bezierCurveTo, absolute
x = current[5];
y = current[6];
controlX = current[3];
controlY = current[4];
ctx.bezierCurveTo(
current[1] + l,
current[2] + t,
controlX + l,
controlY + t,
x + l,
y + t
);
break;
Step 2

Canvas libraries
http://goo.gl/CCRRT

Canvas libraries
canvg
The only other library with (good) SVG parser
But no object model

Canvas libraries
burst
Lots of features but completely abandoned

Canvas libraries
Unit Tests
Hard to come across a library that has them

Canvas libraries
easel.js
Probably the most active, similar, and
promising alternative.
But no unit tests or SVG parser :(

Fabric use cases
Collages
Basic games
Charts
Basic drawing (paintbrush, diagrams)
Display SVG where unsupported (Android)might be overkill for static charts mouse-based interactions built in

What can you build?
mustachified.com

Future plans
Smaller footprint
Better docs, tutorials
Custom builder
fabric-to-SVG
Touch compatible (iOS)

Smaller footprint
102 KB — minified
33 KB — minified + compressed
Fabric 0.2.5 jQuery 1.6.1
91 KB — minified
32 KB — minified + compressed
Can do even better – optional json2.js, cufon.js + custom builder

Smaller footprint
102 KB — minified
33 KB — minified + compressed
with Cufon without cufon.js
86 KB — minified
29 KB — minified + compressed
without json2.js
82 KB — minified
25 KB — minified + compressedJSON missing in FF 3, SF 3.2, OP 10.1, IE 7

Docs, Tests
http://kangax.github.com/fabric.js/test/unit/suite_runner
http://kangax.github.com/fabric.js/docs
1000+ tests ATM

Demos, Benchmarks
http://kangax.github.com/fabric.js/demos
http://kangax.github.com/fabric.js/test/
raphael_vs_fabric/complex_shape

Supported browsers
Firefox 2+
Safari 3+ (& Mobile Safari)
Opera 9.64+
Chrome (all versions should work)
IE9+ (IE7 & 8 via excanvas.js)

Thank you!
Questions?
github.com/kangax/fabric.js
@fabric.js
http://spkr8.com/t/7582
@kangax