Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

fabric

Package Overview
Dependencies
Maintainers
2
Versions
309
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fabric - npm Package Compare versions

Comparing version 6.0.0-beta3 to 6.0.0-beta4

dist/src/parser/typedefs.d.ts

2

dist/src/env/index.d.ts

@@ -14,3 +14,3 @@ /**

export declare const getDocument: () => Document;
export declare const getWindow: () => Window | DOMWindow;
export declare const getWindow: () => (Window & typeof globalThis) | DOMWindow;
//# sourceMappingURL=index.d.ts.map

@@ -9,3 +9,3 @@ import { GLProbe } from '../filters/GLProbes/GLProbe';

document: Document;
window: Window | DOMWindow;
window: (Window & typeof globalThis) | DOMWindow;
isTouchSupported: boolean;

@@ -12,0 +12,0 @@ WebGLProbe: GLProbe;

@@ -9,3 +9,3 @@ export declare const cssRules: {};

};
export declare const reNum = "(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:[eE][-+]?\\d+)?)";
export declare const reNum: string;
export declare const svgNS = "http://www.w3.org/2000/svg";

@@ -12,0 +12,0 @@ export declare const commaWsp: string;

@@ -0,12 +1,18 @@

import { LoadImageOptions } from '../util/misc/objectEnlive';
import type { TSvgParsedCallback, TSvgReviverCallback } from './typedefs';
/**
* Takes string corresponding to an SVG document, and parses it into a set of fabric objects
* @memberOf fabric
* @param {String} string
* @param {Function} callback
* @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.
* @param {String} string representing the svg
* @param {TSvgParsedCallback} callback Invoked when the parsing is done, with null if parsing wasn't possible with the list of svg nodes.
* {@link TSvgParsedCallback} also receives `allElements` array as the last argument. This is the full list of svg nodes available in the document.
* You may want to use it if you are trying to regroup the objects as they were originally grouped in the SVG. ( This was the reason why it was added )
* @param {TSvgReviverCallback} [reviver] Extra callback for further parsing of SVG elements, called after each fabric object has been created.
* Takes as input the original svg element and the generated `FabricObject` as arguments. Used to inspect extra properties not parsed by fabric,
* or extra custom manipulation
* @param {Object} [options] Object containing options for parsing
* @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources
* @param {String} [options.crossOrigin] crossOrigin setting to use for external resources
* @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal
*/
export declare function loadSVGFromString(string: any, callback: any, reviver: any, options: any): void;
export declare function loadSVGFromString(string: string, callback: TSvgParsedCallback, reviver?: TSvgReviverCallback, options?: LoadImageOptions): void;
//# sourceMappingURL=loadSVGFromString.d.ts.map

@@ -0,1 +1,3 @@

import type { TSvgParsedCallback, TSvgReviverCallback } from './typedefs';
import type { LoadImageOptions } from '../util/misc/objectEnlive';
/**

@@ -5,10 +7,14 @@ * Takes url corresponding to an SVG document, and parses it into a set of fabric objects.

* @memberOf fabric
* @param {String} url
* @param {Function} callback
* @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.
* @param {string} url where the SVG is
* @param {TSvgParsedCallback} callback Invoked when the parsing is done, with null if parsing wasn't possible with the list of svg nodes.
* {@link TSvgParsedCallback} also receives `allElements` array as the last argument. This is the full list of svg nodes available in the document.
* You may want to use it if you are trying to regroup the objects as they were originally grouped in the SVG. ( This was the reason why it was added )
* @param {TSvgReviverCallback} [reviver] Extra callback for further parsing of SVG elements, called after each fabric object has been created.
* Takes as input the original svg element and the generated `FabricObject` as arguments. Used to inspect extra properties not parsed by fabric,
* or extra custom manipulation
* @param {Object} [options] Object containing options for parsing
* @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources
* @param {String} [options.crossOrigin] crossOrigin setting to use for external resources
* @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal
*/
export declare function loadSVGFromURL(url: any, callback: any, reviver: any, options: any): void;
export declare function loadSVGFromURL(url: string, callback: TSvgParsedCallback, reviver?: TSvgReviverCallback, options?: LoadImageOptions): void;
//# sourceMappingURL=loadSVGFromURL.d.ts.map

@@ -0,1 +1,3 @@

import type { TSvgParsedCallback, TSvgReviverCallback } from './typedefs';
import type { LoadImageOptions } from '../util/misc/objectEnlive';
/**

@@ -6,11 +8,14 @@ * Parses an SVG document, converts it to an array of corresponding fabric.* instances and passes them to a callback

* @memberOf fabric
* @param {SVGDocument} doc SVG document to parse
* @param {Function} callback Callback to call when parsing is finished;
* It's being passed an array of elements (parsed from a document).
* @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.
* @param {Object} [parsingOptions] options for parsing document
* @param {String} [parsingOptions.crossOrigin] crossOrigin settings
* @param {AbortSignal} [parsingOptions.signal] see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal
* @param {HTMLElement} doc SVG document to parse
* @param {TSvgParsedCallback} callback Invoked when the parsing is done, with null if parsing wasn't possible with the list of svg nodes.
* {@link TSvgParsedCallback} also receives `allElements` array as the last argument. This is the full list of svg nodes available in the document.
* You may want to use it if you are trying to regroup the objects as they were originally grouped in the SVG. ( This was the reason why it was added )
* @param {TSvgReviverCallback} [reviver] Extra callback for further parsing of SVG elements, called after each fabric object has been created.
* Takes as input the original svg element and the generated `FabricObject` as arguments. Used to inspect extra properties not parsed by fabric,
* or extra custom manipulation
* @param {Object} [options] Object containing options for parsing
* @param {String} [options.crossOrigin] crossOrigin setting to use for external resources
* @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal
*/
export declare function parseSVGDocument(doc: any, callback: any, reviver: any, parsingOptions: any): void;
export declare function parseSVGDocument(doc: HTMLElement, callback: TSvgParsedCallback, reviver?: TSvgReviverCallback, { crossOrigin, signal }?: LoadImageOptions): void;
//# sourceMappingURL=parseSVGDocument.d.ts.map

@@ -0,1 +1,2 @@

import { TMat2D } from '../typedefs';
/**

@@ -7,5 +8,5 @@ * Parses "transform" attribute, returning an array of values

* @param {String} attributeValue String containing attribute value
* @return {Array} Array of 6 elements representing transformation matrix
* @return {TTransformMatrix} Array of 6 elements representing transformation matrix
*/
export declare function parseTransformAttribute(attributeValue: any): any;
export declare function parseTransformAttribute(attributeValue: string): TMat2D;
//# sourceMappingURL=parseTransformAttribute.d.ts.map

@@ -1,2 +0,17 @@

export declare function rotateMatrix(matrix: any, args: any): void;
import { TDegree, TMat2D } from '../typedefs';
/**
* A rotation matrix
* In the form of
* [cos(a) -sin(a) -xcos(a)+ysin(a)+x]
* [sin(a) cos(a) -xsin(a)-ycos(a)+y]
* [0 0 1 ]
*/
/**
* Generate a rotation matrix around the center or around a point x,y
* @param {TDegree} angle rotation in degrees
* @param {number} [x] translation on X axis for the pivot point
* @param {number} [y] translation on Y axis for the pivot point
* @returns {TMat2D} matrix
*/
export declare function rotateMatrix(angle: TDegree, x?: number, y?: number): TMat2D;
//# sourceMappingURL=rotateMatrix.d.ts.map

@@ -1,2 +0,18 @@

export declare function scaleMatrix(matrix: any, args: any): void;
import { TMat2D } from '../typedefs';
/**
* A scale matrix
* Takes form
* [x 0 0]
* [0 y 0]
* [0 0 1]
* For more info, see
* @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#scale
*/
/**
* Generate a scale matrix around the point 0,0
* @param {number} x scale on X axis
* @param {number} [y] scale on Y axis
* @returns {TMat2D} matrix
*/
export declare const scaleMatrix: (x: number, y?: number) => TMat2D;
//# sourceMappingURL=scaleMatrix.d.ts.map

@@ -1,2 +0,14 @@

export declare function skewMatrix(matrix: any, args: any, pos: any): void;
import { TDegree, TMat2D } from '../typedefs';
/**
* Generate a skew matrix for the X axis
* @param {TDegree} skewValue translation on X axis
* @returns {TMat2D} matrix
*/
export declare const skewXMatrix: (skewValue: TDegree) => TMat2D;
/**
* Generate a skew matrix for the Y axis
* @param {TDegree} skewValue translation on Y axis
* @returns {TMat2D} matrix
*/
export declare const skewYMatrix: (skewValue: TDegree) => TMat2D;
//# sourceMappingURL=skewMatrix.d.ts.map

@@ -1,2 +0,16 @@

export declare function translateMatrix(matrix: any, args: any): void;
import { TMat2D } from '../typedefs';
/**
* A translation matrix in the form of
* [ 1 0 x ]
* [ 0 1 y ]
* [ 0 0 1 ]
* See @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#translate for more details
*/
/**
* Generate a translation matrix
* @param {number} x translation on X axis
* @param {number} [y] translation on Y axis
* @returns {TMat2D} matrix
*/
export declare const translateMatrix: (x: number, y?: number) => TMat2D;
//# sourceMappingURL=translateMatrix.d.ts.map
import { Point } from '../Point';
import { FabricObject } from './Object/FabricObject';
import { TPathSegmentInfo, TSimplePathData } from '../util/path/typedefs';
import { TComplexPathData, TPathSegmentInfo, TSimplePathData } from '../util/path/typedefs';
import type { FabricObjectProps, SerializedObjectProps, TProps } from './Object/types';
import type { ObjectEvents } from '../EventTypeDefs';
import { TClassProperties, TSVGReviver } from '../typedefs';
import { TBBox, TClassProperties, TSVGReviver } from '../typedefs';
interface UniquePathProps {

@@ -15,2 +15,7 @@ sourcePath?: string;

}
export interface IPathBBox extends TBBox {
left: number;
top: number;
pathOffset: Point;
}
export declare class Path<Props extends TProps<PathProps> = Partial<PathProps>, SProps extends SerializedPathProps = SerializedPathProps, EventSpec extends ObjectEvents = ObjectEvents> extends FabricObject<Props, SProps, EventSpec> {

@@ -30,16 +35,23 @@ /**

* Constructor
* @param {TSimplePathData} path Path data (sequence of coordinates and corresponding "command" tokens)
* @param {Object} [options] Options object
* @param {TComplexPathData} path Path data (sequence of coordinates and corresponding "command" tokens)
* @param {Partial<PathProps>} [options] Options object
* @return {Path} thisArg
*/
constructor(path: TSimplePathData | string, { path, left, top, ...options }?: Props);
constructor(path: TComplexPathData | string, { path, left, top, ...options }?: Partial<Props>);
/**
* @private
* @param {TSimplePathData | string} path Path data (sequence of coordinates and corresponding "command" tokens)
* @param {TComplexPathData | string} path Path data (sequence of coordinates and corresponding "command" tokens)
* @param {boolean} [adjustPosition] pass true to reposition the object according to the bounding box
* @returns {Point} top left position of the bounding box, useful for complementary positioning
*/
_setPath(path: TSimplePathData | string, adjustPosition?: boolean): Point;
_setPath(path: TComplexPathData | string, adjustPosition?: boolean): void;
/**
* This function is an helper for svg import. it returns the center of the object in the svg
* untransformed coordinates, by look at the polyline/polygon points.
* @private
* @return {Point} center point from element coordinates
*/
_findCenterFromElement(): Point;
/**
* @private
* @param {CanvasRenderingContext2D} ctx context to render path on

@@ -76,2 +88,6 @@ */

_toSVG(): string[];
/**
* @private
* @return the path command's translate transform attribute
*/
_getOffsetTransform(): string;

@@ -95,13 +111,9 @@ /**

complexity(): number;
setDimensions(): Point;
setDimensions(): void;
setBoundingBox(adjustPosition?: boolean): void;
_calcBoundsFromPath(): TBBox;
/**
* @private
*/
_calcDimensions(): {
left: number;
top: number;
pathOffset: Point;
width: number;
height: number;
};
_calcDimensions(): IPathBBox;
/**

@@ -127,9 +139,8 @@ * List of attribute names to account for when parsing SVG element (used by `Path.fromElement`)

* @param {SVGElement} element to parse
* @param {Function} callback Callback to invoke when an Path instance is created
* @param {Object} [options] Options object
* @param {Function} [callback] Options callback invoked after parsing is finished
* @param {(path: Path) => void} callback Callback to invoke after the element has been parsed
* @param {Partial<PathProps>} [options] Options object
*/
static fromElement(element: SVGElement, callback: (path: Path) => void, options: any): void;
static fromElement(element: SVGElement, callback: (path: Path) => void, options: Partial<PathProps>): void;
}
export {};
//# sourceMappingURL=Path.d.ts.map

@@ -75,2 +75,9 @@ import { XY, Point } from '../Point';

};
/**
* This function is an helper for svg import. it returns the center of the object in the svg
* untransformed coordinates, by look at the polyline/polygon points.
* @private
* @return {Point} center point from element coordinates
*/
_findCenterFromElement(): Point;
setDimensions(): void;

@@ -77,0 +84,0 @@ setBoundingBox(adjustPosition?: boolean): void;

@@ -50,4 +50,19 @@ import { BaseFabricObject } from './EventTypeDefs';

}
export type TMat2D = [number, number, number, number, number, number];
/**
* A transform matrix.
* Basically a matrix in the form
* [ a c e ]
* [ b d f ]
* [ 0 0 1 ]
* For more details, see @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#matrix
*/
export type TMat2D = [
a: number,
b: number,
c: number,
d: number,
e: number,
f: number
];
/**
* An invalid keyword and an empty string will be handled as the `anonymous` keyword.

@@ -54,0 +69,0 @@ * @see https://developer.mozilla.org/en-US/docs/HTML/CORS_settings_attributes

@@ -13,3 +13,3 @@ /**

*/
export declare function request(url: any, options?: {}): any;
export declare function request(url: any, options?: {}): XMLHttpRequest;
//# sourceMappingURL=dom_request.d.ts.map

@@ -1,3 +0,2 @@

export declare const numberRegExStr: string;
export declare const rePathCommand: string;
//# sourceMappingURL=regex.d.ts.map

@@ -5,3 +5,3 @@ {

"homepage": "http://fabricjs.com/",
"version": "6.0.0-beta3",
"version": "6.0.0-beta4",
"author": "Juriy Zaytsev <kangax@gmail.com>",

@@ -8,0 +8,0 @@ "contributors": [

@@ -24,2 +24,3 @@ /**

export const getWindow = (): Window | DOMWindow => getEnv().window;
export const getWindow = (): (Window & typeof globalThis) | DOMWindow =>
getEnv().window;

@@ -10,3 +10,3 @@ import { GLProbe } from '../filters/GLProbes/GLProbe';

document: Document;
window: Window | DOMWindow;
window: (Window & typeof globalThis) | DOMWindow;
isTouchSupported: boolean;

@@ -13,0 +13,0 @@ WebGLProbe: GLProbe;

@@ -380,2 +380,3 @@ //@ts-nocheck

const gradientUnits = parseGradientUnits(el);
const center = instance._findCenterFromElement();
return new this({

@@ -395,4 +396,4 @@ id: el.getAttribute('id') || undefined,

? {
offsetX: -instance.left,
offsetY: -instance.top,
offsetX: instance.width / 2 - center.x,
offsetY: instance.height / 2 - center.y,
}

@@ -399,0 +400,0 @@ : {

@@ -14,3 +14,3 @@ //@ts-nocheck

export const reNum = '(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:[eE][-+]?\\d+)?)';
export const reNum = String.raw`(?:[-+]?(?:\d*\.\d+|\d+\.?)(?:[eE][-+]?\d+)?)`;

@@ -17,0 +17,0 @@ export const svgNS = 'http://www.w3.org/2000/svg';

@@ -1,4 +0,5 @@

//@ts-nocheck
import { getWindow } from '../env';
import { LoadImageOptions } from '../util/misc/objectEnlive';
import { parseSVGDocument } from './parseSVGDocument';
import type { TSvgParsedCallback, TSvgReviverCallback } from './typedefs';

@@ -8,20 +9,23 @@ /**

* @memberOf fabric
* @param {String} string
* @param {Function} callback
* @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.
* @param {String} string representing the svg
* @param {TSvgParsedCallback} callback Invoked when the parsing is done, with null if parsing wasn't possible with the list of svg nodes.
* {@link TSvgParsedCallback} also receives `allElements` array as the last argument. This is the full list of svg nodes available in the document.
* You may want to use it if you are trying to regroup the objects as they were originally grouped in the SVG. ( This was the reason why it was added )
* @param {TSvgReviverCallback} [reviver] Extra callback for further parsing of SVG elements, called after each fabric object has been created.
* Takes as input the original svg element and the generated `FabricObject` as arguments. Used to inspect extra properties not parsed by fabric,
* or extra custom manipulation
* @param {Object} [options] Object containing options for parsing
* @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources
* @param {String} [options.crossOrigin] crossOrigin setting to use for external resources
* @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal
*/
export function loadSVGFromString(string, callback, reviver, options) {
export function loadSVGFromString(
string: string,
callback: TSvgParsedCallback,
reviver?: TSvgReviverCallback,
options?: LoadImageOptions
) {
const parser = new (getWindow().DOMParser)(),
// should we use `image/svg+xml` here?
doc = parser.parseFromString(string.trim(), 'text/xml');
parseSVGDocument(
doc.documentElement,
function (results, _options, elements, allElements) {
callback(results, _options, elements, allElements);
},
reviver,
options
);
parseSVGDocument(doc.documentElement, callback, reviver, options);
}

@@ -1,5 +0,5 @@

//@ts-nocheck
import { request } from '../util/dom_request';
import { parseSVGDocument } from './parseSVGDocument';
import type { TSvgParsedCallback, TSvgReviverCallback } from './typedefs';
import type { LoadImageOptions } from '../util/misc/objectEnlive';

@@ -10,32 +10,34 @@ /**

* @memberOf fabric
* @param {String} url
* @param {Function} callback
* @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.
* @param {string} url where the SVG is
* @param {TSvgParsedCallback} callback Invoked when the parsing is done, with null if parsing wasn't possible with the list of svg nodes.
* {@link TSvgParsedCallback} also receives `allElements` array as the last argument. This is the full list of svg nodes available in the document.
* You may want to use it if you are trying to regroup the objects as they were originally grouped in the SVG. ( This was the reason why it was added )
* @param {TSvgReviverCallback} [reviver] Extra callback for further parsing of SVG elements, called after each fabric object has been created.
* Takes as input the original svg element and the generated `FabricObject` as arguments. Used to inspect extra properties not parsed by fabric,
* or extra custom manipulation
* @param {Object} [options] Object containing options for parsing
* @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources
* @param {String} [options.crossOrigin] crossOrigin setting to use for external resources
* @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal
*/
export function loadSVGFromURL(url, callback, reviver, options) {
new request(url.replace(/^\n\s*/, '').trim(), {
method: 'get',
onComplete: onComplete,
signal: options && options.signal,
});
function onComplete(r) {
export function loadSVGFromURL(
url: string,
callback: TSvgParsedCallback,
reviver?: TSvgReviverCallback,
options: LoadImageOptions = {}
) {
const onComplete = (r: XMLHttpRequest) => {
const xml = r.responseXML;
if (!xml || !xml.documentElement) {
callback && callback(null);
callback(null, {}, [], []);
return false;
}
parseSVGDocument(
xml.documentElement,
function (results, _options, elements, allElements) {
callback && callback(results, _options, elements, allElements);
},
reviver,
options
);
}
parseSVGDocument(xml.documentElement, callback, reviver, options);
};
request(url.replace(/^\n\s*/, '').trim(), {
method: 'get',
onComplete,
signal: options.signal,
});
}
//@ts-nocheck
import { uid } from '../util/internals/uid';

@@ -17,3 +16,4 @@ import { applyViewboxTransform } from './applyViewboxTransform';

import { parseUseDirectives } from './parseUseDirectives';
import type { TSvgParsedCallback, TSvgReviverCallback } from './typedefs';
import type { LoadImageOptions } from '../util/misc/objectEnlive';
/**

@@ -24,19 +24,23 @@ * Parses an SVG document, converts it to an array of corresponding fabric.* instances and passes them to a callback

* @memberOf fabric
* @param {SVGDocument} doc SVG document to parse
* @param {Function} callback Callback to call when parsing is finished;
* It's being passed an array of elements (parsed from a document).
* @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.
* @param {Object} [parsingOptions] options for parsing document
* @param {String} [parsingOptions.crossOrigin] crossOrigin settings
* @param {AbortSignal} [parsingOptions.signal] see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal
* @param {HTMLElement} doc SVG document to parse
* @param {TSvgParsedCallback} callback Invoked when the parsing is done, with null if parsing wasn't possible with the list of svg nodes.
* {@link TSvgParsedCallback} also receives `allElements` array as the last argument. This is the full list of svg nodes available in the document.
* You may want to use it if you are trying to regroup the objects as they were originally grouped in the SVG. ( This was the reason why it was added )
* @param {TSvgReviverCallback} [reviver] Extra callback for further parsing of SVG elements, called after each fabric object has been created.
* Takes as input the original svg element and the generated `FabricObject` as arguments. Used to inspect extra properties not parsed by fabric,
* or extra custom manipulation
* @param {Object} [options] Object containing options for parsing
* @param {String} [options.crossOrigin] crossOrigin setting to use for external resources
* @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal
*/
export function parseSVGDocument(doc, callback, reviver, parsingOptions) {
export function parseSVGDocument(
doc: HTMLElement,
callback: TSvgParsedCallback,
reviver?: TSvgReviverCallback,
{ crossOrigin, signal }: LoadImageOptions = {}
) {
if (!doc) {
return;
}
if (
parsingOptions &&
parsingOptions.signal &&
parsingOptions.signal.aborted
) {
if (signal && signal.aborted) {
throw new Error('`options.signal` is in `aborted` state');

@@ -47,7 +51,9 @@ }

const svgUid = uid(),
options = applyViewboxTransform(doc),
descendants = Array.from(doc.getElementsByTagName('*'));
options.crossOrigin = parsingOptions && parsingOptions.crossOrigin;
options.svgUid = svgUid;
options.signal = parsingOptions && parsingOptions.signal;
descendants = Array.from(doc.getElementsByTagName('*')),
options = {
...applyViewboxTransform(doc),
crossOrigin,
svgUid,
signal,
};

@@ -62,3 +68,3 @@ const elements = descendants.filter(function (el) {

if (!elements || (elements && !elements.length)) {
callback && callback([], {});
callback([], {}, [], descendants);
return;

@@ -68,11 +74,7 @@ }

descendants
.filter(function (el) {
return el.nodeName.replace('svg:', '') === 'clipPath';
})
.forEach(function (el) {
.filter((el) => el.nodeName.replace('svg:', '') === 'clipPath')
.forEach((el) => {
const id = el.getAttribute('id');
localClipPaths[id] = Array.from(el.getElementsByTagName('*')).filter(
function (el) {
return svgValidTagNamesRegEx.test(el.nodeName.replace('svg:', ''));
}
(el) => svgValidTagNamesRegEx.test(el.nodeName.replace('svg:', ''))
);

@@ -86,3 +88,3 @@ });

elements,
function (instances, elements) {
(instances, elements) => {
if (callback) {

@@ -95,6 +97,6 @@ callback(instances, options, elements, descendants);

},
Object.assign({}, options),
{ ...options },
reviver,
parsingOptions
{ crossOrigin, signal }
);
}

@@ -1,90 +0,26 @@

//@ts-nocheck
import { iMatrix } from '../constants';
import { commaWsp, reNum } from './constants';
import { reNum } from './constants';
import { multiplyTransformMatrices } from '../util/misc/matrix';
import { degreesToRadians } from '../util/misc/radiansDegreesConversion';
import { rotateMatrix } from './rotateMatrix';
import { scaleMatrix } from './scaleMatrix';
import { skewMatrix } from './skewMatrix';
import { translateMatrix } from './translateMatrix';
import { TMat2D } from '../typedefs';
import { cleanupSvgAttribute } from '../util/internals/cleanupSvAttribute';
import { skewXMatrix, skewYMatrix } from './skewMatrix';
// == begin transform regexp
const number = reNum,
skewX = '(?:(skewX)\\s*\\(\\s*(' + number + ')\\s*\\))',
skewY = '(?:(skewY)\\s*\\(\\s*(' + number + ')\\s*\\))',
rotate =
'(?:(rotate)\\s*\\(\\s*(' +
number +
')(?:' +
commaWsp +
'(' +
number +
')' +
commaWsp +
'(' +
number +
'))?\\s*\\))',
scale =
'(?:(scale)\\s*\\(\\s*(' +
number +
')(?:' +
commaWsp +
'(' +
number +
'))?\\s*\\))',
translate =
'(?:(translate)\\s*\\(\\s*(' +
number +
')(?:' +
commaWsp +
'(' +
number +
'))?\\s*\\))',
matrix =
'(?:(matrix)\\s*\\(\\s*' +
'(' +
number +
')' +
commaWsp +
'(' +
number +
')' +
commaWsp +
'(' +
number +
')' +
commaWsp +
'(' +
number +
')' +
commaWsp +
'(' +
number +
')' +
commaWsp +
'(' +
number +
')' +
'\\s*\\))',
transform =
'(?:' +
matrix +
'|' +
translate +
'|' +
scale +
'|' +
rotate +
'|' +
skewX +
'|' +
skewY +
')',
transforms =
'(?:' + transform + '(?:' + commaWsp + '*' + transform + ')*' + ')',
transformList = '^\\s*(?:' + transforms + '?)\\s*$',
// http://www.w3.org/TR/SVG/coords.html#TransformAttribute
reTransformList = new RegExp(transformList),
// == end transform regexp
reTransform = new RegExp(transform, 'g');
const p = `(${reNum})`;
const skewX = String.raw`(skewX)\(${p}\)`;
const skewY = String.raw`(skewY)\(${p}\)`;
const rotate = String.raw`(rotate)\(${p}(?: ${p} ${p})?\)`;
const scale = String.raw`(scale)\(${p}(?: ${p})?\)`;
const translate = String.raw`(translate)\(${p}(?: ${p})?\)`;
const matrix = String.raw`(matrix)\(${p} ${p} ${p} ${p} ${p} ${p}\)`;
const transform = `(?:${matrix}|${translate}|${rotate}|${scale}|${skewX}|${skewY})`;
const transforms = `(?:${transform}*)`;
const transformList = String.raw`^\s*(?:${transforms}?)\s*$`;
// http://www.w3.org/TR/SVG/coords.html#TransformAttribute
const reTransformList = new RegExp(transformList);
// == end transform regexp
const reTransform = new RegExp(transform, 'g');

@@ -97,8 +33,12 @@ /**

* @param {String} attributeValue String containing attribute value
* @return {Array} Array of 6 elements representing transformation matrix
* @return {TTransformMatrix} Array of 6 elements representing transformation matrix
*/
export function parseTransformAttribute(attributeValue) {
export function parseTransformAttribute(attributeValue: string): TMat2D {
// first we clean the string
attributeValue = cleanupSvgAttribute(attributeValue)
// remove spaces around front parentheses
.replace(/\s*([()])\s*/gi, '$1');
// start with identity matrix
let matrix = iMatrix.concat();
const matrices = [];
const matrices: TMat2D[] = [];

@@ -111,32 +51,35 @@ // return if no argument was given or

) {
return matrix;
return [...iMatrix];
}
attributeValue.replace(reTransform, function (match) {
const m = new RegExp(transform).exec(match).filter(function (match) {
// match !== '' && match != null
return !!match;
}),
operation = m[1],
args = m.slice(2).map(parseFloat);
for (const match of attributeValue.matchAll(reTransform)) {
const transformMatch = new RegExp(transform).exec(match[0]);
if (!transformMatch) {
continue;
}
let matrix: TMat2D = iMatrix;
const matchedParams = transformMatch.filter((m) => !!m);
const [, operation, ...rawArgs] = matchedParams;
const [arg0, arg1, arg2, arg3, arg4, arg5] = rawArgs.map((arg) =>
parseFloat(arg)
);
switch (operation) {
case 'translate':
translateMatrix(matrix, args);
matrix = translateMatrix(arg0, arg1);
break;
case 'rotate':
args[0] = degreesToRadians(args[0]);
rotateMatrix(matrix, args);
matrix = rotateMatrix(arg0, arg1, arg2);
break;
case 'scale':
scaleMatrix(matrix, args);
matrix = scaleMatrix(arg0, arg1);
break;
case 'skewX':
skewMatrix(matrix, args, 2);
matrix = skewXMatrix(arg0);
break;
case 'skewY':
skewMatrix(matrix, args, 1);
matrix = skewYMatrix(arg0);
break;
case 'matrix':
matrix = args;
matrix = [arg0, arg1, arg2, arg3, arg4, arg5];
break;

@@ -146,13 +89,9 @@ }

// snapshot current matrix into matrices array
matrices.push(matrix.concat());
// reset
matrix = iMatrix.concat();
});
matrices.push(matrix);
}
let combinedMatrix = matrices[0];
while (matrices.length > 1) {
matrices.shift();
combinedMatrix = multiplyTransformMatrices(combinedMatrix, matrices[0]);
}
return combinedMatrix;
return matrices.reduce(
(acc, matrix) => multiplyTransformMatrices(acc, matrix),
iMatrix
);
}

@@ -1,21 +0,33 @@

//@ts-nocheck
import { cos } from '../util/misc/cos';
import { sin } from '../util/misc/sin';
import { TDegree, TMat2D } from '../typedefs';
import { degreesToRadians } from '../util/misc/radiansDegreesConversion';
export function rotateMatrix(matrix, args) {
const cosValue = cos(args[0]),
sinValue = sin(args[0]);
let x = 0,
y = 0;
if (args.length === 3) {
x = args[1];
y = args[2];
}
/**
* A rotation matrix
* In the form of
* [cos(a) -sin(a) -xcos(a)+ysin(a)+x]
* [sin(a) cos(a) -xsin(a)-ycos(a)+y]
* [0 0 1 ]
*/
matrix[0] = cosValue;
matrix[1] = sinValue;
matrix[2] = -sinValue;
matrix[3] = cosValue;
matrix[4] = x - (cosValue * x - sinValue * y);
matrix[5] = y - (sinValue * x + cosValue * y);
/**
* Generate a rotation matrix around the center or around a point x,y
* @param {TDegree} angle rotation in degrees
* @param {number} [x] translation on X axis for the pivot point
* @param {number} [y] translation on Y axis for the pivot point
* @returns {TMat2D} matrix
*/
export function rotateMatrix(angle: TDegree, x = 0, y = 0): TMat2D {
const angleRadiant = degreesToRadians(angle),
cosValue = cos(angleRadiant),
sinValue = sin(angleRadiant);
return [
cosValue,
sinValue,
-sinValue,
cosValue,
x - (cosValue * x - sinValue * y),
y - (sinValue * x + cosValue * y),
];
}

@@ -1,9 +0,26 @@

//@ts-nocheck
import { TMat2D } from '../typedefs';
export function scaleMatrix(matrix, args) {
const multiplierX = args[0],
multiplierY = args.length === 2 ? args[1] : args[0];
/**
* A scale matrix
* Takes form
* [x 0 0]
* [0 y 0]
* [0 0 1]
* For more info, see
* @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#scale
*/
matrix[0] = multiplierX;
matrix[3] = multiplierY;
}
/**
* Generate a scale matrix around the point 0,0
* @param {number} x scale on X axis
* @param {number} [y] scale on Y axis
* @returns {TMat2D} matrix
*/
export const scaleMatrix = (x: number, y: number = x): TMat2D => [
x,
0,
0,
y,
0,
0,
];

@@ -1,6 +0,47 @@

//@ts-nocheck
import { degreesToRadians } from '../util/misc/radiansDegreesConversion';
import { TDegree, TMat2D } from '../typedefs';
export function skewMatrix(matrix, args, pos) {
matrix[pos] = Math.tan(degreesToRadians(args[0]));
}
/**
* A matrix in the form
* [1 x 0]
* [0 1 0]
* [0 0 1]
*
* or
*
* [1 0 0]
* [y 1 0]
* [0 0 1]
*
* For more info, see
* @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#skewx
*/
const fromAngleToSkew = (angle: TDegree) => Math.tan(degreesToRadians(angle));
/**
* Generate a skew matrix for the X axis
* @param {TDegree} skewValue translation on X axis
* @returns {TMat2D} matrix
*/
export const skewXMatrix = (skewValue: TDegree): TMat2D => [
1,
0,
fromAngleToSkew(skewValue),
1,
0,
0,
];
/**
* Generate a skew matrix for the Y axis
* @param {TDegree} skewValue translation on Y axis
* @returns {TMat2D} matrix
*/
export const skewYMatrix = (skewValue: TDegree): TMat2D => [
1,
fromAngleToSkew(skewValue),
0,
1,
0,
0,
];

@@ -1,8 +0,17 @@

//@ts-nocheck
import { TMat2D } from '../typedefs';
export function translateMatrix(matrix, args) {
matrix[4] = args[0];
if (args.length === 2) {
matrix[5] = args[1];
}
}
/**
* A translation matrix in the form of
* [ 1 0 x ]
* [ 0 1 y ]
* [ 0 0 1 ]
* See @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#translate for more details
*/
/**
* Generate a translation matrix
* @param {number} x translation on X axis
* @param {number} [y] translation on Y axis
* @returns {TMat2D} matrix
*/
export const translateMatrix = (x: number, y = 0): TMat2D => [1, 0, 0, 1, x, y];

@@ -1241,4 +1241,6 @@ import { cache } from '../../cache';

height = dims.y / this.scaleY / retinaScaling;
pCanvas.width = width;
pCanvas.height = height;
// in case width and height are less than 1px, we have to round up.
// since the pattern is no-repeat, this is fine
pCanvas.width = Math.ceil(width);
pCanvas.height = Math.ceil(height);
const pCtx = pCanvas.getContext('2d');

@@ -1245,0 +1247,0 @@ if (!pCtx) {

@@ -29,2 +29,3 @@ import type {

import { ControlProps } from './types/ControlProps';
import { translateMatrix } from '../../parser/translateMatrix';

@@ -666,5 +667,5 @@ type TLineDescriptor = {

const rotateMatrix = calcRotateMatrix({ angle: this.angle }),
center = this.getRelativeCenterPoint(),
translateMatrix = [1, 0, 0, 1, center.x, center.y] as TMat2D,
finalMatrix = multiplyTransformMatrices(translateMatrix, rotateMatrix),
{ x, y } = this.getRelativeCenterPoint(),
tMatrix = translateMatrix(x, y),
finalMatrix = multiplyTransformMatrices(tMatrix, rotateMatrix),
dim = this._getTransformedDimensions(),

@@ -671,0 +672,0 @@ w = dim.x / 2,

@@ -15,3 +15,7 @@ import { config } from '../config';

import { FabricObject, cacheProperties } from './Object/FabricObject';
import { TPathSegmentInfo, TSimplePathData } from '../util/path/typedefs';
import {
TComplexPathData,
TPathSegmentInfo,
TSimplePathData,
} from '../util/path/typedefs';
import type {

@@ -23,3 +27,3 @@ FabricObjectProps,

import type { ObjectEvents } from '../EventTypeDefs';
import { TClassProperties, TSVGReviver } from '../typedefs';
import { TBBox, TClassProperties, TSVGReviver } from '../typedefs';
import { cloneDeep } from '../util/internals/cloneDeep';

@@ -38,2 +42,8 @@

export interface IPathBBox extends TBBox {
left: number;
top: number;
pathOffset: Point;
}
export class Path<

@@ -63,20 +73,14 @@ Props extends TProps<PathProps> = Partial<PathProps>,

* Constructor
* @param {TSimplePathData} path Path data (sequence of coordinates and corresponding "command" tokens)
* @param {Object} [options] Options object
* @param {TComplexPathData} path Path data (sequence of coordinates and corresponding "command" tokens)
* @param {Partial<PathProps>} [options] Options object
* @return {Path} thisArg
*/
constructor(
path: TSimplePathData | string,
{ path: _, left, top, ...options }: Props = {} as Props
path: TComplexPathData | string,
{ path: _, left, top, ...options }: Partial<Props> = {}
) {
super(options as Props);
const pathTL = this._setPath(path || []);
const origin = this.translateToGivenOrigin(
new Point(left ?? pathTL.x, top ?? pathTL.y),
typeof left === 'number' ? this.originX : 'left',
typeof top === 'number' ? this.originY : 'top',
this.originX,
this.originY
);
this.setPositionByOrigin(origin, this.originX, this.originY);
this._setPath(path || [], true);
typeof left === 'number' && this.set('left', left);
typeof top === 'number' && this.set('top', top);
}

@@ -86,18 +90,28 @@

* @private
* @param {TSimplePathData | string} path Path data (sequence of coordinates and corresponding "command" tokens)
* @param {TComplexPathData | string} path Path data (sequence of coordinates and corresponding "command" tokens)
* @param {boolean} [adjustPosition] pass true to reposition the object according to the bounding box
* @returns {Point} top left position of the bounding box, useful for complementary positioning
*/
_setPath(path: TSimplePathData | string, adjustPosition?: boolean) {
_setPath(path: TComplexPathData | string, adjustPosition?: boolean) {
this.path = makePathSimpler(Array.isArray(path) ? path : parsePath(path));
return this.setDimensions();
this.setBoundingBox(adjustPosition);
}
/**
* This function is an helper for svg import. it returns the center of the object in the svg
* untransformed coordinates, by look at the polyline/polygon points.
* @private
* @return {Point} center point from element coordinates
*/
_findCenterFromElement(): Point {
const bbox = this._calcBoundsFromPath();
return new Point(bbox.left + bbox.width / 2, bbox.top + bbox.height / 2);
}
/**
* @private
* @param {CanvasRenderingContext2D} ctx context to render path on
*/
_renderPathCommands(ctx: CanvasRenderingContext2D) {
let current, // current instruction
subpathStartX = 0,
let subpathStartX = 0,
subpathStartY = 0,

@@ -113,11 +127,9 @@ x = 0, // current x

for (let i = 0, len = this.path.length; i < len; ++i) {
current = this.path[i];
for (const command of this.path) {
switch (
current[0] // first letter
command[0] // first letter
) {
case 'L': // lineto, absolute
x = current[1];
y = current[2];
x = command[1];
y = command[2];
ctx.lineTo(x + l, y + t);

@@ -127,4 +139,4 @@ break;

case 'M': // moveTo, absolute
x = current[1];
y = current[2];
x = command[1];
y = command[2];
subpathStartX = x;

@@ -136,9 +148,9 @@ subpathStartY = y;

case 'C': // bezierCurveTo, absolute
x = current[5];
y = current[6];
controlX = current[3];
controlY = current[4];
x = command[5];
y = command[6];
controlX = command[3];
controlY = command[4];
ctx.bezierCurveTo(
current[1] + l,
current[2] + t,
command[1] + l,
command[2] + t,
controlX + l,

@@ -153,11 +165,11 @@ controlY + t,

ctx.quadraticCurveTo(
current[1] + l,
current[2] + t,
current[3] + l,
current[4] + t
command[1] + l,
command[2] + t,
command[3] + l,
command[4] + t
);
x = current[3];
y = current[4];
controlX = current[1];
controlY = current[2];
x = command[3];
y = command[4];
controlX = command[1];
controlY = command[2];
break;

@@ -239,2 +251,6 @@

/**
* @private
* @return the path command's translate transform attribute
*/
_getOffsetTransform() {

@@ -286,11 +302,13 @@ const digits = config.NUM_FRACTION_DIGITS;

setDimensions() {
this.setBoundingBox();
}
setBoundingBox(adjustPosition?: boolean) {
const { left, top, width, height, pathOffset } = this._calcDimensions();
this.set({ width, height, pathOffset });
return new Point(left, top);
adjustPosition &&
this.setPositionByOrigin(new Point(left, top), 'left', 'top');
}
/**
* @private
*/
_calcDimensions() {
_calcBoundsFromPath(): TBBox {
const bounds: XY[] = [];

@@ -302,10 +320,10 @@ let subpathStartX = 0,

for (let i = 0; i < this.path.length; ++i) {
const current = this.path[i]; // current instruction
for (const command of this.path) {
// current instruction
switch (
current[0] // first letter
command[0] // first letter
) {
case 'L': // lineto, absolute
x = current[1];
y = current[2];
x = command[1];
y = command[2];
bounds.push(new Point(subpathStartX, subpathStartY), new Point(x, y));

@@ -315,4 +333,4 @@ break;

case 'M': // moveTo, absolute
x = current[1];
y = current[2];
x = command[1];
y = command[2];
subpathStartX = x;

@@ -327,12 +345,12 @@ subpathStartY = y;

y,
current[1],
current[2],
current[3],
current[4],
current[5],
current[6]
command[1],
command[2],
command[3],
command[4],
command[5],
command[6]
)
);
x = current[5];
y = current[6];
x = command[5];
y = command[6];
break;

@@ -345,12 +363,12 @@

y,
current[1],
current[2],
current[1],
current[2],
current[3],
current[4]
command[1],
command[2],
command[1],
command[2],
command[3],
command[4]
)
);
x = current[3];
y = current[4];
x = command[3];
y = command[4];
break;

@@ -364,4 +382,10 @@

}
return makeBoundingBoxFromPoints(bounds);
}
const bbox = makeBoundingBoxFromPoints(bounds);
/**
* @private
*/
_calcDimensions(): IPathBBox {
const bbox = this._calcBoundsFromPath();
const strokeCorrection = this.fromSVG ? 0 : this.strokeWidth / 2;

@@ -406,5 +430,4 @@

* @param {SVGElement} element to parse
* @param {Function} callback Callback to invoke when an Path instance is created
* @param {Object} [options] Options object
* @param {Function} [callback] Options callback invoked after parsing is finished
* @param {(path: Path) => void} callback Callback to invoke after the element has been parsed
* @param {Partial<PathProps>} [options] Options object
*/

@@ -414,3 +437,3 @@ static fromElement(

callback: (path: Path) => void,
options: any
options: Partial<PathProps>
) {

@@ -417,0 +440,0 @@ const parsedAttributes = parseAttributes(element, this.ATTRIBUTE_NAMES);

@@ -163,2 +163,13 @@ import { config } from '../config';

/**
* This function is an helper for svg import. it returns the center of the object in the svg
* untransformed coordinates, by look at the polyline/polygon points.
* @private
* @return {Point} center point from element coordinates
*/
_findCenterFromElement(): Point {
const bbox = makeBoundingBoxFromPoints(this.points);
return new Point(bbox.left + bbox.width / 2, bbox.top + bbox.height / 2);
}
setDimensions() {

@@ -165,0 +176,0 @@ this.setBoundingBox();

@@ -67,3 +67,18 @@ // https://www.typescriptlang.org/docs/handbook/utility-types.html

export type TMat2D = [number, number, number, number, number, number];
/**
* A transform matrix.
* Basically a matrix in the form
* [ a c e ]
* [ b d f ]
* [ 0 0 1 ]
* For more details, see @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#matrix
*/
export type TMat2D = [
a: number,
b: number,
c: number,
d: number,
e: number,
f: number
];

@@ -70,0 +85,0 @@ /**

import { iMatrix } from '../../constants';
import { scaleMatrix } from '../../parser/scaleMatrix';
import { skewXMatrix, skewYMatrix } from '../../parser/skewMatrix';
import { XY, Point } from '../../Point';

@@ -148,28 +150,13 @@ import { TDegree, TMat2D } from '../../typedefs';

}: TScaleMatrixArgs) => {
let scaleMatrix = iMatrix;
if (scaleX !== 1 || scaleY !== 1 || flipX || flipY) {
scaleMatrix = [
flipX ? -scaleX : scaleX,
0,
0,
flipY ? -scaleY : scaleY,
0,
0,
] as TMat2D;
}
let scaleMat = scaleMatrix(
flipX ? -scaleX : scaleX,
flipY ? -scaleY : scaleY
);
if (skewX) {
scaleMatrix = multiplyTransformMatrices(
scaleMatrix,
[1, 0, Math.tan(degreesToRadians(skewX)), 1] as unknown as TMat2D,
true
);
scaleMat = multiplyTransformMatrices(scaleMat, skewXMatrix(skewX), true);
}
if (skewY) {
scaleMatrix = multiplyTransformMatrices(
scaleMatrix,
[1, Math.tan(degreesToRadians(skewY)), 0, 1] as unknown as TMat2D,
true
);
scaleMat = multiplyTransformMatrices(scaleMat, skewYMatrix(skewY), true);
}
return scaleMatrix;
return scaleMat;
};

@@ -176,0 +163,0 @@

@@ -25,3 +25,4 @@ import { cache } from '../../cache';

import { XY, Point } from '../../Point';
import { numberRegExStr, rePathCommand } from './regex';
import { rePathCommand } from './regex';
import { cleanupSvgAttribute } from '../internals/cleanupSvAttribute';

@@ -98,2 +99,5 @@ /**

): TParsedAbsoluteCubicCurveCommand[] => {
if (rx === 0 || ry === 0) {
return [];
}
let fromX = 0,

@@ -844,7 +848,3 @@ fromY = 0,

// add spaces around the numbers
pathString = pathString
.replace(new RegExp(`(${numberRegExStr})`, 'gi'), ' $1 ')
// replace annoying commas and arbitrary whitespace with single spaces
.replace(/,/gi, ' ')
.replace(/\s+/gi, ' ');
pathString = cleanupSvgAttribute(pathString);

@@ -851,0 +851,0 @@ const res: TComplexPathData = [];

@@ -1,4 +0,2 @@

// absolute value number
const absNumberRegExStr = String.raw`(?:\d*\.\d+|\d+\.?)(?:[eE][-+]?\d+)?`;
export const numberRegExStr = `[-+]?${absNumberRegExStr}`;
import { reNum } from '../../parser/constants';

@@ -9,3 +7,3 @@ /**

*/
const p = `(${numberRegExStr})`;
const p = `(${reNum})`;

@@ -12,0 +10,0 @@ const reMoveToCommand = `(M) (?:${p} ${p} ?)+`;

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc