From 03d94c37f617e2919cd1696dfbf3b1fd472a683d Mon Sep 17 00:00:00 2001 From: ShaMan123 Date: Mon, 5 Sep 2022 12:23:21 +0300 Subject: [PATCH 01/15] Update .npmignore --- .npmignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.npmignore b/.npmignore index c2fae2f6103..901ecd925b8 100644 --- a/.npmignore +++ b/.npmignore @@ -1,5 +1,6 @@ .github/ .nyc_output/ +cli_output/ lib/*.jar lib/*.png coverage/ From 3bf941b452c3a28f58b949ea7a91332e7a648124 Mon Sep 17 00:00:00 2001 From: ShaMan123 Date: Mon, 5 Sep 2022 19:22:34 +0300 Subject: [PATCH 02/15] Update transform_files.js --- scripts/transform_files.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/transform_files.js b/scripts/transform_files.js index eb62528df65..b82e793b27d 100644 --- a/scripts/transform_files.js +++ b/scripts/transform_files.js @@ -121,7 +121,7 @@ function findClassBase(raw, regex) { const rawObject = findObject(raw, '{', '}', result.index); const NS = namespace.slice(0, namespace.lastIndexOf('.')); const { fabric } = require(wd); - const klass = fabric.util.resolveNamespace(NS === 'fabric' ? null : NS)[name]; + // const klass = fabric.util.resolveNamespace(NS === 'fabric' ? null : NS)[name]; return { name, namespace, @@ -133,7 +133,7 @@ function findClassBase(raw, regex) { value: match }, ...rawObject, - klass + // klass }; } From e70569407a66ee80074058ca6804c8fffc6e3e05 Mon Sep 17 00:00:00 2001 From: ShaMan123 Date: Mon, 5 Sep 2022 19:22:46 +0300 Subject: [PATCH 03/15] migrate --- src/pattern.class.ts | 321 ++++++++++++++++++++----------------------- src/typedefs.ts | 8 +- 2 files changed, 154 insertions(+), 175 deletions(-) diff --git a/src/pattern.class.ts b/src/pattern.class.ts index 621b6df817b..5a74927f9b3 100644 --- a/src/pattern.class.ts +++ b/src/pattern.class.ts @@ -1,181 +1,153 @@ -//@ts-nocheck +import { fabric } from "../HEADER"; +import { config } from "./config"; +import { TCrossOrigin, TMat2D } from "./typedefs"; +import { loadImage } from "./util/misc/objectEnlive"; +import { pick } from "./util/misc/pick"; +import { toFixed } from "./util/misc/toFixed"; +export type TPatternRepeat = 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat'; -import { pick } from "./util/misc/pick"; -import { config } from "./config"; +/** + * Pattern class + * @class fabric.Pattern + * @see {@link http://fabricjs.com/patterns|Pattern demo} + * @see {@link http://fabricjs.com/dynamic-patterns demo} + */ +export class Pattern { + + /** + * @type TPatternRepeat + * @defaults + */ + repeat: TPatternRepeat = 'repeat' + + /** + * Pattern horizontal offset from object's left/top corner + * @type Number + * @default + */ + offsetX = 0 + /** + * Pattern vertical offset from object's left/top corner + * @type Number + * @default + */ + offsetY = 0 -(function(global) { - var fabric = global.fabric, toFixed = fabric.util.toFixed; + /** + * @type TCrossOrigin + * @default + */ + crossOrigin: TCrossOrigin = '' /** - * Pattern class - * @class fabric.Pattern - * @see {@link http://fabricjs.com/patterns|Pattern demo} - * @see {@link http://fabricjs.com/dynamic-patterns|DynamicPattern demo} - * @see {@link fabric.Pattern#initialize} for constructor definition + * transform matrix to change the pattern, imported from svgs. + * @type Array + * @default */ + patternTransform: TMat2D | null = null + type = 'pattern' - fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ { - - /** - * Repeat property of a pattern (one of repeat, repeat-x, repeat-y or no-repeat) - * @type String - * @default - */ - repeat: 'repeat', - - /** - * Pattern horizontal offset from object's left/top corner - * @type Number - * @default - */ - offsetX: 0, - - /** - * Pattern vertical offset from object's left/top corner - * @type Number - * @default - */ - offsetY: 0, - - /** - * crossOrigin value (one of "", "anonymous", "use-credentials") - * @see https://developer.mozilla.org/en-US/docs/HTML/CORS_settings_attributes - * @type String - * @default - */ - crossOrigin: '', - - /** - * transform matrix to change the pattern, imported from svgs. - * @type Array - * @default - */ - patternTransform: null, - - type: 'pattern', - - /** - * Constructor - * @param {Object} [options] Options object - * @param {option.source} [source] the pattern source, eventually empty or a drawable - * @return {fabric.Pattern} thisArg - */ - initialize: function(options) { - options || (options = { }); - this.id = fabric.Object.__uid++; - this.setOptions(options); - }, - - /** - * Returns object representation of a pattern - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} Object representation of a pattern instance - */ - toObject: function(propertiesToInclude) { - var NUM_FRACTION_DIGITS = config.NUM_FRACTION_DIGITS, - source, object; + source!: CanvasImageSource; + + readonly id: number; + + /** + * Constructor + * @param {Object} [options] Options object + * @param {option.source} [source] the pattern source, eventually empty or a drawable + * @return {fabric.Pattern} thisArg + */ + constructor(options = {}) { + this.id = fabric.Object.__uid++; + this.setOptions(options); + } + sourceToString() { + return typeof this.source.src === 'string' ? // element - if (typeof this.source.src === 'string') { - source = this.source.src; - } - // element - else if (typeof this.source === 'object' && this.source.toDataURL) { - source = this.source.toDataURL(); - } - - return { - ...pick(this, propertiesToInclude), - type: 'pattern', - source: source, - repeat: this.repeat, - crossOrigin: this.crossOrigin, - offsetX: toFixed(this.offsetX, NUM_FRACTION_DIGITS), - offsetY: toFixed(this.offsetY, NUM_FRACTION_DIGITS), - patternTransform: this.patternTransform ? this.patternTransform.concat() : null - }; - }, - - /* _TO_SVG_START_ */ - /** - * Returns SVG representation of a pattern - * @param {fabric.Object} object - * @return {String} SVG representation of a pattern - */ - toSVG: function(object) { - var patternSource = typeof this.source === 'function' ? this.source() : this.source, - patternWidth = patternSource.width / object.width, - patternHeight = patternSource.height / object.height, - patternOffsetX = this.offsetX / object.width, - patternOffsetY = this.offsetY / object.height, - patternImgSrc = ''; - if (this.repeat === 'repeat-x' || this.repeat === 'no-repeat') { - patternHeight = 1; - if (patternOffsetY) { - patternHeight += Math.abs(patternOffsetY); - } - } - if (this.repeat === 'repeat-y' || this.repeat === 'no-repeat') { - patternWidth = 1; - if (patternOffsetX) { - patternWidth += Math.abs(patternOffsetX); - } - - } - if (patternSource.src) { - patternImgSrc = patternSource.src; - } - else if (patternSource.toDataURL) { - patternImgSrc = patternSource.toDataURL(); - } - - return '\n' + - '\n' + - '\n'; - }, - /* _TO_SVG_END_ */ - - setOptions: function(options) { - for (var prop in options) { - this[prop] = options[prop]; - } - }, - - /** - * Returns an instance of CanvasPattern - * @param {CanvasRenderingContext2D} ctx Context to create pattern - * @return {CanvasPattern} - */ - toLive: function(ctx) { - var source = this.source; - // if the image failed to load, return, and allow rest to continue loading - if (!source) { - return ''; - } + this.source.src : + typeof this.source === 'object' && this.source.toDataURL ? + // element + this.source.toDataURL() : + ''; + } + /** + * Returns object representation of a pattern + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} Object representation of a pattern instance + */ + toObject(propertiesToInclude: (keyof this)[]) { + return { + ...pick(this, propertiesToInclude), + type: 'pattern', + source: this.sourceToString(), + repeat: this.repeat, + crossOrigin: this.crossOrigin, + offsetX: toFixed(this.offsetX, config.NUM_FRACTION_DIGITS), + offsetY: toFixed(this.offsetY, config.NUM_FRACTION_DIGITS), + patternTransform: this.patternTransform ? this.patternTransform.concat() : null + }; + } + + /* _TO_SVG_START_ */ + /** + * Returns SVG representation of a pattern + * @param {fabric.Object} object + * @return {String} SVG representation of a pattern + */ + toSVG(object) { + const patternSource = typeof this.source === 'function' ? this.source() : this.source, + patternOffsetX = this.offsetX / object.width, + patternOffsetY = this.offsetY / object.height, + patternImgSrc = this.sourceToString(); + let patternWidth = patternSource.width / object.width, + patternHeight = patternSource.height / object.height; + if (this.repeat === 'repeat-x' || this.repeat === 'no-repeat') { + patternHeight = 1 + Math.abs(patternOffsetY || 0); + } + if (this.repeat === 'repeat-y' || this.repeat === 'no-repeat') { + patternWidth = 1 + Math.abs(patternOffsetX || 0); + } + + return [ + ``, + ``, + ``, + '' + ].join('\n'); + } + /* _TO_SVG_END_ */ + + setOptions(options: Record) { + for (const prop in options) { + this[prop] = options[prop]; + } + } + + /** + * Returns an instance of CanvasPattern + * @param {CanvasRenderingContext2D} ctx Context to create pattern + * @return {CanvasPattern} + */ + toLive(ctx: CanvasRenderingContext2D) { + const source = this.source; + + if ( + // if the image failed to load, return, and allow rest to continue loading + !source // if an image - if (typeof source.src !== 'undefined') { - if (!source.complete) { - return ''; - } - if (source.naturalWidth === 0 || source.naturalHeight === 0) { - return ''; - } - } - return ctx.createPattern(source, this.repeat); + || (typeof source.src !== 'undefined' + && (!source.complete || source.naturalWidth === 0 || source.naturalHeight === 0)) + ) { + return ''; } - }); + + return ctx.createPattern(source, this.repeat); + } /** * @@ -184,13 +156,14 @@ import { config } from "./config"; * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal * @returns */ - fabric.Pattern.fromObject = function(object, options) { - var patternOptions = Object.assign({}, object), - imageOptions = Object.assign({}, options, { crossOrigin: object.crossOrigin }); - return fabric.util.loadImage(object.source, imageOptions) - .then(function(img) { - patternOptions.source = img; - return new fabric.Pattern(patternOptions); - }); - }; -})(typeof exports !== 'undefined' ? exports : window); + static async fromObject(object: any, options: { signal: AbortSignal }) { + const img = await loadImage(object.source, { + ...options, + crossOrigin: object.crossOrigin + }) + return new Pattern({ ...object, source: img }); + } +} + + +fabric.Pattern = Pattern; diff --git a/src/typedefs.ts b/src/typedefs.ts index e6b493ba53a..a04c83ab7d5 100644 --- a/src/typedefs.ts +++ b/src/typedefs.ts @@ -47,7 +47,7 @@ export const enum SupportedSVGUnit { } export type TMat2D = [number, number, number, number, number, number]; - + export type ModifierKey = 'altKey' | 'shiftKey' | 'ctrlKey'; /** @@ -64,3 +64,9 @@ export type TransformEvent = TEvent & T & { target: any } } + +/** + * An invalid keyword and an empty string will be handled as the `anonymous` keyword. + * @see https://developer.mozilla.org/en-US/docs/HTML/CORS_settings_attributes + */ +export type TCrossOrigin = '' | 'anonymous' | 'use-credentials'; From 91a1996a38e2b8ffb402028754d4350c5c6b14e7 Mon Sep 17 00:00:00 2001 From: ShaMan123 Date: Mon, 5 Sep 2022 20:05:16 +0300 Subject: [PATCH 04/15] types --- src/__types__.ts | 3 +- src/pattern.class.ts | 113 ++++++++++++++++++++-------------- src/typedefs.ts | 2 +- src/util/misc/dom.ts | 2 +- src/util/misc/objectEnlive.ts | 61 +++++++++--------- 5 files changed, 104 insertions(+), 77 deletions(-) diff --git a/src/__types__.ts b/src/__types__.ts index bb693c3bc60..77f9b5f7a5b 100644 --- a/src/__types__.ts +++ b/src/__types__.ts @@ -3,4 +3,5 @@ */ export type Shadow = any; export type Canvas = any; -export type Rect = any; \ No newline at end of file +export type Rect = any; +export type TObject = any; \ No newline at end of file diff --git a/src/pattern.class.ts b/src/pattern.class.ts index 5a74927f9b3..ab042e43bf1 100644 --- a/src/pattern.class.ts +++ b/src/pattern.class.ts @@ -4,9 +4,28 @@ import { TCrossOrigin, TMat2D } from "./typedefs"; import { loadImage } from "./util/misc/objectEnlive"; import { pick } from "./util/misc/pick"; import { toFixed } from "./util/misc/toFixed"; +import { TObject } from "./__types__"; export type TPatternRepeat = 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat'; +type TExportedKeys = 'crossOrigin' | 'offsetX' | 'offsetY' | 'patternTransform' | 'repeat' | 'source'; + +export type TPatternOptions = Partial>; + +export type TPatternSerialized = TPatternOptions & { + source: string; +}; + +export type TPatternHydrationOptions = { + /** + * handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal + */ + signal: AbortSignal +} + +type TImageSource = { source: HTMLImageElement }; +type TCanvasSource = { source: HTMLCanvasElement }; + /** * Pattern class * @class fabric.Pattern @@ -50,7 +69,7 @@ export class Pattern { type = 'pattern' - source!: CanvasImageSource; + source!: CanvasImageSource// | (() => CanvasImageSource); readonly id: number; @@ -60,21 +79,59 @@ export class Pattern { * @param {option.source} [source] the pattern source, eventually empty or a drawable * @return {fabric.Pattern} thisArg */ - constructor(options = {}) { + constructor(options: TPatternOptions = {}) { this.id = fabric.Object.__uid++; this.setOptions(options); } + setOptions(options: Record) { + for (const prop in options) { + this[prop] = options[prop]; + } + } + + /** + * @returns true if {@link source} is a element + */ + isImageSource(): this is TImageSource { + return typeof this.source.src === 'string'; + } + + /** + * @returns true if {@link source} is a element + */ + isCanvasSource(): this is TCanvasSource { + return typeof this.source === 'object' && this.source.toDataURL; + } + sourceToString() { - return typeof this.source.src === 'string' ? - // element + return this.isImageSource() ? this.source.src : - typeof this.source === 'object' && this.source.toDataURL ? - // element + this.isCanvasSource() ? this.source.toDataURL() : ''; } + + /** + * Returns an instance of CanvasPattern + * @param {CanvasRenderingContext2D} ctx Context to create pattern + * @return {CanvasPattern} + */ + toLive(ctx: CanvasRenderingContext2D) { + if ( + // if the image failed to load, return, and allow rest to continue loading + !this.source + // if an image + || (this.isImageSource() + && (!this.source.complete || this.source.naturalWidth === 0 || this.source.naturalHeight === 0)) + ) { + return ''; + } + + return ctx.createPattern(this.source, this.repeat); + } + /** * Returns object representation of a pattern * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output @@ -99,7 +156,7 @@ export class Pattern { * @param {fabric.Object} object * @return {String} SVG representation of a pattern */ - toSVG(object) { + toSVG(object: TObject) { const patternSource = typeof this.source === 'function' ? this.source() : this.source, patternOffsetX = this.offsetX / object.width, patternOffsetY = this.offsetY / object.height, @@ -122,46 +179,12 @@ export class Pattern { } /* _TO_SVG_END_ */ - setOptions(options: Record) { - for (const prop in options) { - this[prop] = options[prop]; - } - } - - /** - * Returns an instance of CanvasPattern - * @param {CanvasRenderingContext2D} ctx Context to create pattern - * @return {CanvasPattern} - */ - toLive(ctx: CanvasRenderingContext2D) { - const source = this.source; - - if ( - // if the image failed to load, return, and allow rest to continue loading - !source - // if an image - || (typeof source.src !== 'undefined' - && (!source.complete || source.naturalWidth === 0 || source.naturalHeight === 0)) - ) { - return ''; - } - - return ctx.createPattern(source, this.repeat); - } - - /** - * - * @param {object} object - * @param {object} [options] - * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal - * @returns - */ - static async fromObject(object: any, options: { signal: AbortSignal }) { - const img = await loadImage(object.source, { + static async fromObject({ source, ...serialized }: TPatternSerialized, options: TPatternHydrationOptions) { + const img = await loadImage(source, { ...options, - crossOrigin: object.crossOrigin + crossOrigin: serialized.crossOrigin }) - return new Pattern({ ...object, source: img }); + return new Pattern({ ...serialized, source: img }); } } diff --git a/src/typedefs.ts b/src/typedefs.ts index a04c83ab7d5..d9d9c292c39 100644 --- a/src/typedefs.ts +++ b/src/typedefs.ts @@ -69,4 +69,4 @@ export type TransformEvent = TEvent & T & { * An invalid keyword and an empty string will be handled as the `anonymous` keyword. * @see https://developer.mozilla.org/en-US/docs/HTML/CORS_settings_attributes */ -export type TCrossOrigin = '' | 'anonymous' | 'use-credentials'; +export type TCrossOrigin = '' | 'anonymous' | 'use-credentials' | null; diff --git a/src/util/misc/dom.ts b/src/util/misc/dom.ts index b944733458d..236fa2bd3bd 100644 --- a/src/util/misc/dom.ts +++ b/src/util/misc/dom.ts @@ -14,7 +14,7 @@ export const createCanvasElement = (): HTMLCanvasElement => fabric.document.crea * @memberOf fabric.util * @return {HTMLImageElement} HTML image element */ -export const createImage = () =>fabric.document.createElement('img'); +export const createImage = (): HTMLImageElement => fabric.document.createElement('img'); /** * Creates a canvas element that is a copy of another and is also painted diff --git a/src/util/misc/objectEnlive.ts b/src/util/misc/objectEnlive.ts index 92d120bf0f9..a19d8958f69 100644 --- a/src/util/misc/objectEnlive.ts +++ b/src/util/misc/objectEnlive.ts @@ -1,6 +1,9 @@ import { fabric } from '../../../HEADER'; -import { capitalize, camelize } from '../lang_string'; import { noop } from '../../constants'; +import { TCrossOrigin } from '../../typedefs'; +import { TObject } from '../../__types__'; +import { camelize, capitalize } from '../lang_string'; +import { createImage } from './dom'; /** * Returns klass "Class" object of given namespace @@ -13,7 +16,7 @@ export const getKlass = (type: string, namespace = fabric): any => namespace[cap type LoadImageOptions = { signal?: AbortSignal; - crossOrigin?: 'anonymous' | 'use-credentials' | null; + crossOrigin?: TCrossOrigin; } /** @@ -26,11 +29,11 @@ type LoadImageOptions = { * @param {Promise} img the loaded image. */ export const loadImage = (url: string, { signal, crossOrigin = null }: LoadImageOptions = {}) => - new Promise(function (resolve, reject) { + new Promise(function (resolve, reject) { if (signal && signal.aborted) { return reject(new Error('`options.signal` is in `aborted` state')); } - const img = fabric.util.createImage(); + const img = createImage(); let abort: EventListenerOrEventListenerObject; if (signal) { abort = function (err: Event) { @@ -39,7 +42,7 @@ export const loadImage = (url: string, { signal, crossOrigin = null }: LoadImage }; signal.addEventListener('abort', abort, { once: true }); } - const done = function() { + const done = function () { img.onload = img.onerror = null; abort && signal?.removeEventListener('abort', abort); resolve(img); @@ -83,31 +86,31 @@ export const enlivenObjects = ( reviver = noop, namespace = fabric, }: EnlivenObjectOptions = {}, -) => new Promise((resolve, reject) => { - const instances: any[] = []; +) => new Promise((resolve, reject) => { + const instances: TObject[] = []; signal && signal.addEventListener('abort', reject, { once: true }); Promise.all(objects.map((obj) => getKlass(obj.type, namespace).fromObject(obj, { signal, reviver, namespace, - }).then((fabricInstance: any) => { + }).then((fabricInstance: TObject) => { reviver(obj, fabricInstance); instances.push(fabricInstance); return fabricInstance; }) )) - .then(resolve) - .catch((error) => { - // cleanup - instances.forEach(function (instance) { - instance.dispose && instance.dispose(); + .then(resolve) + .catch((error) => { + // cleanup + instances.forEach(function (instance) { + instance.dispose && instance.dispose(); + }); + reject(error); + }) + .finally(() => { + signal && signal.removeEventListener('abort', reject); }); - reject(error); - }) - .finally(() => { - signal && signal.removeEventListener('abort', reject); - }); }); /** @@ -134,7 +137,7 @@ export const enlivenObjectEnlivables = (serializedObject: any, { signal }: { sig } // clipPath if (value.type) { - return fabric.util.enlivenObjects([value], { signal }).then(([enlived]: any[]) => { + return enlivenObjects([value], { signal }).then(([enlived]) => { instances.push(enlived); return enlived; }); @@ -155,15 +158,15 @@ export const enlivenObjectEnlivables = (serializedObject: any, { signal }: { sig return acc; }, {}); }) - .then(resolve) - .catch(function (error) { - // cleanup - instances.forEach((instance) => { - instance.dispose && instance.dispose(); + .then(resolve) + .catch(function (error) { + // cleanup + instances.forEach((instance) => { + instance.dispose && instance.dispose(); + }); + reject(error); + }) + .finally(function () { + signal && signal.removeEventListener('abort', reject); }); - reject(error); - }) - .finally(function () { - signal && signal.removeEventListener('abort', reject); - }); }); From 433bdcd3145e3c001fd74b6a51fea2dabb3cd3b3 Mon Sep 17 00:00:00 2001 From: ShaMan123 Date: Mon, 5 Sep 2022 20:11:01 +0300 Subject: [PATCH 05/15] Update pattern.class.ts --- src/pattern.class.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pattern.class.ts b/src/pattern.class.ts index ab042e43bf1..221e89a6e5f 100644 --- a/src/pattern.class.ts +++ b/src/pattern.class.ts @@ -1,3 +1,5 @@ +//@ts-nocheck + import { fabric } from "../HEADER"; import { config } from "./config"; import { TCrossOrigin, TMat2D } from "./typedefs"; From 06c7afd3b79f62062232a4c373d09be8c9b62846 Mon Sep 17 00:00:00 2001 From: ShaMan123 Date: Mon, 5 Sep 2022 20:14:04 +0300 Subject: [PATCH 06/15] Update pattern.js --- test/unit/pattern.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unit/pattern.js b/test/unit/pattern.js index a424eca0031..00389ac86ae 100644 --- a/test/unit/pattern.js +++ b/test/unit/pattern.js @@ -11,10 +11,10 @@ var img = fabric.document.createElement('img'); setSrc(img, IMG_SRC); - function createPattern(callback) { + function createPattern() { return new fabric.Pattern({ source: img - }, callback); + }); } QUnit.test('constructor', function(assert) { From c121239206f4fdf3594e4dc4d9c0f80364b4666b Mon Sep 17 00:00:00 2001 From: ShaMan123 Date: Mon, 5 Sep 2022 20:21:38 +0300 Subject: [PATCH 07/15] Update pattern.class.ts --- src/pattern.class.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pattern.class.ts b/src/pattern.class.ts index 221e89a6e5f..4c4bdd0a7bf 100644 --- a/src/pattern.class.ts +++ b/src/pattern.class.ts @@ -93,7 +93,7 @@ export class Pattern { } /** - * @returns true if {@link source} is a element + * @returns true if {@link source} is an element */ isImageSource(): this is TImageSource { return typeof this.source.src === 'string'; From 482ded8b2fdbd6b3008087ab00d3642c05f79f78 Mon Sep 17 00:00:00 2001 From: ShaMan123 Date: Mon, 5 Sep 2022 20:23:08 +0300 Subject: [PATCH 08/15] fix(): `toSVG` source value This line was missed in #6296 --- src/pattern.class.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pattern.class.ts b/src/pattern.class.ts index 4c4bdd0a7bf..82d2202a74a 100644 --- a/src/pattern.class.ts +++ b/src/pattern.class.ts @@ -159,7 +159,7 @@ export class Pattern { * @return {String} SVG representation of a pattern */ toSVG(object: TObject) { - const patternSource = typeof this.source === 'function' ? this.source() : this.source, + const patternSource = this.sourceToString(), patternOffsetX = this.offsetX / object.width, patternOffsetY = this.offsetY / object.height, patternImgSrc = this.sourceToString(); From 16ddc8c723a17e8c878974fe2134439ad172f470 Mon Sep 17 00:00:00 2001 From: ShaMan123 Date: Mon, 5 Sep 2022 20:25:07 +0300 Subject: [PATCH 09/15] Update pattern.class.ts --- src/pattern.class.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pattern.class.ts b/src/pattern.class.ts index 82d2202a74a..ca81545443c 100644 --- a/src/pattern.class.ts +++ b/src/pattern.class.ts @@ -161,8 +161,7 @@ export class Pattern { toSVG(object: TObject) { const patternSource = this.sourceToString(), patternOffsetX = this.offsetX / object.width, - patternOffsetY = this.offsetY / object.height, - patternImgSrc = this.sourceToString(); + patternOffsetY = this.offsetY / object.height; let patternWidth = patternSource.width / object.width, patternHeight = patternSource.height / object.height; if (this.repeat === 'repeat-x' || this.repeat === 'no-repeat') { @@ -174,7 +173,7 @@ export class Pattern { return [ ``, - ``, + ``, ``, '' ].join('\n'); From 97127a19f2a5ec7aa55486d8373f1991773772bd Mon Sep 17 00:00:00 2001 From: ShaMan123 Date: Mon, 5 Sep 2022 20:28:33 +0300 Subject: [PATCH 10/15] cleanup --- src/pattern.class.ts | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/pattern.class.ts b/src/pattern.class.ts index ca81545443c..9f0152d6266 100644 --- a/src/pattern.class.ts +++ b/src/pattern.class.ts @@ -2,7 +2,7 @@ import { fabric } from "../HEADER"; import { config } from "./config"; -import { TCrossOrigin, TMat2D } from "./typedefs"; +import { TCrossOrigin, TMat2D, TSize } from "./typedefs"; import { loadImage } from "./util/misc/objectEnlive"; import { pick } from "./util/misc/pick"; import { toFixed } from "./util/misc/toFixed"; @@ -20,7 +20,8 @@ export type TPatternSerialized = TPatternOptions & { export type TPatternHydrationOptions = { /** - * handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal + * handle aborting + * @see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal */ signal: AbortSignal } @@ -29,9 +30,7 @@ type TImageSource = { source: HTMLImageElement }; type TCanvasSource = { source: HTMLCanvasElement }; /** - * Pattern class - * @class fabric.Pattern - * @see {@link http://fabricjs.com/patterns|Pattern demo} + * @see {@link http://fabricjs.com/patterns demo} * @see {@link http://fabricjs.com/dynamic-patterns demo} */ export class Pattern { @@ -71,7 +70,7 @@ export class Pattern { type = 'pattern' - source!: CanvasImageSource// | (() => CanvasImageSource); + source!: CanvasImageSource readonly id: number; @@ -158,12 +157,12 @@ export class Pattern { * @param {fabric.Object} object * @return {String} SVG representation of a pattern */ - toSVG(object: TObject) { + toSVG({ width, height }: TSize) { const patternSource = this.sourceToString(), - patternOffsetX = this.offsetX / object.width, - patternOffsetY = this.offsetY / object.height; - let patternWidth = patternSource.width / object.width, - patternHeight = patternSource.height / object.height; + patternOffsetX = this.offsetX / width, + patternOffsetY = this.offsetY / height; + let patternWidth = patternSource.width / width, + patternHeight = patternSource.height / height; if (this.repeat === 'repeat-x' || this.repeat === 'no-repeat') { patternHeight = 1 + Math.abs(patternOffsetY || 0); } From c9f65ce46a3513d7e621a2df9eefdb9e3e10f025 Mon Sep 17 00:00:00 2001 From: ShaMan123 Date: Mon, 5 Sep 2022 20:34:23 +0300 Subject: [PATCH 11/15] safeguard nan --- src/pattern.class.ts | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/pattern.class.ts b/src/pattern.class.ts index 9f0152d6266..52e11f42490 100644 --- a/src/pattern.class.ts +++ b/src/pattern.class.ts @@ -3,10 +3,10 @@ import { fabric } from "../HEADER"; import { config } from "./config"; import { TCrossOrigin, TMat2D, TSize } from "./typedefs"; +import { ifNaN } from "./util/internals"; import { loadImage } from "./util/misc/objectEnlive"; import { pick } from "./util/misc/pick"; import { toFixed } from "./util/misc/toFixed"; -import { TObject } from "./__types__"; export type TPatternRepeat = 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat'; @@ -136,7 +136,7 @@ export class Pattern { /** * Returns object representation of a pattern * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} Object representation of a pattern instance + * @return {object} Object representation of a pattern instance */ toObject(propertiesToInclude: (keyof this)[]) { return { @@ -154,15 +154,13 @@ export class Pattern { /* _TO_SVG_START_ */ /** * Returns SVG representation of a pattern - * @param {fabric.Object} object - * @return {String} SVG representation of a pattern */ toSVG({ width, height }: TSize) { const patternSource = this.sourceToString(), - patternOffsetX = this.offsetX / width, - patternOffsetY = this.offsetY / height; - let patternWidth = patternSource.width / width, - patternHeight = patternSource.height / height; + patternOffsetX = ifNaN(this.offsetX / width, 0), + patternOffsetY = ifNaN(this.offsetY / height, 0); + let patternWidth = ifNaN(patternSource.width / width, 0), + patternHeight = ifNaN(patternSource.height / height, 0); if (this.repeat === 'repeat-x' || this.repeat === 'no-repeat') { patternHeight = 1 + Math.abs(patternOffsetY || 0); } From ba435687d2c15aa9312579c3d75f3a0ff8321e9f Mon Sep 17 00:00:00 2001 From: ShaMan123 Date: Mon, 5 Sep 2022 20:39:08 +0300 Subject: [PATCH 12/15] fix svg exporting --- src/pattern.class.ts | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/pattern.class.ts b/src/pattern.class.ts index 52e11f42490..cff5f7b58f1 100644 --- a/src/pattern.class.ts +++ b/src/pattern.class.ts @@ -156,21 +156,19 @@ export class Pattern { * Returns SVG representation of a pattern */ toSVG({ width, height }: TSize) { - const patternSource = this.sourceToString(), + const { width: patternWidth, height: patternHeight } = this.source, patternOffsetX = ifNaN(this.offsetX / width, 0), - patternOffsetY = ifNaN(this.offsetY / height, 0); - let patternWidth = ifNaN(patternSource.width / width, 0), - patternHeight = ifNaN(patternSource.height / height, 0); - if (this.repeat === 'repeat-x' || this.repeat === 'no-repeat') { - patternHeight = 1 + Math.abs(patternOffsetY || 0); - } - if (this.repeat === 'repeat-y' || this.repeat === 'no-repeat') { - patternWidth = 1 + Math.abs(patternOffsetX || 0); - } + patternOffsetY = ifNaN(this.offsetY / height, 0), + patternWidth = this.repeat === 'repeat-y' || this.repeat === 'no-repeat' ? + 1 + Math.abs(patternOffsetX) : + ifNaN(patternWidth / width, 0), + patternHeight = this.repeat === 'repeat-x' || this.repeat === 'no-repeat' ? + 1 + Math.abs(patternOffsetY) : + ifNaN(patternHeight / height, 0); return [ ``, - ``, + ``, ``, '' ].join('\n'); From cbfb8dd553e101287fdfe53158f9a1c2028875fd Mon Sep 17 00:00:00 2001 From: ShaMan123 Date: Mon, 5 Sep 2022 20:43:10 +0300 Subject: [PATCH 13/15] Revert "fix svg exporting" This reverts commit ba435687d2c15aa9312579c3d75f3a0ff8321e9f. --- src/pattern.class.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/pattern.class.ts b/src/pattern.class.ts index cff5f7b58f1..44bc2b6710f 100644 --- a/src/pattern.class.ts +++ b/src/pattern.class.ts @@ -156,19 +156,19 @@ export class Pattern { * Returns SVG representation of a pattern */ toSVG({ width, height }: TSize) { - const { width: patternWidth, height: patternHeight } = this.source, + const patternSource = this.source, patternOffsetX = ifNaN(this.offsetX / width, 0), patternOffsetY = ifNaN(this.offsetY / height, 0), patternWidth = this.repeat === 'repeat-y' || this.repeat === 'no-repeat' ? - 1 + Math.abs(patternOffsetX) : - ifNaN(patternWidth / width, 0), + 1 + Math.abs(patternOffsetX || 0) : + ifNaN(patternSource.width / width, 0), patternHeight = this.repeat === 'repeat-x' || this.repeat === 'no-repeat' ? - 1 + Math.abs(patternOffsetY) : - ifNaN(patternHeight / height, 0); + 1 + Math.abs(patternOffsetY || 0) : + ifNaN(patternSource.height / height, 0); return [ ``, - ``, + ``, ``, '' ].join('\n'); From 6ca7c30034122c8ca58370c85dc3316a7bd48e66 Mon Sep 17 00:00:00 2001 From: ShaMan123 Date: Mon, 5 Sep 2022 20:54:38 +0300 Subject: [PATCH 14/15] Revert "Update .npmignore" This reverts commit 03d94c37f617e2919cd1696dfbf3b1fd472a683d. --- .npmignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.npmignore b/.npmignore index 901ecd925b8..c2fae2f6103 100644 --- a/.npmignore +++ b/.npmignore @@ -1,6 +1,5 @@ .github/ .nyc_output/ -cli_output/ lib/*.jar lib/*.png coverage/ From 93a6580e165a1a8e61d698cebf29c1d68cd6b27b Mon Sep 17 00:00:00 2001 From: ShaMan123 Date: Wed, 7 Sep 2022 09:06:38 +0300 Subject: [PATCH 15/15] Update pattern.class.ts --- src/pattern.class.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pattern.class.ts b/src/pattern.class.ts index 44bc2b6710f..5022a683720 100644 --- a/src/pattern.class.ts +++ b/src/pattern.class.ts @@ -35,6 +35,8 @@ type TCanvasSource = { source: HTMLCanvasElement }; */ export class Pattern { + type = 'pattern' + /** * @type TPatternRepeat * @defaults @@ -68,8 +70,6 @@ export class Pattern { */ patternTransform: TMat2D | null = null - type = 'pattern' - source!: CanvasImageSource readonly id: number;