diff --git a/HEADER.js b/HEADER.js index bb612de3..9959d1b0 100644 --- a/HEADER.js +++ b/HEADER.js @@ -1,6 +1,6 @@ /*! Fabric.js Copyright 2008-2012, Printio (Juriy Zaytsev, Maxim Chernyak) */ -var fabric = fabric || { version: "0.9.15" }; +var fabric = fabric || { version: "0.9.16" }; if (typeof exports != 'undefined') { exports.fabric = fabric; diff --git a/dist/all.js b/dist/all.js index b63ba5da..3156b405 100644 --- a/dist/all.js +++ b/dist/all.js @@ -1,7 +1,7 @@ /* build: `node build.js modules=ALL` */ /*! Fabric.js Copyright 2008-2012, Printio (Juriy Zaytsev, Maxim Chernyak) */ -var fabric = fabric || { version: "0.9.15" }; +var fabric = fabric || { version: "0.9.16" }; if (typeof exports != 'undefined') { exports.fabric = fabric; @@ -1784,7 +1784,12 @@ fabric.Observable = { this.__eventListeners = { }; } if (this.__eventListeners[eventName]) { - fabric.util.removeFromArray(this.__eventListeners[eventName], handler); + if (handler) { + fabric.util.removeFromArray(this.__eventListeners[eventName], handler); + } + else { + this.__eventListeners[eventName].length = 0; + } } }, @@ -4955,6 +4960,28 @@ fabric.util.string = { */ backgroundImageStretch: true, + /** + * Overlay image of canvas instance + * Should be set via `setOverlayImage` + * @property + * @type String + */ + overlayImage: '', + + /** + * Left offset of overlay image (if present) + * @property + * @type Number + */ + overlayImageLeft: 0, + + /** + * Top offset of overlay image (if present) + * @property + * @type Number + */ + overlayImageTop: 0, + /** * Indicates whether toObject/toDatalessObject should include default values * @property @@ -5000,13 +5027,6 @@ fabric.util.string = { /* NOOP */ }, - /** - * Callback; invoked on every redraw of canvas and is being passed a number indicating current fps - * @method onFpsUpdate - * @param {Number} fps - */ - onFpsUpdate: null, - _initStatic: function(el, options) { this._objects = []; @@ -5374,8 +5394,7 @@ fabric.util.string = { this.clearContext(canvasToDrawOn); } - var activeGroup = this.getActiveGroup(), - startTime = new Date(); + var activeGroup = this.getActiveGroup(); if (this.clipTo) { this._clipCanvas(canvasToDrawOn); @@ -5388,6 +5407,8 @@ fabric.util.string = { this._drawBackroundImage(canvasToDrawOn); } + this.fire('before:render'); + for (var i = 0, length = this._objects.length; i < length; ++i) { if (!activeGroup || (activeGroup && this._objects[i] && !activeGroup.contains(this._objects[i]))) { @@ -5405,18 +5426,13 @@ fabric.util.string = { } if (this.overlayImage) { - this.contextContainer.drawImage(this.overlayImage, 0, 0); + this.contextContainer.drawImage(this.overlayImage, this.overlayImageLeft, this.overlayImageTop); } if (this.controlsAboveOverlay) { this.drawControls(this.contextContainer); } - if (this.onFpsUpdate) { - var elapsedTime = new Date() - startTime; - this.onFpsUpdate(~~(1000 / elapsedTime)); - } - this.fire('after:render'); return this; @@ -5453,7 +5469,7 @@ fabric.util.string = { this.clearContext(this.contextTop || this.contextContainer); if (this.overlayImage) { - this.contextContainer.drawImage(this.overlayImage, 0, 0); + this.contextContainer.drawImage(this.overlayImage, this.overlayImageLeft, this.overlayImageTop); } // we render the top context - last object @@ -6156,10 +6172,24 @@ fabric.util.string = { */ containerClass: 'canvas-container', + /** + * When true, object detection happens on per-pixel basis rather than on per-bounding-box + * @property + * @type Boolean + */ perPixelTargetFind: false, + /** + * Number of pixels around target pixel to tolerate (consider active) during object detection + * @property + * @type Number + */ targetFindTolerance: 0, + /** + * @method _initInteractive + * @private + */ _initInteractive: function() { this._currentTransform = null; this._groupSelector = null; @@ -9612,7 +9642,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { _render: function(ctx, noTransform) { ctx.beginPath(); // multiply by currently set alpha (the one that was set by path group where this object is contained, for example) - ctx.globalAlpha *= this.opacity; + ctx.globalAlpha = this.group ? (ctx.globalAlpha * this.opacity) : this.opacity; ctx.arc(noTransform ? this.left : 0, noTransform ? this.top : 0, this.radius, 0, piBy2, false); ctx.closePath(); if (this.fill) { @@ -9908,7 +9938,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { _render: function(ctx, noTransform) { ctx.beginPath(); ctx.save(); - ctx.globalAlpha *= this.opacity; + ctx.globalAlpha = this.group ? (ctx.globalAlpha * this.opacity) : this.opacity; if (this.transformMatrix && this.group) { ctx.translate(this.cx, this.cy); } @@ -10071,7 +10101,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { h = this.height; ctx.beginPath(); - ctx.globalAlpha *= this.opacity; + ctx.globalAlpha = this.group ? (ctx.globalAlpha * this.opacity) : this.opacity; if (this.transformMatrix && this.group) { ctx.translate( diff --git a/dist/all.min.js b/dist/all.min.js index d66c4e32..56d014dc 100644 --- a/dist/all.min.js +++ b/dist/all.min.js @@ -1,5 +1,5 @@ -/* build: `node build.js modules=ALL` *//*! Fabric.js Copyright 2008-2012, Printio (Juriy Zaytsev, Maxim Chernyak) */var fabric=fabric||{version:"0.9.15"};typeof exports!="undefined"&&(exports.fabric=fabric),typeof document!="undefined"&&typeof window!="undefined"?(fabric.document=document,fabric.window=window):(fabric.document=require("jsdom").jsdom("
"),fabric.window=fabric.document.createWindow()),fabric.isTouchSupported="ontouchstart"in fabric.document.documentElement,fabric.isLikelyNode=typeof Buffer!="undefined"&&typeof window=="undefined";var Cufon=function(){function r(e){var t=this.face=e.face;this.glyphs=e.glyphs,this.w=e.w,this.baseSize=parseInt(t["units-per-em"],10),this.family=t["font-family"].toLowerCase(),this.weight=t["font-weight"],this.style=t["font-style"]||"normal",this.viewBox=function(){var e=t.bbox.split(/\s+/),n={minX:parseInt(e[0],10),minY:parseInt(e[1],10),maxX:parseInt(e[2],10),maxY:parseInt(e[3],10)};return n.width=n.maxX-n.minX,n.height=n.maxY-n.minY,n.toString=function(){return[this.minX,this.minY,this.width,this.height].join(" ")},n}(),this.ascent=-parseInt(t.ascent,10),this.descent=-parseInt(t.descent,10),this.height=-this.ascent+this.descent}function i(){var e={},t={oblique:"italic",italic:"oblique"};this.add=function(t){(e[t.style]||(e[t.style]={}))[t.weight]=t},this.get=function(n,r){var i=e[n]||e[t[n]]||e.normal||e.italic||e.oblique;if(!i)return null;r={normal:400,bold:700}[r]||parseInt(r,10);if(i[r])return i[r];var s={1:1,99:0}[r%100],o=[],u,a;s===undefined&&(s=r>400),r==500&&(r=400);for(var f in i){f=parseInt(f,10);if(!u||fa)a=f;o.push(f)}return ra&&(r=a),o.sort(function(e,t){return(s?e>r&&t>r?er?n:i-t;s(u(l,f,c,n));if(i>r||o()){e.onComplete&&e.onComplete();return}a(h)}()}function f(e,t,n){if(e){var r=new Image;r.onload=function(){t&&t.call(n,r),r=r.onload=null},r.src=e}else t&&t.call(n,e)}function l(e,t){function n(e){return fabric[fabric.util.string.camelize(fabric.util.string.capitalize(e))]}function r(){++s===o&&t&&t(i)}var i=[],s=0,o=e.length;e.forEach(function(e,t){if(!e.type)return;var s=n(e.type);s.async?s.fromObject(e,function(e){i[t]=e,r()}):(i[t]=s.fromObject(e),r())})}function c(e,t,n){var r=e.length>1?new fabric.PathGroup(e,t):e[0];return typeof n!="undefined"&&r.setSourcePath(n),r}fabric.util={};var n=Math.PI/180,u=fabric.window.requestAnimationFrame||fabric.window.webkitRequestAnimationFrame||fabric.window.mozRequestAnimationFrame||fabric.window.oRequestAnimationFrame||fabric.window.msRequestAnimationFrame||function(e){fabric.window.setTimeout(e,1e3/60)},a=function(){return u.apply(fabric.window,arguments)};fabric.util.removeFromArray=e,fabric.util.degreesToRadians=r,fabric.util.toFixed=i,fabric.util.getRandomInt=t,fabric.util.falseFunction=s,fabric.util.animate=o,fabric.util.requestAnimFrame=a,fabric.util.loadImage=f,fabric.util.enlivenObjects=l,fabric.util.groupSVGElements=c}(),function(){function t(t,n){var r=e.call(arguments,2),i=[];for(var s=0,o=t.length;s 0&&this.init(e,t)}var t=e.fabric||(e.fabric={});if(t.Point){t.warn("fabric.Point is already defined");return}t.Point=n,n.prototype={constructor:n,init:function(e,t){this.x=e,this.y=t},add:function(e){return new n(this.x+e.x,this.y+e.y)},addEquals:function(e){return this.x+=e.x,this.y+=e.y,this},scalarAdd:function(e){return new n(this.x+e,this.y+e)},scalarAddEquals:function(e){return this.x+=e,this.y+=e,this},subtract:function(e){return new n(this.x-e.x,this.y-e.y)},subtractEquals:function(e){return this.x-=e.x,this.y-=e.y,this},scalarSubtract:function(e){return new n(this.x-e,this.y-e)},scalarSubtractEquals:function(e){return this.x-=e,this.y-=e,this},multiply:function(e){return new n(this.x*e,this.y*e)},multiplyEquals:function(e){return this.x*=e,this.y*=e,this},divide:function(e){return new n(this.x/e,this.y/e)},divideEquals:function(e){return this.x/=e,this.y/=e,this},eq:function(e){return this.x===e.x&&this.y===e.y},lt:function(e){return this.x>>0,n=0,r;if(arguments.length>1)r=arguments[1];else do{if(n in this){r=this[n++];break}if(++n>=t)throw new TypeError}while(!0);for(;n0&&(i.status="Intersection"),i},t.Intersection.intersectPolygonPolygon=function(e,t){var r=new n("No Intersection"),i=e.length;for(var s=0;s0&&(r.status="Intersection"),r},t.Intersection.intersectPolygonRectangle=function(e,r,i){var s=r.min(i),o=r.max(i),u=new t.Point(o.x,s.y),a=new t.Point(s.x,o.y),f=n.intersectLinePolygon(s,u,e),l=n.intersectLinePolygon(u,o,e),c=n.intersectLinePolygon(o,a,e),h=n.intersectLinePolygon(a,s,e),p=new n("No Intersection");return p.appendPoints(f.points),p.appendPoints(l.points),p.appendPoints(c.points),p.appendPoints(h.points),p.points.length>0&&(p.status="Intersection"),p}}(typeof exports!="undefined"?exports:this),function(e){"use strict";function n(e){e?this._tryParsingColor(e):this.setSource([0,0,0,1])}var t=e.fabric||(e.fabric={});if(t.Color){t.warn("fabric.Color is already defined.");return}t.Color=n,t.Color.prototype={_tryParsingColor:function(e){var t=n.sourceFromHex(e);t||(t=n.sourceFromRgb(e)),t&&this.setSource(t)},getSource:function(){return this._source},setSource:function(e){this._source=e},toRgb:function(){var e=this.getSource();return"rgb("+e[0]+","+e[1]+","+e[2]+")"},toRgba:function(){var e=this.getSource();return"rgba("+e[0]+","+e[1]+","+e[2]+","+e[3]+")"},toHex:function(){var e=this.getSource(),t=e[0].toString(16);t=t.length===1?"0"+t:t;var n=e[1].toString(16);n=n.length===1?"0"+n:n;var r=e[2].toString(16);return r=r.length===1?"0"+r:r,t.toUpperCase()+n.toUpperCase()+r.toUpperCase()},getAlpha:function(){return this.getSource()[3]},setAlpha:function(e){var t=this.getSource();return t[3]=e,this.setSource(t),this},toGrayscale:function(){var e=this.getSource(),t=parseInt((e[0]*.3+e[1]*.59+e[2]*.11).toFixed(0),10),n=e[3];return this.setSource([t,t,t,n]),this},toBlackWhite:function(e){var t=this.getSource(),n=(t[0]*.3+t[1]*.59+t[2]*.11).toFixed(0),r=t[3];return e=e||127,n=Number(n)