Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/EventTypeDefs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ type CanvasSelectionEvents = {
};
};

type CollectionEvents = {
export type CollectionEvents = {
'object:added': { target: FabricObject };
'object:removed': { target: FabricObject };
};
Expand Down
14 changes: 8 additions & 6 deletions src/mixins/collection.mixin.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { fabric } from '../../HEADER';
import type { FabricObject } from '../shapes/fabricObject.class';
import { FabricObject } from '../shapes/fabricObject.class';
import { Constructor } from '../typedefs';

export function createCollectionMixin<T extends { new (...args: any[]): any }>(
Klass: T
) {
return class Collection extends Klass {
export function createCollectionMixin<TBase extends Constructor>(Base: TBase) {
class Collection extends Base {
/**
* @type {FabricObject[]}
*/
Expand Down Expand Up @@ -153,7 +152,10 @@ export function createCollectionMixin<T extends { new (...args: any[]): any }>(
return memo;
}, 0);
}
};
}

// https://github.com/microsoft/TypeScript/issues/32080
return Collection as typeof Collection & TBase;
}

fabric.createCollectionMixin = createCollectionMixin;
14 changes: 6 additions & 8 deletions src/shapes/fabricObject.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,16 @@ import { fabric } from '../../HEADER';
import { ObjectEvents } from '../EventTypeDefs';
import { FabricObjectSVGExportMixin } from '../mixins/object.svg_export';
import { InteractiveFabricObject } from '../mixins/object_interactivity.mixin';
import { applyMixins } from '../util/applyMixins';

// TODO somehow we have to make a tree-shakeable import

export class FabricObject extends applyMixins(InteractiveFabricObject, [
FabricObjectSVGExportMixin,
]) {}

// @ts-expect-error type conflict of generic EventSpec
// eslint-disable-next-line @typescript-eslint/no-empty-interface, @typescript-eslint/no-unused-vars
export interface FabricObject<EventSpec extends ObjectEvents = ObjectEvents>
extends InteractiveFabricObject<EventSpec>,
FabricObjectSVGExportMixin {}
extends FabricObjectSVGExportMixin {}

export class FabricObject<
EventSpec extends ObjectEvents = ObjectEvents
> extends InteractiveFabricObject<EventSpec> {}

export { fabricObjectDefaultValues } from './object.class';

Expand Down
11 changes: 2 additions & 9 deletions src/shapes/group.class.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//@ts-nocheck
import type { ObjectEvents, CollectionEvents } from '../EventTypeDefs';
// @ts-nocheck
import { fabric } from '../../HEADER';
import type { CollectionEvents, ObjectEvents } from '../EventTypeDefs';
import { createCollectionMixin } from '../mixins/collection.mixin';
import { resolveOrigin } from '../mixins/object_origin.mixin';
import { Point } from '../point.class';
Expand Down Expand Up @@ -37,13 +37,6 @@ export type LayoutContext = {
[key: string]: any;
};

export type LayoutResult = {
centerX: number;
centerY: number;
width: number;
height: number;
};

export type GroupEvents = ObjectEvents &
CollectionEvents & {
layout: {
Expand Down
38 changes: 36 additions & 2 deletions src/static_canvas.class.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
// @ts-nocheck
import { fabric } from '../HEADER';
import type { BaseBrush } from './brushes';
import { config } from './config';
import { iMatrix, VERSION } from './constants';
import type { StaticCanvasEvents } from './EventTypeDefs';
Expand Down Expand Up @@ -229,6 +231,8 @@ export class StaticCanvas extends createCollectionMixin(
*/
lowerCanvasEl: HTMLCanvasElement;

contextContainer: CanvasRenderingContext2D;

/**
* Width in virtual/logical pixels of the canvas.
* The canvas can be larger than width if retina scaling is active
Expand Down Expand Up @@ -257,6 +261,28 @@ export class StaticCanvas extends createCollectionMixin(
*/
disposed?: boolean;

renderAndResetBound: () => void;
requestRenderAllBound: () => StaticCanvas;

// TODO: move to canvas
interactive: boolean;
upperCanvasEl: HTMLCanvasElement;
contextTop: CanvasRenderingContext2D;
wrapperEl: HTMLDivElement;
cacheCanvasEl: HTMLCanvasElement;
protected _isCurrentlyDrawing: boolean;
freeDrawingBrush: BaseBrush;
_activeObject: FabricObject;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

All of there belong to canvas along with drawControls and _applyCanvasStyle

Copy link
Member

Choose a reason for hiding this comment

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

So how this passed before withtout the ts-nocheck on top?
How did i get a clea build without those types?


_offset: { left: number; top: number };
protected _originalCanvasStyle?: string;
protected hasLostContext: boolean;
protected nextRenderHandle: number;
protected __cleanupTask: {
(): void;
kill: (reason?: any) => void;
};

add(...objects: FabricObject[]) {
const size = super.add(...objects);
objects.length > 0 && this.renderOnAddRemove && this.requestRenderAll();
Expand Down Expand Up @@ -453,6 +479,9 @@ export class StaticCanvas extends createCollectionMixin(

this.contextContainer = this.lowerCanvasEl.getContext('2d');
}
_applyCanvasStyle(lowerCanvasEl: HTMLCanvasElement) {
throw new Error('Method not implemented.');
}

/**
* Returns canvas width (in px)
Expand Down Expand Up @@ -554,6 +583,7 @@ export class StaticCanvas extends createCollectionMixin(
this.upperCanvasEl[prop] = value;
}

// TODO: move to canvas
if (this.cacheCanvasEl) {
this.cacheCanvasEl[prop] = value;
}
Expand Down Expand Up @@ -851,6 +881,9 @@ export class StaticCanvas extends createCollectionMixin(
this.__cleanupTask = undefined;
}
}
drawControls(ctx: CanvasRenderingContext2D) {
throw new Error('Method not implemented.');
}

/**
* Paint the cached clipPath on the lowerCanvasEl
Expand Down Expand Up @@ -1764,16 +1797,17 @@ export class StaticCanvas extends createCollectionMixin(
}
this.overlayImage = null;
this._iTextInstances = null;
// @ts-expect-error disposing
this.contextContainer = null;
const canvasElement = this.lowerCanvasEl;
// @ts-ignore
// @ts-expect-error disposing
this.lowerCanvasEl = undefined;
// restore canvas style and attributes
canvasElement.classList.remove('lower-canvas');
canvasElement.removeAttribute('data-fabric');
// needs to be moved into Canvas class
if (this.interactive) {
canvasElement.style.cssText = this._originalCanvasStyle;
canvasElement.style.cssText = this._originalCanvasStyle || '';
delete this._originalCanvasStyle;
}
// restore canvas size to original size in case retina scaling was applied
Expand Down
3 changes: 3 additions & 0 deletions src/typedefs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ type TNonFunctionPropertyNames<T> = {
}[keyof T];
export type TClassProperties<T> = Pick<T, TNonFunctionPropertyNames<T>>;

// https://github.com/microsoft/TypeScript/issues/32080
export type Constructor<T = object> = new (...args: any[]) => T;

const enum Degree {}
const enum Radian {}

Expand Down
6 changes: 3 additions & 3 deletions src/util/applyMixins.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
type TClass = { new (...args: any[]): any };
import { Constructor } from '../typedefs';

/***
* https://www.typescriptlang.org/docs/handbook/mixins.html#alternative-pattern
*/
export function applyMixins<T extends TClass, S extends TClass>(
export function applyMixins<T extends Constructor, S extends Constructor>(
derivedCtor: T,
constructors: S[]
) {
Expand All @@ -18,5 +18,5 @@ export function applyMixins<T extends TClass, S extends TClass>(
);
});
});
return derivedCtor;
return derivedCtor as T & { prototype: InstanceType<T & S> };
}