fabric.js @ falsy values
DESCRIPTION
Presentation on Fabric.js at Falsy Values, Warsaw, 2011TRANSCRIPT
![Page 1: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/1.jpg)
fabric.jsBuilding a canvas library
Warsaw ♥ 2011
![Page 2: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/2.jpg)
who is kangax?kangax.com
![Page 3: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/3.jpg)
Common Feature Tests
perfectionkills.com ES5 compat tables
HTML minifier
PrototypeJS
DOMLint
fabric.js
who is kangax?
![Page 4: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/4.jpg)
HistoryWhy fabric?How it works. Features.Canvas librariesFuture plans
Game Plan
![Page 5: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/5.jpg)
Historyprintio.ru
![Page 6: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/6.jpg)
Historyprintio.ru
All Javascript, no FlashFree drawingVectors & imagesPerformance
![Page 7: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/7.jpg)
Canvas vs SVG
![Page 8: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/8.jpg)
Why fabric?
There was an excruciating need forinteractive object model
for canvas element
Canvas API sucks is too low level
![Page 9: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/9.jpg)
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
![Page 10: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/10.jpg)
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
![Page 11: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/11.jpg)
Why fabric?
rect.set(‘left’, 20).set(‘top’, 50);canvas.renderAll();
ctx.fillRect(20, 50, 20, 20);
native
fabric
![Page 12: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/12.jpg)
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
![Page 13: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/13.jpg)
Demo
http://kangax.github.com/fabric.js/test/demo
![Page 14: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/14.jpg)
Under the hoodUpper <canvas>
Lower <canvas>
Group selection
All objects
![Page 15: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/15.jpg)
Under the hood
fabric.Triangle
fabric.Circlefabric.Rect
fabric.Element
render()render()
render()
renderAll()
![Page 16: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/16.jpg)
Under the hood
fabric.Triangle
fabric.Circlefabric.Rect
fabric.Element
render()
render()renderAll()
render()
![Page 17: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/17.jpg)
Under the hood
fabric.Element
fabric.Object fabric.Linefabric.Circlefabric.Trianglefabric.Ellipsefabric.Rectfabric.Polylinefabric.Polygonfabric.Groupfabric.Textfabric.Imagefabric.Path
Root “class”. 2D objects
Container
Concrete “subclasses”
fabric.Colorfabric.Pointfabric.Intersection
![Page 18: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/18.jpg)
Under the hood
fabric.Object
Root “class”. 2D objects
clonecloneAsImagecomplexitygetgetCentergetWidthgetElementgetHeightintersectsWithObjectisActiveisTypescalescaleToHeightscaleToWidthsetsetActivesetElementstraightentoDataURLtoJSONtoGrayscale...
Inherited by all subclasses
![Page 19: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/19.jpg)
Features — Animationfabric.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(); } }); ...}
fxCenterObjectVfxCenterObjectHfxStraightenObjectfxRemove...
![Page 20: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/20.jpg)
Features — AnimationOr 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);})();
![Page 21: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/21.jpg)
Features — Eventsfabric.util.observeEvent('object:moved', function(e) {
var activeObject = e.memo.target;
console.log(activeObject.left, activeObject.top);
});
object:scaledobject:selectedobject:moved
group:modifiedgroup:selectedbefore:group:destroyedafter:group:destroyed
mouse:up
selection:clearedpath:created
Will be made more consistent!
![Page 22: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/22.jpg)
Features — Textvar myText = new fabric.Text('Hello world', {
fontfamily: 'delicious'
});
canvas.add(myText);
fontsizefontweightfontfamilyfontStyle
textDecorationtextShadow
lineHeightbackgroundColor
strokeStylestrokeWidth
Will be made more consistent!
![Page 23: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/23.jpg)
Features — TextMultiline support
text aligning coming soon
![Page 24: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/24.jpg)
Features — TextMultiline supportRelies on Cufon.js
http://kangax.github.com/jstests/canvas_fillText_test
![Page 25: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/25.jpg)
Features — TextMultiline supportRelies on Cufon.jsRenders using any OTF, TTF, etc. font
Each font is a JS file with glyph definitions
![Page 26: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/26.jpg)
Features — SVG Parser
Q: How to render SVG shapes on canvas?
A: Transform them to fabric objects.
![Page 27: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/27.jpg)
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
![Page 28: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/28.jpg)
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
![Page 30: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/30.jpg)
Canvas libraries
canvgThe only other library with (good) SVG parserBut no object model
![Page 31: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/31.jpg)
Canvas libraries
burstLots of features but completely abandoned
![Page 32: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/32.jpg)
Canvas libraries
Unit TestsHard to come across a library that has them
![Page 33: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/33.jpg)
Canvas libraries
easel.js
Probably the most active, similar, and promising alternative.But no unit tests or SVG parser :(
![Page 34: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/34.jpg)
Fabric use cases
CollagesBasic gamesChartsBasic drawing (paintbrush, diagrams)Display SVG where unsupported (Android)
might be overkill for static charts
mouse-based interactions built in
![Page 35: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/35.jpg)
What can you build?mustachified.com
![Page 36: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/36.jpg)
Future plans
Smaller footprintBetter docs, tutorialsCustom builderfabric-to-SVGTouch compatible (iOS)
![Page 37: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/37.jpg)
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
![Page 38: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/38.jpg)
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 + compressed
JSON missing in FF 3, SF 3.2, OP 10.1, IE 7
![Page 39: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/39.jpg)
Docs, Tests
http://kangax.github.com/fabric.js/test/unit/suite_runner
http://kangax.github.com/fabric.js/docs
1000+ tests ATM
![Page 40: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/40.jpg)
Demos, Benchmarks
http://kangax.github.com/fabric.js/demos
http://kangax.github.com/fabric.js/test/raphael_vs_fabric/complex_shape
![Page 41: Fabric.js @ Falsy Values](https://reader033.vdocuments.net/reader033/viewer/2022060109/55561de1d8b42a5b528b4603/html5/thumbnails/41.jpg)
Supported browsers
Firefox 2+Safari 3+ (& Mobile Safari)Opera 9.64+Chrome (all versions should work)IE9+ (IE7 & 8 via excanvas.js)