Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(TS): convert StaticCanvas #8485

Merged
merged 20 commits into from
Dec 5, 2022
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## [next]

- chore(TS): migrate StatiCanvas to TS [#8485](https://github.com/fabricjs/fabric.js/pull/8485)
- chore(): refactor `Object.__uid++` => `uid()` [#8482](https://github.com/fabricjs/fabric.js/pull/8482)
- chore(TS): migrate object mixins to TS [#8414](https://github.com/fabricjs/fabric.js/pull/8414)
- chore(TS): migrate filters [#8474](https://github.com/fabricjs/fabric.js/pull/8474)
Expand Down
14 changes: 9 additions & 5 deletions src/EventTypeDefs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { TOriginX, TOriginY, TRadian } from './typedefs';
import type { saveObjectTransform } from './util/misc/objectTransforms';
import type { Canvas } from './__types__';
import type { IText } from './shapes/itext.class';
import type { StaticCanvas } from './static_canvas.class';

export type ModifierKey = 'altKey' | 'shiftKey' | 'ctrlKey';

Expand Down Expand Up @@ -149,6 +150,11 @@ type CanvasSelectionEvents = {
};
};

type CollectionEvents = {
'object:added': { target: FabricObject };
'object:removed': { target: FabricObject };
};

type BeforeSuffix<T extends string> = `${T}:before`;
type WithBeforeSuffix<T extends string> = T | BeforeSuffix<T>;

Expand Down Expand Up @@ -181,17 +187,15 @@ export type ObjectEvents = ObjectPointerEvents &
};

// tree
added: { target: Group | Canvas };
removed: { target: Group | Canvas };
added: { target: Group | Canvas | StaticCanvas };
removed: { target: Group | Canvas | StaticCanvas };

// erasing
'erasing:end': { path: FabricObject };
};

export type StaticCanvasEvents = {
export type StaticCanvasEvents = CollectionEvents & {
// tree
'object:added': { target: FabricObject };
'object:removed': { target: FabricObject };
'canvas:cleared': never;

// rendering
Expand Down
5 changes: 5 additions & 0 deletions src/canvas.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1418,6 +1418,11 @@ import { saveObjectTransform } from './util/misc/objectTransforms';
// this.discardActiveGroup();
this.discardActiveObject();
this.clearContext(this.contextTop);
if (this._hasITextHandlers) {
this.off('mouse:up', this._mouseUpITextHandler);
this._iTextInstances = null;
this._hasITextHandlers = false;
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

StaticCanvas shouldn't have Itext handlers, if someone come with a real use case we can revert this back

return this.callSuper('clear');
},

Expand Down
23 changes: 17 additions & 6 deletions src/gradient/gradient.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,25 @@ export class Gradient<
*/
type: T;

/**
* Defines how the gradient is located in space and spread
* @type GradientCoords
*/
coords: GradientCoords<T>;

/**
* Defines how many colors a gradient has and how they are located on the axis
* defined by coords
* @type GradientCoords
*/
colorStops: ColorStop[];

/**
* If true, this object will not be exported during the serialization of a canvas
* @type boolean
*/
excludeFromExport?: boolean;

private id: string | number;

constructor({
Expand Down Expand Up @@ -130,7 +145,7 @@ export class Gradient<
* @param {string[]} [propertiesToInclude] Any properties that you might want to additionally include in the output
* @return {object}
*/
toObject(propertiesToInclude?: (keyof this)[]) {
toObject(propertiesToInclude?: (keyof this | string)[]) {
return {
...pick(this, propertiesToInclude),
type: this.type,
Expand Down Expand Up @@ -276,11 +291,7 @@ export class Gradient<
* @param {CanvasRenderingContext2D} ctx Context to render on
* @return {CanvasGradient}
*/
toLive(ctx: CanvasRenderingContext2D) {
if (!this.type) {
return;
}

toLive(ctx: CanvasRenderingContext2D): CanvasGradient {
const coords = this.coords as GradientCoords<'radial'>;
const gradient =
this.type === 'linear'
Expand Down
2 changes: 1 addition & 1 deletion src/mixins/collection.mixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export function createCollectionMixin<T extends { new (...args: any[]): any }>(
* @param {...FabricObject[]} objects to add
* @returns {number} new array length
*/
add(...objects: FabricObject[]) {
add(...objects: FabricObject[]): number {
const size = this._objects.push(...objects);
objects.forEach((object) => this._onObjectAdded(object));
return size;
Expand Down
21 changes: 14 additions & 7 deletions src/mixins/object.svg_export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { uid } from '../util/internals/uid';
import { matrixToSVG } from '../util/misc/svgParsing';
import { toFixed } from '../util/misc/toFixed';

type SVGReviver = (markup: string) => string;
export type TSVGReviver = (markup: string) => string;

/* _TO_SVG_START_ */

Expand All @@ -29,6 +29,13 @@ function getSvgColorString(prop: string, value?: any) {
}

export class FabricObjectSVGExportMixin {
/**
* When an object is being exported as SVG as a clippath, a reference inside the SVG is needed.
* This reference is a UID in the fabric namespace and is temporary stored here.
* @type {String}
*/
clipPathId?: string;

/**
* Returns styles-string for svg-export
* @param {Boolean} skipShadow a boolean to skip shadow filter output
Expand Down Expand Up @@ -191,21 +198,21 @@ export class FabricObjectSVGExportMixin {

/**
* Returns svg representation of an instance
* @param {SVGReviver} [reviver] Method for further parsing of svg representation.
* @param {TSVGReviver} [reviver] Method for further parsing of svg representation.
* @return {String} svg representation of an instance
*/
toSVG(reviver?: SVGReviver) {
toSVG(reviver?: TSVGReviver) {
return this._createBaseSVGMarkup(this._toSVG(reviver), {
reviver,
});
}

/**
* Returns svg clipPath representation of an instance
* @param {SVGReviver} [reviver] Method for further parsing of svg representation.
* @param {TSVGReviver} [reviver] Method for further parsing of svg representation.
* @return {String} svg representation of an instance
*/
toClipPathSVG(reviver?: SVGReviver) {
toClipPathSVG(reviver?: TSVGReviver) {
return (
'\t' +
this._createBaseClipPathSVGMarkup(this._toSVG(reviver), {
Expand All @@ -222,7 +229,7 @@ export class FabricObjectSVGExportMixin {
{
reviver,
additionalTransform = '',
}: { reviver?: SVGReviver; additionalTransform?: string } = {}
}: { reviver?: TSVGReviver; additionalTransform?: string } = {}
) {
const commonPieces = [
this.getSvgTransform(true, additionalTransform),
Expand All @@ -246,7 +253,7 @@ export class FabricObjectSVGExportMixin {
additionalTransform,
}: {
noStyle?: boolean;
reviver?: SVGReviver;
reviver?: TSVGReviver;
withShadow?: boolean;
additionalTransform?: string;
} = {}
Expand Down
8 changes: 4 additions & 4 deletions src/mixins/object_geometry.mixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,8 +293,8 @@ export class ObjectGeometry<
*/
intersectsWithObject(
other: ObjectGeometry,
absolute: boolean,
calculate: boolean
absolute = false,
calculate = false
): boolean {
const intersection = Intersection.intersectPolygonPolygon(
this.getCoords(absolute, calculate),
Expand All @@ -318,8 +318,8 @@ export class ObjectGeometry<
*/
isContainedWithinObject(
other: ObjectGeometry,
absolute: boolean,
calculate: boolean
absolute = false,
calculate = false
): boolean {
const points = this.getCoords(absolute, calculate),
otherCoords = absolute ? other.aCoords : other.lineCoords,
Expand Down
13 changes: 11 additions & 2 deletions src/pattern.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,17 @@ export class Pattern {
*/
patternTransform: TMat2D | null = null;

/**
* The actual pixel source of the pattern
*/
source!: CanvasImageSource;

/**
* If true, this object will not be exported during the serialization of a canvas
* @type boolean
*/
excludeFromExport?: boolean;

readonly id: number;

/**
Expand Down Expand Up @@ -122,7 +131,7 @@ export class Pattern {
* @param {CanvasRenderingContext2D} ctx Context to create pattern
* @return {CanvasPattern}
*/
toLive(ctx: CanvasRenderingContext2D) {
toLive(ctx: CanvasRenderingContext2D): CanvasPattern | string {
if (
// if the image failed to load, return, and allow rest to continue loading
!this.source ||
Expand All @@ -143,7 +152,7 @@ export class 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)[]) {
toObject(propertiesToInclude?: (keyof this | string)[]) {
return {
...pick(this, propertiesToInclude),
type: 'pattern',
Expand Down
19 changes: 9 additions & 10 deletions src/shapes/group.class.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
//@ts-nocheck
import { ObjectEvents } from '../EventTypeDefs';
import type { ObjectEvents, CollectionEvents } from '../EventTypeDefs';
import { fabric } from '../../HEADER';
import { createCollectionMixin } from '../mixins/collection.mixin';
import { resolveOrigin } from '../mixins/object_origin.mixin';
import { Point } from '../point.class';
import { TClassProperties } from '../typedefs';
import type { TClassProperties } from '../typedefs';
import { cos } from '../util/misc/cos';
import {
invertTransform,
Expand Down Expand Up @@ -44,15 +44,14 @@ export type LayoutResult = {
height: number;
};

export type GroupEvents = ObjectEvents & {
layout: {
context: LayoutContext;
result: LayoutResult;
diff: Point;
export type GroupEvents = ObjectEvents &
CollectionEvents & {
layout: {
context: LayoutContext;
result: LayoutResult;
diff: Point;
};
};
'object:added': { target: FabricObject };
'object:removed': { target: FabricObject };
};

export type LayoutStrategy =
| 'fit-content'
Expand Down
35 changes: 31 additions & 4 deletions src/shapes/object.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ import { ObjectEvents } from '../EventTypeDefs';
import { AnimatableObject } from '../mixins/object_animation.mixin';
import { Point } from '../point.class';
import { Shadow } from '../shadow.class';
import type { TClassProperties, TDegree, TFiller, TSize } from '../typedefs';
import type {
TClassProperties,
TDegree,
TFiller,
TSize,
TCacheCanvasDimensions,
} from '../typedefs';
import { runningAnimations } from '../util/animation_registry';
import { clone } from '../util/lang_object';
import { capitalize } from '../util/lang_string';
Expand All @@ -19,6 +25,18 @@ import { pick } from '../util/misc/pick';
import { toFixed } from '../util/misc/toFixed';
import type { Group } from './group.class';

export type TCachedFabricObject = FabricObject &
Required<
Pick<
FabricObject,
| 'zoomX'
| 'zoomY'
| '_cacheCanvas'
| 'cacheTranslationX'
| 'cacheTranslationY'
>
>;

// temporary hack for unfinished migration
type TCallSuper = (arg0: string, ...moreArgs: any[]) => any;

Expand Down Expand Up @@ -596,6 +614,15 @@ export class FabricObject<
*/
ownCaching?: boolean;

/**
* Private. indicates if the object inside a group is on a transformed context or not
* or is part of a larger cache for many object ( a group for example)
* @type boolean
* @default undefined
* @private
*/
_transformDone?: boolean;

callSuper?: TCallSuper;

/**
Expand Down Expand Up @@ -694,7 +721,7 @@ export class FabricObject<
* @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache
* @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache
*/
_getCacheCanvasDimensions() {
_getCacheCanvasDimensions(): TCacheCanvasDimensions {
const objectScale = this.getTotalObjectScaling(),
// calculate dimensions without skewing
dim = this._getTransformedDimensions({ skewX: 0, skewY: 0 }),
Expand Down Expand Up @@ -826,7 +853,7 @@ export class FabricObject<
* @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
* @return {Object} Object representation of an instance
*/
toObject(propertiesToInclude?: (keyof this)[]): Record<string, any> {
toObject(propertiesToInclude?: (keyof this | string)[]): Record<string, any> {
const NUM_FRACTION_DIGITS = config.NUM_FRACTION_DIGITS,
clipPathData =
this.clipPath && !this.clipPath.excludeFromExport
Expand Down Expand Up @@ -891,7 +918,7 @@ export class FabricObject<
* @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
* @return {Object} Object representation of an instance
*/
toDatalessObject(propertiesToInclude: (keyof this)[]) {
toDatalessObject(propertiesToInclude?: (keyof this | string)[]) {
// will be overwritten by subclasses
return this.toObject(propertiesToInclude);
}
Expand Down
4 changes: 2 additions & 2 deletions src/shapes/text.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { cache } from '../cache';
import { DEFAULT_SVG_FONT_SIZE } from '../constants';
import { ObjectEvents } from '../EventTypeDefs';
import { TextStyle, TextStyleMixin } from '../mixins/text_style.mixin';
import { TClassProperties, TFiller } from '../typedefs';
import { TClassProperties, TFiller, TCacheCanvasDimensions } from '../typedefs';
import { graphemeSplit } from '../util/lang_string';
import { createCanvasElement } from '../util/misc/dom';
import {
Expand Down Expand Up @@ -556,7 +556,7 @@ export class Text<
* @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache
* @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache
*/
_getCacheCanvasDimensions(): object {
_getCacheCanvasDimensions(): TCacheCanvasDimensions {
const dims = super._getCacheCanvasDimensions();
const fontSize = this.fontSize;
dims.width += fontSize * dims.zoomX;
Expand Down