Fabric.js — Building a Canvas Library
Upcoming SlideShare
Loading in...5
×
 

Fabric.js — Building a Canvas Library

on

  • 12,241 views

 

Statistics

Views

Total Views
12,241
Views on SlideShare
12,215
Embed Views
26

Actions

Likes
8
Downloads
130
Comments
0

9 Embeds 26

https://twitter.com 6
http://www.linkedin.com 6
https://www.linkedin.com 6
http://twitter.com 3
http://www.onlydoo.com 1
http://localhost:8090 1
http://a0.twimg.com 1
https://si0.twimg.com 1
http://www.verious.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Fabric provides state. Object oriented approach. Different paradigm.\n
  • Demo time.\n
  • \n
  • More complete IE support to come in the future\n
  • \n
  • Note the chaining.\n
  • Note the chaining.\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Exclude images, parser, text.\nMore tutorials.\nSupport gradients.\n
  • \n
  • \n

Fabric.js — Building a Canvas Library Presentation Transcript

  • 1. Fabric.jsBulding a canvas library @kangax ✎ BK.js ✎ 2011
  • 2. Who am I? @kangaxperfectionkills.com kangax.github.com/es5-compat-table/
  • 3. fabric.js Fabric.js is a framework that makes it easy to work with HTML5 canvas element. It is an interactive object model on top of canvas element.It is also an SVG-to-canvas parser.
  • 4. t ian Canvas? -co m pl WHATWG says:“The canvas element provides scripts with a resolution-dependent bitmap canvas, which can be used for rendering graphs, game graphics, or other visual images on the fly.” http://www.whatwg.org/specs/web-apps/current-work/ multipage/the-canvas-element.html#the-canvas-element
  • 5. CanvasCharts GamesEditors Physics simulation
  • 6. How canvas works document.getElementById(‘canvas’).getContext(‘2d’) CanvasRenderingContext2D• clearRect() • arc()• fillRect() • drawImage() • createImageData() • arcTo()• strokeRect() • bezierCurveTo() • putImageData() • getImageData() • clip() • closePath()• restore() • fill()• save() • strokeText() • lineTo() • fillText() • moveTo()• rotate() • measureText() • quadraticCurveTo()• scale() • rect()• transform() • stroke()• translate() • strokeStyle= • fillStyle=
  • 7. But why get rid of an elegant canvas API forsome questionable blob of Javascript code?
  • 8. fabric vs. nativenative var canvasEl = document.getElementById(canvas); var ctx = canvasEl.getContext(2d); ctx.strokeStyle = ; ctx.fillStyle = red; ctx.fillRect(100, 100, 20, 20);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);
  • 9. fabric vs. nativenative var canvasEl = document.getElementById(canvas); var ctx = canvasEl.getContext(2d); ctx.strokeStyle = ; ctx.fillStyle = red; because we all love radians ctx.save(); ctx.translate(100, 100); ctx.rotate(Math.PI / 180 * 45); ctx.fillRect(-10, -10, 20, 20); ctx.restore();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);
  • 10. fabric vs. nativenative ctx.fillRect(20, 50, 20, 20);fabricrect.set(‘left’, 20).set(‘top’, 50);canvas.renderAll();
  • 11. fabric vs. nativenative ctx.fillRect(20, 50, 20, 20); ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); ctx.fillRect(20, 50, 20, 20);fabricrect.set(‘left’, 20).set(‘top’, 50);canvas.renderAll();
  • 12. But wait, there’s more! Object manipulations with mouse http://kangax.github.com/fabric.js/test/demo/
  • 13. Goals• Unit tested (1000+ tests at the moment)• Modular (~20 small "classes")• Cross-browser (degrades gracefully)• Fast• Encapsulated in one object• No browser sniffing• ES5 strict mode -ready
  • 14. Supported browsers• Firefox 2+• Safari 3+• Opera 9.64+• Chrome (all versions should work)• IE9 (IE7/8 via excanvas)
  • 15. How fabric works “Hello world” examplevar canvas = new fabric.Element(canvas);var text = new fabric.Text(hello world, { fontfamily: delicious_500});canvas.add(text);
  • 16. How fabric works “Hello world” examplevar canvas = new fabric.Element(canvas);var text = new fabric.Text(hello world, { fontfamily: delicious_500});canvas.add(text);text.setText(trololololo) .set(left, 100) .set(top, 100) .set(fontfamily, comic_sans);
  • 17. How fabric works “Hello world” examplevar canvas = new fabric.Element(canvas);var text = new fabric.Text(hello world, { fontfamily: delicious_500});canvas.add(text);text.setText(trololololo) .set(left, 100) .set(top, 100) .set(fontfamily, comic_sans);canvas.remove(text);
  • 18. How fabric works “Class” hierarchyfabric.Object fabric.util.* fabric.Elementfabric.Linefabric.Circlefabric.Triangle fabric.parseAttributesfabric.Ellipse fabric.parseElementsfabric.Rect fabric.parseStyleAttributefabric.Polyline fabric.parsePointsAttributefabric.Polygonfabric.Groupfabric.Textfabric.Image fabric.Colorfabric.Path fabric.PathGroup fabric.Point fabric.Intersection
  • 19. How fabric works “Class” hierarchyfabric.Object clone cloneAsImage complexity getfabric.Line getCenterfabric.Circle getWidthfabric.Triangle getHeight intersectsWithObjectfabric.Ellipse isActivefabric.Rect isTypefabric.Polyline scale scaleToHeightfabric.Polygon scaleToWidthfabric.Group setfabric.Text setActive straightenfabric.Image toDataURLfabric.Path toJSON ...
  • 20. How fabric works “Class” hierarchy clonefabric.Object cloneAsImage complexity get getCenterfabric.Line getRadiusXfabric.Circle getRadiusYfabric.Triangle getWidth getHeightfabric.Ellipse intersectsWithObjectfabric.Rect isActivefabric.Polyline isType scalefabric.Polygon scaleToHeightfabric.Group scaleToWidthfabric.Text set setActivefabric.Image straightenfabric.Path toDataURL toJSON ...
  • 21. How fabric works “Class” hierarchy clonefabric.Object cloneAsImage complexity get getCenterfabric.Line getWidth getElementfabric.Circle getHeightfabric.Triangle intersectsWithObjectfabric.Ellipse isActive isTypefabric.Rect scalefabric.Polyline scaleToHeightfabric.Polygon scaleToWidth setfabric.Group setActivefabric.Text setElementfabric.Image straighten toDataURLfabric.Path toJSON toGrayscale ...
  • 22. How fabric works fabric.Element add bringForwardfabric.Element bringToFront centerObjectH centerObjectV clear clone Main drawing area complexity containsPoint deactivateAll - Wraps <canvas> element getActiveObject - Renders fabric.* objects added to it getCenter - Provides mouse-based selection getHeight getWidth - Dispatches events getObjects insertAt isEmpty item loadFromJSON loadSVGFromURL remove renderAll ...
  • 23. How fabric works fabric.Element render()fabric.Rect.prototype.render render() fabric.Path.prototype.render render() render() fabric.Image.prototype.render fabric.Circle.prototype.render
  • 24. How fabric works Drawing a frame 1. clear entire canvas 2. for each object in canvas 2a. object.render() render() render()fabric.Rect.prototype.render fabric.Path.prototype.render render() render() fabric.Image.prototype.render fabric.Circle.prototype.render
  • 25. How fabric works Prototypal inheritancefunction createClass() { var parent = null, based on properties = slice.call(arguments, 0); Prototype.js if (typeof properties[0] === function) { parent = properties.shift(); } function klass() { this.initialize.apply(this, arguments); } klass.superclass = parent; klass.subclasses = [ ]; if (parent) { subclass.prototype = parent.prototype; klass.prototype = new subclass; parent.subclasses.push(klass); } for (var i = 0, length = properties.length; i < length; i++) { addMethods(klass, properties[i]); } if (!klass.prototype.initialize) { klass.prototype.initialize = emptyFunction; } klass.prototype.constructor = klass; return klass;}
  • 26. How fabric works Prototypal inheritancefabric.Path = fabric.util.createClass( fabric.Object, { type: path, initialize: function(path, options) { options = options || { }; ... }, render: function() { ... }, toString: function() { return #<fabric.Path ( + this.complexity() + ): + JSON.stringify({ top: this.top, left: this.left }) + >; }});
  • 27. How fabric works SVG parser
  • 28. How fabric works SVG parser<path d="M-122.304 84.285C-122.304 {84.285 -122.203 86.179 -123.027 path: [86.16C-123.851 86.141 -140.305 [ "M", -122.304, 84.285 ],38.066 -160.833 40.309C-160.833 [ "C", -122.304, 84.285,40.309 -143.05 32.956 -122.304 -122.203, 86.179,84.285z" /> -123.027, 86.16 ], [ "C", -123.851, ... ], [ ... ], ... ] }
  • 29. How fabric works SVG parser { path: [ [ "M", -122.304, 84.285 ], [ "C", -122.304, 84.285, Instance of fabric.Path -122.203, 86.179,[[Prototype]] == fabric.Path.prototype -123.027, 86.16 ], [ "C", -123.851, ... ], [ ... ], ... ] }
  • 30. How fabric works SVG parser fabric.Path.prototype.render (line 173)case C: // bezierCurveTo, absolute x = current[5]; { y = current[6]; path: [ controlX = current[3]; [ "M", -122.304, 84.285 ], controlY = current[4]; [ "C", -122.304, 84.285, ctx.bezierCurveTo( -122.203, 86.179, current[1] + l, current[2] + t, -123.027, 86.16 ], controlX + l, [ "C", -123.851, ... ], controlY + t, [ ... ], x + l, ... y + t ] ); } break;
  • 31. How fabric works SVG parser Static fromElement method on all constructorsfabric.Line.fromElement = function(element, options) { var parsedAttributes = fabric.parseAttributes(element, fabric.Line.ATTRIBUTE_NAMES); var points = [ parsedAttributes.x1 || 0, parsedAttributes.y1 || 0, parsedAttributes.x2 || 0, parsedAttributes.y2 || 0 ]; return new fabric.Line(points, extend(parsedAttributes, options));};
  • 32. How fabric works SVG parser Static fromElement method on all constructorsfabric.Path.fromElement = function(element, options) { var parsedAttributes = fabric.parseAttributes(element, fabric.Path.ATTRIBUTE_NAMES); return new fabric.Path(parsedAttributes.d, extend(parsedAttributes, options));}; Ditto for fabric.Rect, fabric.Circle, etc.
  • 33. http://www.w3.org/TR/SVG/ paths.html#PathDataBNF Fun with SVG parsing
  • 34. continued...
  • 35. are we there yet?
  • 36. Fun with SVG parsing
  • 37. Docshttp://kangax.github.com/fabric.js/docs
  • 38. Unit testshttp://kangax.github.com/fabric.js/test/unit/suite_runner
  • 39. Benchmarks http://kangax.github.com/fabric.js/test/ raphael_vs_fabric/simple_shapeshttp://kangax.github.com/fabric.js/test/ raphael_vs_fabric/complex_shape
  • 40. Future plans:• Smaller footprint (delete Cufon)• Custom builder• Better docs• More complete SVG parsing• toSVG()• Pretty website, logo (help!!111)• Better IE support
  • 41. These slides online:http://slideshare.net/kangax
  • 42. Thank you! Questions? http://spkr8.com/t/7303github.com/kangax/fabric.js@FabricJS Follow me @kangax