Skip to content

Commit 2f35272

Browse files
committed
Merge branch 'master' of github.com:konvajs/konva
2 parents 5ca3005 + c7d4796 commit 2f35272

File tree

13 files changed

+72
-67
lines changed

13 files changed

+72
-67
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ types
2020
out.png
2121
cmj
2222
.test-temp
23+
.history
2324

2425
# Numerous always-ignore extensions
2526
*.diff

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<p align="center">
2-
<img src="https://konvajs.org/android-chrome-192x192.png" alt="Konva logo" height="180" />
2+
<img src="https://konvajs.org/img/icon.png" alt="Konva logo" height="60" />
33
</p>
44

55
<h1 align="center">Konva</h1>

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,13 @@
4444
"test": "npm run test:browser && npm run test:node && npm run test:import",
4545
"test:build": "PARCEL_WORKER_BACKEND=process parcel build ./test/unit-tests.html --dist-dir ./test-build --target none --public-url ./ --no-source-maps",
4646
"test:browser": "npm run test:build && mocha-headless-chrome -f ./test-build/unit-tests.html -a disable-web-security -a no-sandbox -a disable-setuid-sandbox",
47-
"test:watch": "rm -rf ./.parcel-cache && PARCEL_WORKERS=0 parcel serve ./test/unit-tests.html ./test/manual-tests.html ./test/sandbox.html ./test/text-paths.html ./test/bunnies.html",
47+
"test:watch": "rimraf ./.parcel-cache && PARCEL_WORKERS=0 parcel serve ./test/unit-tests.html ./test/manual-tests.html ./test/sandbox.html ./test/text-paths.html ./test/bunnies.html",
4848
"test:node:canvas": "mocha -r tsx -r ./test/node-canvas-global-setup.mjs --extension ts --recursive './test/unit/' --exit",
4949
"test:node:skia": "mocha -r tsx -r ./test/node-skia-global-setup.mjs --extension ts --recursive './test/unit/' --exit",
5050
"test:node": "npm run test:node:canvas && npm run test:node:skia",
5151
"tsc": "tsc --removeComments",
5252
"rollup": "rollup -c",
53-
"clean": "rm -rf ./lib && rm -rf ./types && rm -rf ./cmj && rm -rf ./test-build",
53+
"clean": "rimraf ./lib && rimraf ./types && rimraf ./cmj && rimraf ./test-build",
5454
"watch": "rollup -c -w",
5555
"size": "size-limit"
5656
},
@@ -107,6 +107,7 @@
107107
"parcel": "2.15.4",
108108
"prettier": "^3.6.2",
109109
"process": "^0.11.10",
110+
"rimraf": "^6.0.1",
110111
"rollup": "^4.48.0",
111112
"rollup-plugin-typescript2": "^0.36.0",
112113
"size-limit": "^11.2.0",

src/Container.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ export interface ContainerConfig extends NodeConfig {
3232
*/
3333
export abstract class Container<
3434
ChildType extends Node = Node,
35-
> extends Node<ContainerConfig> {
35+
Config extends ContainerConfig = ContainerConfig
36+
> extends Node<Config> {
3637
children: Array<ChildType> = [];
3738

3839
/**

src/Global.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ export const Konva = {
196196
_injectGlobal(Konva) {
197197
if (typeof glob.Konva !== 'undefined') {
198198
console.error(
199-
'Severa Konva instances detected. It is not recommended to use multiple Konva instances in the same environment.'
199+
'Several Konva instances detected. It is not recommended to use multiple Konva instances in the same environment.'
200200
);
201201
}
202202
glob.Konva = Konva;

src/Node.ts

Lines changed: 51 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import type { Layer } from './Layer.ts';
1010
import type { Shape } from './Shape.ts';
1111
import type { Stage } from './Stage.ts';
1212
import type { GetSet, IRect, Vector2d } from './types.ts';
13-
import { Transform, Util } from './Util.ts';
13+
import { Transform, Util, type AnyString } from './Util.ts';
1414
import {
1515
getBooleanValidator,
1616
getNumberValidator,
@@ -134,9 +134,8 @@ type globalCompositeOperationType =
134134
| 'color'
135135
| 'luminosity';
136136

137-
export interface NodeConfig {
138-
// allow any custom attribute
139-
[index: string]: any;
137+
// allow any custom attribute
138+
export type NodeConfig<Props extends Record<string, any> = {}> = Props & {
140139
x?: number;
141140
y?: number;
142141
width?: number;
@@ -223,6 +222,20 @@ export type KonvaEventListener<This, EventType> = (
223222
ev: KonvaEventObject<EventType, This>
224223
) => void;
225224

225+
export type CanvasConfig = {
226+
x?: number;
227+
y?: number;
228+
width?: number;
229+
height?: number;
230+
pixelRatio?: number;
231+
imageSmoothingEnabled?: boolean;
232+
};
233+
234+
export type ImageConfig = CanvasConfig & {
235+
mimeType?: string;
236+
quality?: number;
237+
};
238+
226239
/**
227240
* Node constructor. Nodes are entities that can be transformed, layered,
228241
* and have bound events. The stage, layers, groups, and shapes all extend Node.
@@ -393,17 +406,13 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
393406
* drawBorder: true
394407
* });
395408
*/
396-
cache(config?: {
397-
x?: number;
398-
y?: number;
399-
width?: number;
400-
height?: number;
401-
drawBorder?: boolean;
402-
offset?: number;
403-
pixelRatio?: number;
404-
imageSmoothingEnabled?: boolean;
405-
hitCanvasPixelRatio?: number;
406-
}) {
409+
cache(
410+
config?: CanvasConfig & {
411+
drawBorder?: boolean;
412+
offset?: number;
413+
hitCanvasPixelRatio?: number;
414+
}
415+
) {
407416
const conf = config || {};
408417
let rect = {} as IRect;
409418

@@ -1015,13 +1024,13 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
10151024
* @example
10161025
* var x = node.getAttr('x');
10171026
*/
1018-
getAttr<T>(attr: string) {
1019-
const method = 'get' + Util._capitalize(attr);
1027+
getAttr<AttrConfig extends Config, K extends AnyString<keyof Config>>(attr: K): K extends keyof AttrConfig ? AttrConfig[K] : any {
1028+
const method = 'get' + Util._capitalize(attr as string);
10201029
if (Util._isFunction((this as any)[method])) {
10211030
return (this as any)[method]();
10221031
}
10231032
// otherwise get directly
1024-
return this.attrs[attr] as T | undefined;
1033+
return this.attrs[attr];
10251034
}
10261035
/**
10271036
* get ancestors
@@ -1050,8 +1059,8 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
10501059
* @name Konva.Node#getAttrs
10511060
* @returns {Object}
10521061
*/
1053-
getAttrs() {
1054-
return (this.attrs || {}) as Config & Record<string, any>;
1062+
getAttrs(): Config {
1063+
return (this.attrs || {});
10551064
}
10561065
/**
10571066
* set multiple attrs at once using an object literal
@@ -1065,7 +1074,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
10651074
* fill: 'red'
10661075
* });
10671076
*/
1068-
setAttrs(config: any) {
1077+
setAttrs(config?: Config) {
10691078
this._batchTransformChanges(() => {
10701079
let key, method;
10711080
if (!config) {
@@ -1624,7 +1633,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
16241633
* @returns {Object}
16251634
*/
16261635
toObject() {
1627-
let attrs = this.getAttrs() as any,
1636+
let attrs = this.getAttrs(),
16281637
key,
16291638
val,
16301639
getter,
@@ -2111,7 +2120,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
21112120
* @example
21122121
* var canvas = node.toCanvas();
21132122
*/
2114-
toCanvas(config?) {
2123+
toCanvas(config?: CanvasConfig) {
21152124
return this._toKonvaCanvas(config)._canvas;
21162125
}
21172126
/**
@@ -2137,16 +2146,11 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
21372146
* @param {Boolean} [config.imageSmoothingEnabled] set this to false if you want to disable imageSmoothing
21382147
* @returns {String}
21392148
*/
2140-
toDataURL(config?: {
2141-
x?: number;
2142-
y?: number;
2143-
width?: number;
2144-
height?: number;
2145-
pixelRatio?: number;
2146-
mimeType?: string;
2147-
quality?: number;
2148-
callback?: (str: string) => void;
2149-
}) {
2149+
toDataURL(
2150+
config?: ImageConfig & {
2151+
callback?: (url: string) => void;
2152+
}
2153+
) {
21502154
config = config || {};
21512155
const mimeType = config.mimeType || null,
21522156
quality = config.quality || null;
@@ -2187,16 +2191,11 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
21872191
* }
21882192
* });
21892193
*/
2190-
toImage(config?: {
2191-
x?: number;
2192-
y?: number;
2193-
width?: number;
2194-
height?: number;
2195-
pixelRatio?: number;
2196-
mimeType?: string;
2197-
quality?: number;
2198-
callback?: (img: HTMLImageElement) => void;
2199-
}) {
2194+
toImage(
2195+
config?: ImageConfig & {
2196+
callback?: (img: HTMLImageElement) => void;
2197+
}
2198+
) {
22002199
return new Promise<HTMLImageElement>((resolve, reject) => {
22012200
try {
22022201
const callback = config?.callback;
@@ -2231,16 +2230,11 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
22312230
* var blob = await node.toBlob({});
22322231
* @returns {Promise<Blob>}
22332232
*/
2234-
toBlob(config?: {
2235-
x?: number;
2236-
y?: number;
2237-
width?: number;
2238-
height?: number;
2239-
pixelRatio?: number;
2240-
mimeType?: string;
2241-
quality?: number;
2242-
callback?: (blob: Blob | null) => void;
2243-
}) {
2233+
toBlob(
2234+
config?: ImageConfig & {
2235+
callback?: (blob: Blob | null) => void;
2236+
}
2237+
) {
22442238
return new Promise((resolve, reject) => {
22452239
try {
22462240
const callback = config?.callback;
@@ -2405,8 +2399,8 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
24052399
* @example
24062400
* node.setAttr('x', 5);
24072401
*/
2408-
setAttr(attr: string, val) {
2409-
const func = this[SET + Util._capitalize(attr)];
2402+
setAttr<AttrConfig extends Config, K extends AnyString<keyof Config>>(attr: K, val: K extends keyof AttrConfig ? AttrConfig[K] : any) {
2403+
const func = this[SET + Util._capitalize(attr as string)];
24102404

24112405
if (Util._isFunction(func)) {
24122406
func.call(this, val);
@@ -2422,7 +2416,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
24222416
drawNode?.batchDraw();
24232417
}
24242418
}
2425-
_setAttr(key: string, val) {
2419+
_setAttr<AttrConfig extends Config, K extends AnyString<keyof Config>>(key: K, val: K extends keyof AttrConfig ? AttrConfig[K] : any) {
24262420
const oldVal = this.attrs[key];
24272421
if (oldVal === val && !Util.isObject(val)) {
24282422
return;
@@ -2878,7 +2872,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
28782872
}
28792873
}
28802874

2881-
interface AnimTo extends NodeConfig {
2875+
interface AnimTo extends NodeConfig<Record<string, any>> {
28822876
onFinish?: Function;
28832877
onUpdate?: Function;
28842878
duration?: number;

src/Shape.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export type ShapeConfigHandler<TTarget> = {
2626
export type LineJoin = 'round' | 'bevel' | 'miter';
2727
export type LineCap = 'butt' | 'round' | 'square';
2828

29-
export interface ShapeConfig extends NodeConfig {
29+
export type ShapeConfig<Props extends Record<string, any> = {}> = NodeConfig<Props> & {
3030
fill?: string | CanvasGradient;
3131
fillPatternImage?: HTMLImageElement;
3232
fillPatternX?: number;

src/Stage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ export const stages: Stage[] = [];
154154
* });
155155
*/
156156

157-
export class Stage extends Container<Layer> {
157+
export class Stage extends Container<Layer, StageConfig> {
158158
content: HTMLDivElement;
159159
pointerPos: Vector2d | null;
160160
_pointerPositions: (Vector2d & { id?: number })[] = [];

src/Tween.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,9 @@ class TweenEngine {
151151
}
152152

153153
export interface TweenConfig extends NodeConfig {
154+
easing?: typeof Easings[keyof typeof Easings];
155+
yoyo?: boolean;
156+
onReset?: Function;
154157
onFinish?: Function;
155158
onUpdate?: Function;
156159
duration?: number;
@@ -419,7 +422,7 @@ export class Tween {
419422
// after tweening points of line we need to set original end
420423
const attrs = Tween.attrs[node._id][this._id];
421424
if (attrs.points && attrs.points.trueEnd) {
422-
node.setAttr('points', attrs.points.trueEnd);
425+
node.setAttr('points' as any, attrs.points.trueEnd);
423426
}
424427

425428
if (this.onFinish) {

src/Util.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,3 +1121,5 @@ export const Util = {
11211121
}
11221122
},
11231123
};
1124+
1125+
export type AnyString<T> = T | (string & {})

0 commit comments

Comments
 (0)