mirror of
https://github.com/konvajs/konva.git
synced 2025-06-28 02:03:47 +08:00
feat: improved types in Node
No logic changes - only typing changes.
This commit is contained in:
parent
583fccf249
commit
2b5a1aa4a3
222
src/Node.ts
222
src/Node.ts
@ -3,7 +3,18 @@ import { Factory } from './Factory';
|
||||
import { SceneCanvas, HitCanvas, Canvas } from './Canvas';
|
||||
import { Konva } from './Global';
|
||||
import { Container } from './Container';
|
||||
import { GetSet, Vector2d, IRect } from './types';
|
||||
import {
|
||||
GetSet,
|
||||
Vector2d,
|
||||
IRect,
|
||||
ToCanvasConfig,
|
||||
ToDataURLConfig,
|
||||
ToImageConfig,
|
||||
ToBlobConfig,
|
||||
Size,
|
||||
CacheConfig,
|
||||
GetClientRectConfig,
|
||||
} from './types';
|
||||
import { DD } from './DragAndDrop';
|
||||
import {
|
||||
getNumberValidator,
|
||||
@ -172,11 +183,11 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
// all change event listeners are attached to the prototype
|
||||
}
|
||||
|
||||
hasChildren() {
|
||||
hasChildren(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
_clearCache(attr?: string) {
|
||||
_clearCache(attr?: string): void {
|
||||
// if we want to clear transform cache
|
||||
// we don't really need to remove it from the cache
|
||||
// but instead mark as "dirty"
|
||||
@ -300,17 +311,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* drawBorder: true
|
||||
* });
|
||||
*/
|
||||
cache(config?: {
|
||||
x?: number;
|
||||
y?: number;
|
||||
width?: number;
|
||||
height?: number;
|
||||
drawBorder?: boolean;
|
||||
offset?: number;
|
||||
pixelRatio?: number;
|
||||
imageSmoothingEnabled?: boolean;
|
||||
hitCanvasPixelRatio?: number;
|
||||
}) {
|
||||
cache(config?: CacheConfig): typeof this | undefined {
|
||||
var conf = config || {};
|
||||
var rect = {} as IRect;
|
||||
|
||||
@ -445,7 +446,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* @name Konva.Node#isCached
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
isCached() {
|
||||
isCached(): boolean {
|
||||
return this._cache.has(CANVAS);
|
||||
}
|
||||
|
||||
@ -487,17 +488,12 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* rect.getClientRect();
|
||||
* // returns Object {x: -2, y: 46, width: 104, height: 208}
|
||||
*/
|
||||
getClientRect(config?: {
|
||||
skipTransform?: boolean;
|
||||
skipShadow?: boolean;
|
||||
skipStroke?: boolean;
|
||||
relativeTo?: Container;
|
||||
}): { x: number; y: number; width: number; height: number } {
|
||||
getClientRect(config?: GetClientRectConfig): IRect {
|
||||
// abstract method
|
||||
// redefine in Container and Shape
|
||||
throw new Error('abstract "getClientRect" method call');
|
||||
}
|
||||
_transformedRect(rect: IRect, top?: Node | null) {
|
||||
_transformedRect(rect: IRect, top?: Node | null): IRect {
|
||||
var points = [
|
||||
{ x: rect.x, y: rect.y },
|
||||
{ x: rect.x + rect.width, y: rect.y },
|
||||
@ -527,7 +523,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
height: maxY - minY,
|
||||
};
|
||||
}
|
||||
_drawCachedSceneCanvas(context: Context) {
|
||||
_drawCachedSceneCanvas(context: Context): void {
|
||||
context.save();
|
||||
context._applyOpacity(this);
|
||||
context._applyGlobalCompositeOperation(this);
|
||||
@ -547,7 +543,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
);
|
||||
context.restore();
|
||||
}
|
||||
_drawCachedHitCanvas(context: Context) {
|
||||
_drawCachedHitCanvas(context: Context): void {
|
||||
var canvasCache = this._getCanvasCache(),
|
||||
hitCanvas = canvasCache.hit;
|
||||
context.save();
|
||||
@ -750,7 +746,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* // remove listener by name
|
||||
* node.off('click.foo');
|
||||
*/
|
||||
off(evtStr?: string, callback?: Function) {
|
||||
off(evtStr?: string, callback?: Function): typeof this {
|
||||
var events = (evtStr || '').split(SPACE),
|
||||
len = events.length,
|
||||
n,
|
||||
@ -787,7 +783,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
return this;
|
||||
}
|
||||
// some event aliases for third party integration like HammerJS
|
||||
dispatchEvent(evt: any) {
|
||||
dispatchEvent(evt: any): typeof this {
|
||||
var e = {
|
||||
target: this,
|
||||
type: evt.type,
|
||||
@ -796,19 +792,23 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
this.fire(evt.type, e);
|
||||
return this;
|
||||
}
|
||||
addEventListener(type: string, handler: (e: Event) => void) {
|
||||
addEventListener(type: string, handler: (e: Event) => void): typeof this {
|
||||
// we have to pass native event to handler
|
||||
this.on(type, function (evt) {
|
||||
handler.call(this, evt.evt);
|
||||
});
|
||||
return this;
|
||||
}
|
||||
removeEventListener(type: string) {
|
||||
removeEventListener(type: string): typeof this {
|
||||
this.off(type);
|
||||
return this;
|
||||
}
|
||||
// like node.on
|
||||
_delegate(event: string, selector: string, handler: (e: Event) => void) {
|
||||
_delegate(
|
||||
event: string,
|
||||
selector: string,
|
||||
handler: (e: Event) => void
|
||||
): void {
|
||||
var stopNode = this;
|
||||
this.on(event, function (evt) {
|
||||
var targets = evt.target.findAncestors(selector, true, stopNode);
|
||||
@ -827,7 +827,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* @example
|
||||
* node.remove();
|
||||
*/
|
||||
remove() {
|
||||
remove(): typeof this {
|
||||
if (this.isDragging()) {
|
||||
this.stopDrag();
|
||||
}
|
||||
@ -837,7 +837,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
this._remove();
|
||||
return this;
|
||||
}
|
||||
_clearCaches() {
|
||||
_clearCaches(): void {
|
||||
this._clearSelfAndDescendantCache(ABSOLUTE_TRANSFORM);
|
||||
this._clearSelfAndDescendantCache(ABSOLUTE_OPACITY);
|
||||
this._clearSelfAndDescendantCache(ABSOLUTE_SCALE);
|
||||
@ -845,7 +845,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
this._clearSelfAndDescendantCache(VISIBLE);
|
||||
this._clearSelfAndDescendantCache(LISTENING);
|
||||
}
|
||||
_remove() {
|
||||
_remove(): void {
|
||||
// every cached attr that is calculated via node tree
|
||||
// traversal must be cleared when removing a node
|
||||
this._clearCaches();
|
||||
@ -898,9 +898,9 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* console.log(node.getId());
|
||||
* })
|
||||
*/
|
||||
getAncestors() {
|
||||
getAncestors(): Container[] {
|
||||
var parent = this.getParent(),
|
||||
ancestors: Array<Node> = [];
|
||||
ancestors: Array<Container> = [];
|
||||
|
||||
while (parent) {
|
||||
ancestors.push(parent);
|
||||
@ -915,8 +915,8 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* @name Konva.Node#getAttrs
|
||||
* @returns {Object}
|
||||
*/
|
||||
getAttrs() {
|
||||
return (this.attrs || {}) as Config & Record<string, any>;
|
||||
getAttrs(): Partial<Config> {
|
||||
return this.attrs || {};
|
||||
}
|
||||
/**
|
||||
* set multiple attrs at once using an object literal
|
||||
@ -930,7 +930,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* fill: 'red'
|
||||
* });
|
||||
*/
|
||||
setAttrs(config: any) {
|
||||
setAttrs(config?: Partial<Config>) {
|
||||
this._batchTransformChanges(() => {
|
||||
var key, method;
|
||||
if (!config) {
|
||||
@ -1125,7 +1125,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
// like node.position(pos)
|
||||
// for performance reasons, lets batch transform reset
|
||||
// so it work faster
|
||||
_batchTransformChanges(func) {
|
||||
_batchTransformChanges(func: () => void): void {
|
||||
this._batchingTransformChange = true;
|
||||
func();
|
||||
this._batchingTransformChange = false;
|
||||
@ -1136,14 +1136,14 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
this._needClearTransformCache = false;
|
||||
}
|
||||
|
||||
setPosition(pos: Vector2d) {
|
||||
setPosition(pos: Vector2d): typeof this {
|
||||
this._batchTransformChanges(() => {
|
||||
this.x(pos.x);
|
||||
this.y(pos.y);
|
||||
});
|
||||
return this;
|
||||
}
|
||||
getPosition() {
|
||||
getPosition(): Vector2d {
|
||||
return {
|
||||
x: this.x(),
|
||||
y: this.y(),
|
||||
@ -1161,7 +1161,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* // if you want to know position of the click, related to the rectangle you can use
|
||||
* rect.getRelativePointerPosition();
|
||||
*/
|
||||
getRelativePointerPosition() {
|
||||
getRelativePointerPosition(): Vector2d | null {
|
||||
const stage = this.getStage();
|
||||
if (!stage) {
|
||||
return null;
|
||||
@ -1192,7 +1192,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* // so stage transforms are ignored
|
||||
* node.getAbsolutePosition(stage)
|
||||
*/
|
||||
getAbsolutePosition(top?: Node) {
|
||||
getAbsolutePosition(top?: Node): Vector2d {
|
||||
let haveCachedParent = false;
|
||||
let parent = this.parent;
|
||||
while (parent) {
|
||||
@ -1217,7 +1217,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
|
||||
return absoluteTransform.getTranslation();
|
||||
}
|
||||
setAbsolutePosition(pos: Vector2d) {
|
||||
setAbsolutePosition(pos: Vector2d): typeof this {
|
||||
const { x, y, ...origTrans } = this._clearTransform();
|
||||
|
||||
// don't clear translation
|
||||
@ -1241,7 +1241,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
|
||||
return this;
|
||||
}
|
||||
_setTransform(trans) {
|
||||
_setTransform(trans): void {
|
||||
var key;
|
||||
|
||||
for (key in trans) {
|
||||
@ -1291,7 +1291,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* y: 2
|
||||
* });
|
||||
*/
|
||||
move(change: Vector2d) {
|
||||
move(change: Vector2d): typeof this {
|
||||
var changeX = change.x,
|
||||
changeY = change.y,
|
||||
x = this.x(),
|
||||
@ -1308,7 +1308,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
this.setPosition({ x: x, y: y });
|
||||
return this;
|
||||
}
|
||||
_eachAncestorReverse(func, top) {
|
||||
_eachAncestorReverse(func: (node: Node) => void, top?: Node): void {
|
||||
var family: Array<Node> = [],
|
||||
parent = this.getParent(),
|
||||
len,
|
||||
@ -1341,7 +1341,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* @param {Number} theta
|
||||
* @returns {Konva.Node}
|
||||
*/
|
||||
rotate(theta: number) {
|
||||
rotate(theta: number): typeof this {
|
||||
this.rotation(this.rotation() + theta);
|
||||
return this;
|
||||
}
|
||||
@ -1413,7 +1413,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* @name Konva.Node#moveToBottom
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
moveToBottom() {
|
||||
moveToBottom(): boolean {
|
||||
if (!this.parent) {
|
||||
Util.warn('Node has no parent. moveToBottom function is ignored.');
|
||||
return false;
|
||||
@ -1427,7 +1427,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
setZIndex(zIndex) {
|
||||
setZIndex(zIndex: number): typeof this {
|
||||
if (!this.parent) {
|
||||
Util.warn('Node has no parent. zIndex parameter is ignored.');
|
||||
return this;
|
||||
@ -1453,10 +1453,10 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* @name Konva.Node#getAbsoluteOpacity
|
||||
* @returns {Number}
|
||||
*/
|
||||
getAbsoluteOpacity() {
|
||||
getAbsoluteOpacity(): number {
|
||||
return this._getCache(ABSOLUTE_OPACITY, this._getAbsoluteOpacity);
|
||||
}
|
||||
_getAbsoluteOpacity() {
|
||||
_getAbsoluteOpacity(): number {
|
||||
var absOpacity = this.opacity();
|
||||
var parent = this.getParent();
|
||||
if (parent && !parent._isUnderCache) {
|
||||
@ -1474,7 +1474,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* // move node from current layer into layer2
|
||||
* node.moveTo(layer2);
|
||||
*/
|
||||
moveTo(newContainer: any) {
|
||||
moveTo(newContainer: Container): typeof this {
|
||||
// do nothing if new container is already parent
|
||||
if (this.getParent() !== newContainer) {
|
||||
this._remove();
|
||||
@ -1533,7 +1533,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* @name Konva.Node#toJSON
|
||||
* @returns {String}
|
||||
*/
|
||||
toJSON() {
|
||||
toJSON(): string {
|
||||
return JSON.stringify(this.toObject());
|
||||
}
|
||||
/**
|
||||
@ -1542,7 +1542,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* @name Konva.Node#getParent
|
||||
* @returns {Konva.Node}
|
||||
*/
|
||||
getParent() {
|
||||
getParent(): Container | null {
|
||||
return this.parent;
|
||||
}
|
||||
/**
|
||||
@ -1561,7 +1561,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
selector: string | Function,
|
||||
includeSelf?: boolean,
|
||||
stopNode?: Node
|
||||
) {
|
||||
): Node[] {
|
||||
var res: Array<Node> = [];
|
||||
|
||||
if (includeSelf && this._isMatch(selector)) {
|
||||
@ -1598,11 +1598,11 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
selector: string | Function,
|
||||
includeSelf?: boolean,
|
||||
stopNode?: Container
|
||||
) {
|
||||
): Node | undefined {
|
||||
return this.findAncestors(selector, includeSelf, stopNode)[0];
|
||||
}
|
||||
// is current node match passed selector?
|
||||
_isMatch(selector: string | Function) {
|
||||
_isMatch(selector: string | Function): boolean {
|
||||
if (!selector) {
|
||||
return false;
|
||||
}
|
||||
@ -1663,7 +1663,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
return this._getCache(STAGE, this._getStage);
|
||||
}
|
||||
|
||||
_getStage() {
|
||||
_getStage(): Stage | null {
|
||||
var parent = this.getParent();
|
||||
if (parent) {
|
||||
return parent.getStage();
|
||||
@ -1695,7 +1695,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* // fire click event that bubbles
|
||||
* node.fire('click', null, true);
|
||||
*/
|
||||
fire(eventType: string, evt: any = {}, bubble?: boolean) {
|
||||
fire(eventType: string, evt: any = {}, bubble?: boolean): typeof this {
|
||||
evt.target = evt.target || this;
|
||||
// bubble
|
||||
if (bubble) {
|
||||
@ -1713,19 +1713,16 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* @name Konva.Node#getAbsoluteTransform
|
||||
* @returns {Konva.Transform}
|
||||
*/
|
||||
getAbsoluteTransform(top?: Node | null) {
|
||||
getAbsoluteTransform(top?: Node | null): Transform {
|
||||
// if using an argument, we can't cache the result.
|
||||
if (top) {
|
||||
return this._getAbsoluteTransform(top);
|
||||
} else {
|
||||
// if no argument, we can cache the result
|
||||
return this._getCache(
|
||||
ABSOLUTE_TRANSFORM,
|
||||
this._getAbsoluteTransform
|
||||
) as Transform;
|
||||
return this._getCache(ABSOLUTE_TRANSFORM, this._getAbsoluteTransform);
|
||||
}
|
||||
}
|
||||
_getAbsoluteTransform(top?: Node) {
|
||||
_getAbsoluteTransform(top?: Node): Transform {
|
||||
var at: Transform;
|
||||
// we we need position relative to an ancestor, we will iterate for all
|
||||
if (top) {
|
||||
@ -1776,7 +1773,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* // get absolute scale x
|
||||
* var scaleX = node.getAbsoluteScale().x;
|
||||
*/
|
||||
getAbsoluteScale(top?: Node) {
|
||||
getAbsoluteScale(top?: Node): Vector2d {
|
||||
// do not cache this calculations,
|
||||
// because it use cache transform
|
||||
// this is special logic for caching with some shapes with shadow
|
||||
@ -1806,7 +1803,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* // get absolute rotation
|
||||
* var rotation = node.getAbsoluteRotation();
|
||||
*/
|
||||
getAbsoluteRotation() {
|
||||
getAbsoluteRotation(): number {
|
||||
// var parent: Node = this;
|
||||
// var rotation = 0;
|
||||
|
||||
@ -1823,8 +1820,8 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* @name Konva.Node#getTransform
|
||||
* @returns {Konva.Transform}
|
||||
*/
|
||||
getTransform() {
|
||||
return this._getCache(TRANSFORM, this._getTransform) as Transform;
|
||||
getTransform(): Transform {
|
||||
return this._getCache(TRANSFORM, this._getTransform);
|
||||
}
|
||||
_getTransform(): Transform {
|
||||
var m: Transform = this._cache.get(TRANSFORM) || new Transform();
|
||||
@ -1915,7 +1912,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
}
|
||||
return node;
|
||||
}
|
||||
_toKonvaCanvas(config) {
|
||||
_toKonvaCanvas(config?: ToCanvasConfig): SceneCanvas {
|
||||
config = config || {};
|
||||
|
||||
var box = this.getClientRect();
|
||||
@ -1976,7 +1973,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* @example
|
||||
* var canvas = node.toCanvas();
|
||||
*/
|
||||
toCanvas(config?) {
|
||||
toCanvas(config?: ToCanvasConfig): HTMLCanvasElement {
|
||||
return this._toKonvaCanvas(config)._canvas;
|
||||
}
|
||||
/**
|
||||
@ -2002,16 +1999,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* @param {Boolean} [config.imageSmoothingEnabled] set this to false if you want to disable imageSmoothing
|
||||
* @returns {String}
|
||||
*/
|
||||
toDataURL(config?: {
|
||||
x?: number;
|
||||
y?: number;
|
||||
width?: number;
|
||||
height?: number;
|
||||
pixelRatio?: number;
|
||||
mimeType?: string;
|
||||
quality?: number;
|
||||
callback?: (str: string) => void;
|
||||
}) {
|
||||
toDataURL(config?: ToDataURLConfig): string {
|
||||
config = config || {};
|
||||
var mimeType = config.mimeType || null,
|
||||
quality = config.quality || null;
|
||||
@ -2052,16 +2040,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* }
|
||||
* });
|
||||
*/
|
||||
toImage(config?: {
|
||||
x?: number;
|
||||
y?: number;
|
||||
width?: number;
|
||||
height?: number;
|
||||
pixelRatio?: number;
|
||||
mimeType?: string;
|
||||
quality?: number;
|
||||
callback?: (img: HTMLImageElement) => void;
|
||||
}) {
|
||||
toImage(config?: ToImageConfig): Promise<HTMLImageElement> {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const callback = config?.callback;
|
||||
@ -2096,16 +2075,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* var blob = await node.toBlob({});
|
||||
* @returns {Promise<Blob>}
|
||||
*/
|
||||
toBlob(config?: {
|
||||
x?: number;
|
||||
y?: number;
|
||||
width?: number;
|
||||
height?: number;
|
||||
pixelRatio?: number;
|
||||
mimeType?: string;
|
||||
quality?: number;
|
||||
callback?: (blob: Blob | null) => void;
|
||||
}) {
|
||||
toBlob(config?: ToBlobConfig): Promise<Blob | null> {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const callback = config?.callback;
|
||||
@ -2123,12 +2093,12 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
}
|
||||
});
|
||||
}
|
||||
setSize(size) {
|
||||
setSize(size: IRect): typeof this {
|
||||
this.width(size.width);
|
||||
this.height(size.height);
|
||||
return this;
|
||||
}
|
||||
getSize() {
|
||||
getSize(): Size {
|
||||
return {
|
||||
width: this.width(),
|
||||
height: this.height(),
|
||||
@ -2140,7 +2110,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* @name Konva.Node#getClassName
|
||||
* @returns {String}
|
||||
*/
|
||||
getClassName() {
|
||||
getClassName(): string {
|
||||
return this.className || this.nodeType;
|
||||
}
|
||||
/**
|
||||
@ -2149,7 +2119,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* @name Konva.Node#getType
|
||||
* @returns {String}
|
||||
*/
|
||||
getType() {
|
||||
getType(): string {
|
||||
return this.nodeType;
|
||||
}
|
||||
getDragDistance(): number {
|
||||
@ -2162,7 +2132,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
return Konva.dragDistance;
|
||||
}
|
||||
}
|
||||
_off(type, name?, callback?) {
|
||||
_off(type, name?, callback?): void {
|
||||
var evtListeners = this.eventListeners[type],
|
||||
i,
|
||||
evtName,
|
||||
@ -2190,7 +2160,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
}
|
||||
}
|
||||
}
|
||||
_fireChangeEvent(attr, oldVal, newVal) {
|
||||
_fireChangeEvent(attr, oldVal, newVal): void {
|
||||
this._fire(attr + CHANGE, {
|
||||
oldVal: oldVal,
|
||||
newVal: newVal,
|
||||
@ -2207,7 +2177,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* node.addName('selected');
|
||||
* node.name(); // return 'red selected'
|
||||
*/
|
||||
addName(name) {
|
||||
addName(name: string): typeof this {
|
||||
if (!this.hasName(name)) {
|
||||
var oldName = this.name();
|
||||
var newName = oldName ? oldName + ' ' + name : name;
|
||||
@ -2227,7 +2197,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* node.hasName('selected'); // return false
|
||||
* node.hasName(''); // return false
|
||||
*/
|
||||
hasName(name) {
|
||||
hasName(name: string): boolean {
|
||||
if (!name) {
|
||||
return false;
|
||||
}
|
||||
@ -2251,7 +2221,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* node.hasName('selected'); // return false
|
||||
* node.name(); // return 'red'
|
||||
*/
|
||||
removeName(name) {
|
||||
removeName(name: string): typeof this {
|
||||
var names = (this.name() || '').split(/\s/g);
|
||||
var index = names.indexOf(name);
|
||||
if (index !== -1) {
|
||||
@ -2270,7 +2240,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* @example
|
||||
* node.setAttr('x', 5);
|
||||
*/
|
||||
setAttr(attr, val) {
|
||||
setAttr(attr: string, val: any): typeof this {
|
||||
var func = this[SET + Util._capitalize(attr)];
|
||||
|
||||
if (Util._isFunction(func)) {
|
||||
@ -2281,13 +2251,13 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
}
|
||||
return this;
|
||||
}
|
||||
_requestDraw() {
|
||||
_requestDraw(): void {
|
||||
if (Konva.autoDrawEnabled) {
|
||||
const drawNode = this.getLayer() || this.getStage();
|
||||
drawNode?.batchDraw();
|
||||
}
|
||||
}
|
||||
_setAttr(key, val) {
|
||||
_setAttr(key: string, val: any): void {
|
||||
var oldVal = this.attrs[key];
|
||||
if (oldVal === val && !Util.isObject(val)) {
|
||||
return;
|
||||
@ -2302,7 +2272,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
}
|
||||
this._requestDraw();
|
||||
}
|
||||
_setComponentAttr(key, component, val) {
|
||||
_setComponentAttr(key: string, component: string, val: any): void {
|
||||
var oldVal;
|
||||
if (val !== undefined) {
|
||||
oldVal = this.attrs[key];
|
||||
@ -2316,7 +2286,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
this._fireChangeEvent(key, oldVal, val);
|
||||
}
|
||||
}
|
||||
_fireAndBubble(eventType, evt, compareShape?) {
|
||||
_fireAndBubble(eventType, evt, compareShape?): void {
|
||||
if (evt && this.nodeType === SHAPE) {
|
||||
evt.target = this;
|
||||
}
|
||||
@ -2372,7 +2342,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
|
||||
return events;
|
||||
}
|
||||
_fire(eventType, evt) {
|
||||
_fire(eventType, evt): void {
|
||||
evt = evt || {};
|
||||
evt.currentTarget = this;
|
||||
evt.type = eventType;
|
||||
@ -2399,14 +2369,14 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* @name Konva.Node#draw
|
||||
* @returns {Konva.Node}
|
||||
*/
|
||||
draw() {
|
||||
draw(): typeof this {
|
||||
this.drawScene();
|
||||
this.drawHit();
|
||||
return this;
|
||||
}
|
||||
|
||||
// drag & drop
|
||||
_createDragElement(evt) {
|
||||
_createDragElement(evt): void {
|
||||
var pointerId = evt ? evt.pointerId : undefined;
|
||||
var stage = this.getStage();
|
||||
var ap = this.getAbsolutePosition();
|
||||
@ -2434,7 +2404,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* @method
|
||||
* @name Konva.Node#startDrag
|
||||
*/
|
||||
startDrag(evt?: any, bubbleEvent = true) {
|
||||
startDrag(evt?: any, bubbleEvent = true): void {
|
||||
if (!DD._dragElements.has(this._id)) {
|
||||
this._createDragElement(evt);
|
||||
}
|
||||
@ -2452,7 +2422,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
);
|
||||
}
|
||||
|
||||
_setDragPosition(evt, elem) {
|
||||
_setDragPosition(evt, elem): void {
|
||||
// const pointers = this.getStage().getPointersPositions();
|
||||
// const pos = pointers.find(p => p.id === this._dragEventId);
|
||||
const pos = this.getStage()!._getPointerById(elem.pointerId);
|
||||
@ -2494,7 +2464,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* @method
|
||||
* @name Konva.Node#stopDrag
|
||||
*/
|
||||
stopDrag(evt?) {
|
||||
stopDrag(evt?): void {
|
||||
const elem = DD._dragElements.get(this._id);
|
||||
if (elem) {
|
||||
elem.dragStatus = 'stopped';
|
||||
@ -2503,7 +2473,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
DD._endDragAfter(evt);
|
||||
}
|
||||
|
||||
setDraggable(draggable) {
|
||||
setDraggable(draggable): void {
|
||||
this._setAttr('draggable', draggable);
|
||||
this._dragChange();
|
||||
}
|
||||
@ -2513,12 +2483,12 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* @method
|
||||
* @name Konva.Node#isDragging
|
||||
*/
|
||||
isDragging() {
|
||||
isDragging(): boolean {
|
||||
const elem = DD._dragElements.get(this._id);
|
||||
return elem ? elem.dragStatus === 'dragging' : false;
|
||||
}
|
||||
|
||||
_listenDrag() {
|
||||
_listenDrag(): void {
|
||||
this._dragCleanup();
|
||||
|
||||
this.on('mousedown.konva touchstart.konva', function (evt) {
|
||||
@ -2546,7 +2516,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
});
|
||||
}
|
||||
|
||||
_dragChange() {
|
||||
_dragChange(): void {
|
||||
if (this.attrs.draggable) {
|
||||
this._listenDrag();
|
||||
} else {
|
||||
@ -2574,7 +2544,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
}
|
||||
}
|
||||
|
||||
_dragCleanup() {
|
||||
_dragCleanup(): void {
|
||||
this.off('mousedown.konva');
|
||||
this.off('touchstart.konva');
|
||||
}
|
||||
|
147
src/types.ts
147
src/types.ts
@ -1,3 +1,5 @@
|
||||
import type { Container } from './Container';
|
||||
|
||||
export interface GetSet<Type, This> {
|
||||
(): Type;
|
||||
(v: Type): This;
|
||||
@ -82,3 +84,148 @@ export interface RGB {
|
||||
export interface RGBA extends RGB {
|
||||
a: number;
|
||||
}
|
||||
|
||||
export interface Size {
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
export interface ToCanvasConfig {
|
||||
/**
|
||||
* The x coordinate of the canvas section to be exported.
|
||||
* If omitted, the x coordinate of the node's rect will be used.
|
||||
*/
|
||||
x?: number;
|
||||
/**
|
||||
* The y coordinate of the canvas section to be exported.
|
||||
* If omitted, the y coordinate of the node's rect will be used.
|
||||
*/
|
||||
y?: number;
|
||||
/**
|
||||
* The width of the canvas section to be exported.
|
||||
* If omitted, the width of the node's rect will be used.
|
||||
*/
|
||||
width?: number;
|
||||
/**
|
||||
* The height of the canvas section to be exported.
|
||||
* If omitted, the height of the node's rect will be used.
|
||||
*/
|
||||
height?: number;
|
||||
/**
|
||||
* The pixel ratio of the of output image.
|
||||
*
|
||||
* Use this property to increase resolution of the output image. For example, you may wish to increase the pixel ratio
|
||||
* to support high resolution (retina) displays.
|
||||
*
|
||||
* `pixelRatio` will be used to multiply the size of exported image. For example, if you export a 500x500 section of the canvas
|
||||
* with `pixelRatio: 2, the exported image will be 1000x1000.
|
||||
* @default 1
|
||||
*/
|
||||
pixelRatio?: number;
|
||||
/**
|
||||
* Whether to enable image smoothing.
|
||||
* @default true
|
||||
*/
|
||||
imageSmoothingEnabled?: boolean;
|
||||
}
|
||||
|
||||
export type MIMEType = 'image/jpeg' | 'image/png' | 'image/webp';
|
||||
|
||||
interface MIMETypeConfig {
|
||||
/**
|
||||
* The MIME type of the exported image. Default is `image/png`.
|
||||
*
|
||||
* Browsers may support different MIME types. For example, Firefox and Chromium-based browsers support `image/webp`
|
||||
* and `image/jpeg` in addition to `image/png`, while Safari supports only `image/png` and `image/jpeg`.
|
||||
*
|
||||
* See: https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL#browser_compatibility.
|
||||
* @default 'image/png'
|
||||
*/
|
||||
mimeType?: MIMEType;
|
||||
}
|
||||
|
||||
interface QualityConfig {
|
||||
/**
|
||||
* The quality of the exported image. Values from 0 to 1 are supported, where 0 is poorest quality and 1 is best quality.
|
||||
*
|
||||
* This only applies to `image/jpeg` and `image/webp` MIME types, which are lossy formats and support quality settings.
|
||||
* @default 1
|
||||
*/
|
||||
quality?: number;
|
||||
}
|
||||
|
||||
export interface ToDataURLConfig
|
||||
extends ToCanvasConfig,
|
||||
MIMETypeConfig,
|
||||
QualityConfig {
|
||||
/**
|
||||
* A callback function that will be called with the data URL of the exported image.
|
||||
* @param dataURL The data URL of the exported image.
|
||||
* @returns void
|
||||
*/
|
||||
callback?: (dataURL: string) => void;
|
||||
}
|
||||
|
||||
export interface ToImageConfig
|
||||
extends ToCanvasConfig,
|
||||
MIMETypeConfig,
|
||||
QualityConfig {
|
||||
/**
|
||||
* A callback function that will be called with the exported image element.
|
||||
* @param image The exported image element.
|
||||
* @returns void
|
||||
*/
|
||||
callback?: (image: HTMLImageElement) => void;
|
||||
}
|
||||
|
||||
export interface ToBlobConfig
|
||||
extends ToCanvasConfig,
|
||||
MIMETypeConfig,
|
||||
QualityConfig {
|
||||
/**
|
||||
* A callback function that will be called with the exported blob.
|
||||
* @param blob The exported blob, or null if the browser was unable to create the blob for any reason.
|
||||
* @returns void
|
||||
*/
|
||||
callback?: (blob: Blob | null) => void;
|
||||
}
|
||||
|
||||
export interface CacheConfig extends ToCanvasConfig {
|
||||
/**
|
||||
* When set to `true`, a red border will be drawn around the cached region. Used for debugging.
|
||||
* @default false
|
||||
*/
|
||||
drawBorder?: boolean;
|
||||
/**
|
||||
* Increases the size of the cached region by the specified amount of pixels in each direction.
|
||||
* @default 0
|
||||
*/
|
||||
offset?: number;
|
||||
/**
|
||||
* The pixel ratio of the cached hit canvas. Lower pixel ratios can result in better performance, but less accurate hit detection.
|
||||
* @default 1
|
||||
*/
|
||||
hitCanvasPixelRatio?: number;
|
||||
}
|
||||
|
||||
export interface GetClientRectConfig {
|
||||
/**
|
||||
* Whether to apply the current node's transforms when calculating the client rect.
|
||||
* @default false
|
||||
*/
|
||||
skipTransform?: boolean;
|
||||
/**
|
||||
* Whether to apply shadow to the node when calculating the client rect.
|
||||
* @default false
|
||||
*/
|
||||
skipShadow?: boolean;
|
||||
/**
|
||||
* Whether to apply stroke to the node when calculating the client rect.
|
||||
* @default false
|
||||
*/
|
||||
skipStroke?: boolean;
|
||||
/**
|
||||
* If provided, the client rect will be calculated relative to the specified container. Must be a parent of the node.
|
||||
*/
|
||||
relativeTo?: Container;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user