mirror of
https://github.com/Hopiu/fabric.js.git
synced 2026-03-16 22:10:32 +00:00
v250
This commit is contained in:
parent
77321ca648
commit
fa50d4ae8c
3 changed files with 98 additions and 88 deletions
|
|
@ -1,5 +1,11 @@
|
|||
# Changelog
|
||||
|
||||
## [2.5.0]
|
||||
- Fix: textbox transform report newScaleX and newScaleY values [#5464](https://github.com/fabricjs/fabric.js/pull/5464)
|
||||
- Fix: export of svg and gradient with transforms [#5456](https://github.com/fabricjs/fabric.js/pull/5456)
|
||||
- Fix: detection of controls in perPixelTargetFind + cache [#5455](https://github.com/fabricjs/fabric.js/pull/5455)
|
||||
- Add: added canvas.toCanvasElement method [#5452](https://github.com/fabricjs/fabric.js/pull/5452)
|
||||
|
||||
## [2.4.6]
|
||||
- Fix: unbreak the svg export broken in 2.4.5 [#5438](https://github.com/fabricjs/fabric.js/pull/5438)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */
|
||||
|
||||
var fabric = fabric || { version: '2.4.6' };
|
||||
var fabric = fabric || { version: '2.5.0' };
|
||||
if (typeof exports !== 'undefined') {
|
||||
exports.fabric = fabric;
|
||||
}
|
||||
|
|
|
|||
178
dist/fabric.js
vendored
178
dist/fabric.js
vendored
|
|
@ -1,7 +1,7 @@
|
|||
/* build: `node build.js modules=ALL exclude=gestures,accessors requirejs minifier=uglifyjs` */
|
||||
/*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */
|
||||
|
||||
var fabric = fabric || { version: '2.4.6' };
|
||||
var fabric = fabric || { version: '2.5.0' };
|
||||
if (typeof exports !== 'undefined') {
|
||||
exports.fabric = fabric;
|
||||
}
|
||||
|
|
@ -5874,29 +5874,25 @@ fabric.ElementsParser = function(elements, callback, options, reviver, parsingOp
|
|||
var coords = clone(this.coords, true), i, len,
|
||||
markup, commonAttributes, colorStops = clone(this.colorStops, true),
|
||||
needsSwap = coords.r1 > coords.r2,
|
||||
offsetX = object.width / 2, offsetY = object.height / 2;
|
||||
transform = this.gradientTransform ? this.gradientTransform.concat() : fabric.iMatrix.concat(),
|
||||
offsetX = object.width / 2 - this.offsetX, offsetY = object.height / 2 - this.offsetY;
|
||||
// colorStops must be sorted ascending
|
||||
colorStops.sort(function(a, b) {
|
||||
return a.offset - b.offset;
|
||||
});
|
||||
|
||||
if (object.type === 'path') {
|
||||
offsetX -= object.pathOffset.x;
|
||||
offsetY -= object.pathOffset.y;
|
||||
}
|
||||
for (var prop in coords) {
|
||||
if (prop === 'x1' || prop === 'x2') {
|
||||
coords[prop] += this.offsetX - offsetX;
|
||||
}
|
||||
else if (prop === 'y1' || prop === 'y2') {
|
||||
coords[prop] += this.offsetY - offsetY;
|
||||
}
|
||||
}
|
||||
|
||||
transform[4] -= offsetX;
|
||||
transform[5] -= offsetY;
|
||||
|
||||
commonAttributes = 'id="SVGID_' + this.id +
|
||||
'" gradientUnits="userSpaceOnUse"';
|
||||
if (this.gradientTransform) {
|
||||
commonAttributes += ' gradientTransform="matrix(' + this.gradientTransform.join(' ') + ')" ';
|
||||
}
|
||||
commonAttributes += ' gradientTransform="matrix(' + transform.join(' ') + ')" ';
|
||||
|
||||
if (this.type === 'linear') {
|
||||
markup = [
|
||||
'<linearGradient ',
|
||||
|
|
@ -6631,6 +6627,7 @@ fabric.ElementsParser = function(elements, callback, options, reviver, parsingOp
|
|||
|
||||
/**
|
||||
* Indicates whether toObject/toDatalessObject should include default values
|
||||
* if set to false, takes precedence over the object value.
|
||||
* @type Boolean
|
||||
* @default
|
||||
*/
|
||||
|
|
@ -7713,7 +7710,7 @@ fabric.ElementsParser = function(elements, callback, options, reviver, parsingOp
|
|||
objects: this._toObjects(methodName, propertiesToInclude),
|
||||
};
|
||||
if (clipPath) {
|
||||
clipPath = clipPath.toObject(propertiesToInclude);
|
||||
data.clipPath = this._toObjectMethod(clipPath, methodName, propertiesToInclude);
|
||||
}
|
||||
extend(data, this.__serializeBgOverlay(methodName, propertiesToInclude));
|
||||
|
||||
|
|
@ -9714,13 +9711,15 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
|
|||
* @return {Boolean}
|
||||
*/
|
||||
isTargetTransparent: function (target, x, y) {
|
||||
if (target.shouldCache() && target._cacheCanvas) {
|
||||
// in case the target is the activeObject, we cannot execute this optimization
|
||||
// because we need to draw controls too.
|
||||
if (target.shouldCache() && target._cacheCanvas && target !== this._activeObject) {
|
||||
var normalizedPointer = this._normalizePointer(target, {x: x, y: y}),
|
||||
targetRelativeX = target.cacheTranslationX + (normalizedPointer.x * target.zoomX),
|
||||
targetRelativeY = target.cacheTranslationY + (normalizedPointer.y * target.zoomY);
|
||||
targetRelativeX = Math.max(target.cacheTranslationX + (normalizedPointer.x * target.zoomX), 0),
|
||||
targetRelativeY = Math.max(target.cacheTranslationY + (normalizedPointer.y * target.zoomY), 0);
|
||||
|
||||
var isTransparent = fabric.util.isTransparent(
|
||||
target._cacheContext, targetRelativeX, targetRelativeY, this.targetFindTolerance);
|
||||
target._cacheContext, Math.round(targetRelativeX), Math.round(targetRelativeY), this.targetFindTolerance);
|
||||
|
||||
return isTransparent;
|
||||
}
|
||||
|
|
@ -10099,12 +10098,10 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
|
|||
*/
|
||||
_setObjectScale: function(localMouse, transform, lockScalingX, lockScalingY, by, lockScalingFlip, _dim) {
|
||||
var target = transform.target, forbidScalingX = false, forbidScalingY = false, scaled = false,
|
||||
changeX, changeY, scaleX, scaleY;
|
||||
|
||||
scaleX = localMouse.x * target.scaleX / _dim.x;
|
||||
scaleY = localMouse.y * target.scaleY / _dim.y;
|
||||
changeX = target.scaleX !== scaleX;
|
||||
changeY = target.scaleY !== scaleY;
|
||||
scaleX = localMouse.x * target.scaleX / _dim.x,
|
||||
scaleY = localMouse.y * target.scaleY / _dim.y,
|
||||
changeX = target.scaleX !== scaleX,
|
||||
changeY = target.scaleY !== scaleY;
|
||||
|
||||
if (lockScalingFlip && scaleX <= 0 && scaleX < target.scaleX) {
|
||||
forbidScalingX = true;
|
||||
|
|
@ -10124,10 +10121,10 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
|
|||
forbidScalingY || lockScalingY || (target.set('scaleY', scaleY) && (scaled = scaled || changeY));
|
||||
}
|
||||
else if (by === 'x' && !target.get('lockUniScaling')) {
|
||||
forbidScalingX || lockScalingX || (target.set('scaleX', scaleX) && (scaled = scaled || changeX));
|
||||
forbidScalingX || lockScalingX || (target.set('scaleX', scaleX) && (scaled = changeX));
|
||||
}
|
||||
else if (by === 'y' && !target.get('lockUniScaling')) {
|
||||
forbidScalingY || lockScalingY || (target.set('scaleY', scaleY) && (scaled = scaled || changeY));
|
||||
forbidScalingY || lockScalingY || (target.set('scaleY', scaleY) && (scaled = changeY));
|
||||
}
|
||||
transform.newScaleX = scaleX;
|
||||
transform.newScaleY = scaleY;
|
||||
|
|
@ -10145,15 +10142,15 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
|
|||
lastDist = _dim.y * transform.original.scaleY / target.scaleY +
|
||||
_dim.x * transform.original.scaleX / target.scaleX,
|
||||
scaled, signX = localMouse.x < 0 ? -1 : 1,
|
||||
signY = localMouse.y < 0 ? -1 : 1;
|
||||
signY = localMouse.y < 0 ? -1 : 1, newScaleX, newScaleY;
|
||||
|
||||
// We use transform.scaleX/Y instead of target.scaleX/Y
|
||||
// because the object may have a min scale and we'll loose the proportions
|
||||
transform.newScaleX = signX * Math.abs(transform.original.scaleX * dist / lastDist);
|
||||
transform.newScaleY = signY * Math.abs(transform.original.scaleY * dist / lastDist);
|
||||
scaled = transform.newScaleX !== target.scaleX || transform.newScaleY !== target.scaleY;
|
||||
target.set('scaleX', transform.newScaleX);
|
||||
target.set('scaleY', transform.newScaleY);
|
||||
newScaleX = signX * Math.abs(transform.original.scaleX * dist / lastDist);
|
||||
newScaleY = signY * Math.abs(transform.original.scaleY * dist / lastDist);
|
||||
scaled = newScaleX !== target.scaleX || newScaleY !== target.scaleY;
|
||||
target.set('scaleX', newScaleX);
|
||||
target.set('scaleY', newScaleY);
|
||||
return scaled;
|
||||
},
|
||||
|
||||
|
|
@ -12119,70 +12116,69 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
|
|||
|
||||
var format = options.format || 'png',
|
||||
quality = options.quality || 1,
|
||||
multiplier = (options.multiplier || 1) * (options.enableRetinaScaling ? 1 : 1 / this.getRetinaScaling()),
|
||||
cropping = {
|
||||
left: options.left || 0,
|
||||
top: options.top || 0,
|
||||
width: options.width || 0,
|
||||
height: options.height || 0,
|
||||
};
|
||||
return this.__toDataURLWithMultiplier(format, quality, cropping, multiplier);
|
||||
multiplier = (options.multiplier || 1) * (options.enableRetinaScaling ? this.getRetinaScaling() : 1),
|
||||
canvasEl = this.toCanvasElement(multiplier, options);
|
||||
return this.__toDataURL(canvasEl, format, quality);
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
* Create a new HTMLCanvas element painted with the current canvas content.
|
||||
* No need to resize the actual one or repaint it.
|
||||
* Will transfer object ownership to a new canvas, paint it, and set everything back.
|
||||
* This is an intermediary step used to get to a dataUrl but also it is usefull to
|
||||
* create quick image copies of a canvas without passing for the dataUrl string
|
||||
* @param {Number} [multiplier] a zoom factor.
|
||||
* @param {Object} [cropping] Cropping informations
|
||||
* @param {Number} [cropping.left] Cropping left offset.
|
||||
* @param {Number} [cropping.top] Cropping top offset.
|
||||
* @param {Number} [cropping.width] Cropping width.
|
||||
* @param {Number} [cropping.height] Cropping height.
|
||||
*/
|
||||
__toDataURLWithMultiplier: function(format, quality, cropping, multiplier) {
|
||||
|
||||
var origWidth = this.width,
|
||||
origHeight = this.height,
|
||||
scaledWidth = (cropping.width || this.width) * multiplier,
|
||||
toCanvasElement: function(multiplier, cropping) {
|
||||
multiplier = multiplier || 1;
|
||||
cropping = cropping || { };
|
||||
var scaledWidth = (cropping.width || this.width) * multiplier,
|
||||
scaledHeight = (cropping.height || this.height) * multiplier,
|
||||
zoom = this.getZoom(),
|
||||
originalWidth = this.width,
|
||||
originalHeight = this.height,
|
||||
newZoom = zoom * multiplier,
|
||||
vp = this.viewportTransform,
|
||||
translateX = (vp[4] - cropping.left) * multiplier,
|
||||
translateY = (vp[5] - cropping.top) * multiplier,
|
||||
newVp = [newZoom, 0, 0, newZoom, translateX, translateY],
|
||||
translateX = (vp[4] - (cropping.left || 0)) * multiplier,
|
||||
translateY = (vp[5] - (cropping.top || 0)) * multiplier,
|
||||
originalInteractive = this.interactive,
|
||||
originalSkipOffScreen = this.skipOffscreen,
|
||||
needsResize = origWidth !== scaledWidth || origHeight !== scaledHeight;
|
||||
|
||||
this.viewportTransform = newVp;
|
||||
this.skipOffscreen = false;
|
||||
// setting interactive to false avoid exporting controls
|
||||
originalContext = this.contextContainer,
|
||||
newVp = [newZoom, 0, 0, newZoom, translateX, translateY],
|
||||
canvasEl = fabric.util.createCanvasElement();
|
||||
canvasEl.width = scaledWidth;
|
||||
canvasEl.height = scaledHeight;
|
||||
this.interactive = false;
|
||||
if (needsResize) {
|
||||
this.setDimensions({ width: scaledWidth, height: scaledHeight }, { backstoreOnly: true });
|
||||
}
|
||||
// call a renderAll to force sync update. This will cancel the scheduled requestRenderAll
|
||||
// from setDimensions
|
||||
this.viewportTransform = newVp;
|
||||
this.width = scaledWidth;
|
||||
this.height = scaledHeight;
|
||||
this.calcViewportBoundaries();
|
||||
this.contextContainer = canvasEl.getContext('2d');
|
||||
// will be renderAllExport();
|
||||
this.renderAll();
|
||||
var data = this.__toDataURL(format, quality, cropping);
|
||||
this.interactive = originalInteractive;
|
||||
this.skipOffscreen = originalSkipOffScreen;
|
||||
this.viewportTransform = vp;
|
||||
//setDimensions with no option object is taking care of:
|
||||
//this.width, this.height, this.requestRenderAll()
|
||||
if (needsResize) {
|
||||
this.setDimensions({ width: origWidth, height: origHeight }, { backstoreOnly: true });
|
||||
}
|
||||
this.renderAll();
|
||||
return data;
|
||||
this.width = originalWidth;
|
||||
this.height = originalHeight;
|
||||
this.calcViewportBoundaries();
|
||||
this.contextContainer = originalContext;
|
||||
this.interactive = originalInteractive;
|
||||
return canvasEl;
|
||||
},
|
||||
|
||||
/**
|
||||
* since 2.5.0 does not need to be on canvas instance anymore.
|
||||
* leave it here for context;
|
||||
* @private
|
||||
*/
|
||||
__toDataURL: function(format, quality) {
|
||||
|
||||
var canvasEl = this.contextContainer.canvas;
|
||||
var data = supportQuality
|
||||
__toDataURL: function(canvasEl, format, quality) {
|
||||
return supportQuality
|
||||
? canvasEl.toDataURL('image/' + format, quality)
|
||||
: canvasEl.toDataURL('image/' + format);
|
||||
|
||||
return data;
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
})();
|
||||
|
|
@ -13781,18 +13777,19 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
|
|||
return;
|
||||
}
|
||||
|
||||
var multX = (this.canvas && this.canvas.viewportTransform[0]) || 1,
|
||||
multY = (this.canvas && this.canvas.viewportTransform[3]) || 1,
|
||||
var shadow = this.shadow, canvas = this.canvas,
|
||||
multX = (canvas && canvas.viewportTransform[0]) || 1,
|
||||
multY = (canvas && canvas.viewportTransform[3]) || 1,
|
||||
scaling = this.getObjectScaling();
|
||||
if (this.canvas && this.canvas._isRetinaScaling()) {
|
||||
if (canvas && canvas._isRetinaScaling()) {
|
||||
multX *= fabric.devicePixelRatio;
|
||||
multY *= fabric.devicePixelRatio;
|
||||
}
|
||||
ctx.shadowColor = this.shadow.color;
|
||||
ctx.shadowBlur = this.shadow.blur * fabric.browserShadowBlurConstant *
|
||||
ctx.shadowColor = shadow.color;
|
||||
ctx.shadowBlur = shadow.blur * fabric.browserShadowBlurConstant *
|
||||
(multX + multY) * (scaling.scaleX + scaling.scaleY) / 4;
|
||||
ctx.shadowOffsetX = this.shadow.offsetX * multX * scaling.scaleX;
|
||||
ctx.shadowOffsetY = this.shadow.offsetY * multY * scaling.scaleY;
|
||||
ctx.shadowOffsetX = shadow.offsetX * multX * scaling.scaleX;
|
||||
ctx.shadowOffsetY = shadow.offsetY * multY * scaling.scaleY;
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -13812,6 +13809,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
|
|||
* @private
|
||||
* @param {CanvasRenderingContext2D} ctx Context to render on
|
||||
* @param {Object} filler fabric.Pattern or fabric.Gradient
|
||||
* @return {Object} offset.offsetX offset for text rendering
|
||||
* @return {Object} offset.offsetY offset for text rendering
|
||||
*/
|
||||
_applyPatternGradientTransform: function(ctx, filler) {
|
||||
if (!filler || !filler.toLive) {
|
||||
|
|
@ -14785,7 +14784,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
|
|||
/**
|
||||
* Checks if object is contained within the canvas with current viewportTransform
|
||||
* the check is done stopping at first point that appears on screen
|
||||
* @param {Boolean} [calculate] use coordinates of current position instead of .oCoords
|
||||
* @param {Boolean} [calculate] use coordinates of current position instead of .aCoords
|
||||
* @return {Boolean} true if object is fully or partially contained within canvas
|
||||
*/
|
||||
isOnScreen: function(calculate) {
|
||||
|
|
@ -29064,13 +29063,18 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
|
|||
fabric.Canvas.prototype._setObjectScale = function(localMouse, transform,
|
||||
lockScalingX, lockScalingY, by, lockScalingFlip, _dim) {
|
||||
|
||||
var t = transform.target;
|
||||
var t = transform.target, scaled,
|
||||
scaleX = localMouse.x * t.scaleX / _dim.x,
|
||||
scaleY = localMouse.y * t.scaleY / _dim.y;
|
||||
if (by === 'x' && t instanceof fabric.Textbox) {
|
||||
var tw = t._getTransformedDimensions().x;
|
||||
var w = t.width * (localMouse.x / tw);
|
||||
transform.newScaleX = scaleX;
|
||||
transform.newScaleY = scaleY;
|
||||
if (w >= t.getMinWidth()) {
|
||||
scaled = w !== t.width;
|
||||
t.set('width', w);
|
||||
return true;
|
||||
return scaled;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
|||
Loading…
Reference in a new issue