Merge branch 'master' of github.com:konvajs/konva

This commit is contained in:
Anton Lavrevov
2025-08-23 03:18:14 -05:00
34 changed files with 705 additions and 1319 deletions

13
.github/workflows/prettier.yml vendored Normal file
View File

@@ -0,0 +1,13 @@
name: check formatting
on:
pull_request:
jobs:
fmt-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v4
with:
node-version: 'latest'
- run: npm install
- run: npm run fmt:check

View File

@@ -1413,7 +1413,6 @@ That changes are private and internal specific. They should not break most of `K
Differences from last official `KineticJS` release
- Bug Fixes
- `strokeScaleEnabled = false` is disabled for text as I can not find a way to implement this
- `strokeScaleEnabled = false` for Line now creates a correct hit graph
- working "this-example" as name for nodes

View File

@@ -35,6 +35,8 @@
"start": "npm run test:watch",
"compile": "npm run clean && npm run tsc && cp ./src/index-types.d.ts ./lib/index-types.d.ts && npm run rollup",
"build": "npm run compile && cp ./src/index-types.d.ts ./lib && gulp build && node ./rename-imports.mjs",
"fmt": "prettier --write .",
"fmt:check": "prettier --check .",
"test:import": "npm run build && node ./test/import-test.cjs && node ./test/import-test.mjs",
"test": "npm run test:browser && npm run test:node && npm run test:import",
"test:build": "PARCEL_WORKER_BACKEND=process parcel build ./test/unit-tests.html --dist-dir ./test-build --target none --public-url ./ --no-source-maps",
@@ -100,6 +102,7 @@
"mocha": "10.2.0",
"mocha-headless-chrome": "^4.0.0",
"parcel": "2.13.3",
"prettier": "^3.6.2",
"process": "^0.11.10",
"rollup": "^4.46.2",
"rollup-plugin-typescript2": "^0.36.0",
@@ -116,7 +119,8 @@
"html5"
],
"prettier": {
"singleQuote": true
"singleQuote": true,
"trailingComma": "es5"
},
"bugs": {
"url": "https://github.com/konvajs/konva/issues"

View File

@@ -1,28 +1,28 @@
{
"path" : "ink-docstrap",
"tags" : {
"allowUnknownTags" : true
"path": "ink-docstrap",
"tags": {
"allowUnknownTags": true
},
"plugins" : ["plugins/markdown"],
"plugins": ["plugins/markdown"],
"templates" : {
"cleverLinks" : false,
"monospaceLinks" : false,
"dateFormat" : "ddd MMM Do YYYY",
"outputSourceFiles" : true,
"outputSourcePath" : true,
"systemName" : "Konva",
"footer" : "",
"copyright" : "Konva Copyright © 2015 The contributors to the Konva project.",
"navType" : "vertical",
"theme" : "cosmo",
"linenums" : true,
"collapseSymbols" : false,
"inverseNav" : true,
"highlightTutorialCode" : true
"templates": {
"cleverLinks": false,
"monospaceLinks": false,
"dateFormat": "ddd MMM Do YYYY",
"outputSourceFiles": true,
"outputSourcePath": true,
"systemName": "Konva",
"footer": "",
"copyright": "Konva Copyright © 2015 The contributors to the Konva project.",
"navType": "vertical",
"theme": "cosmo",
"linenums": true,
"collapseSymbols": false,
"inverseNav": true,
"highlightTutorialCode": true
},
"markdown" : {
"parser" : "gfm",
"hardwrap" : true
"markdown": {
"parser": "gfm",
"hardwrap": true
}
}

View File

@@ -30,7 +30,7 @@ export interface ContainerConfig extends NodeConfig {
* @@containerParams
*/
export abstract class Container<
ChildType extends Node = Node
ChildType extends Node = Node,
> extends Node<ContainerConfig> {
children: Array<ChildType> = [];

View File

@@ -332,6 +332,12 @@ export class Context {
this.setAttr('lineJoin', lineJoin);
}
}
_applyMiterLimit(shape: Shape) {
const miterLimit = shape.attrs.miterLimit;
if (miterLimit != null) {
this.setAttr('miterLimit', miterLimit);
}
}
setAttr(attr: string, val) {
this._context[attr] = val;

View File

@@ -46,10 +46,8 @@ type ValidatorFunc<T> = (val: ExtractGetSet<T>, attr: string) => T;
/**
* Extracts the "components" (keys) of a GetSet value. The value must be an object.
*/
type ExtractComponents<T extends Constructor, U extends Attr<T>> = Value<
T,
U
> extends Record<string, any>
type ExtractComponents<T extends Constructor, U extends Attr<T>> =
Value<T, U> extends Record<string, any>
? EnforceString<keyof Value<T, U>>[]
: never;

View File

@@ -66,6 +66,7 @@ export interface ShapeConfig extends NodeConfig {
strokeEnabled?: boolean;
lineJoin?: LineJoin;
lineCap?: LineCap;
miterLimit?: number;
sceneFunc?: (con: Context, shape: Shape) => void;
hitFunc?: (con: Context, shape: Shape) => void;
shadowColor?: string;
@@ -187,7 +188,7 @@ function _clearRadialGradientCache(this: Node) {
*});
*/
export class Shape<
Config extends ShapeConfig = ShapeConfig
Config extends ShapeConfig = ShapeConfig,
> extends Node<Config> {
_centroid: boolean;
colorKey: string;
@@ -637,6 +638,7 @@ export class Shape<
bufferContext.clear();
bufferContext.save();
bufferContext._applyLineJoin(this);
bufferContext._applyMiterLimit(this);
// layer might be undefined if we are using cache before adding to layer
const o = this.getAbsoluteTransform(top).getMatrix();
bufferContext.transform(o[0], o[1], o[2], o[3], o[4], o[5]);
@@ -666,6 +668,7 @@ export class Shape<
);
} else {
context._applyLineJoin(this);
context._applyMiterLimit(this);
if (!cachingSelf) {
const o = this.getAbsoluteTransform(top).getMatrix();
@@ -721,6 +724,7 @@ export class Shape<
}
context.save();
context._applyLineJoin(this);
context._applyMiterLimit(this);
const selfCache = this === top;
if (!selfCache) {
@@ -839,6 +843,7 @@ export class Shape<
hitFunc: GetSet<ShapeConfigHandler<this>, this>;
lineCap: GetSet<LineCap, this>;
lineJoin: GetSet<LineJoin, this>;
miterLimit: GetSet<number, this>;
perfectDrawEnabled: GetSet<boolean, this>;
sceneFunc: GetSet<ShapeConfigHandler<this>, this>;
shadowColor: GetSet<string, this>;
@@ -1095,6 +1100,22 @@ Factory.addGetterSetter(Shape, 'lineCap');
* shape.lineCap('round');
*/
Factory.addGetterSetter(Shape, 'miterLimit');
/**
* get/set miterLimit.
* @name Konva.Shape#miterLimit
* @method
* @param {Number} miterLimit
* @returns {Number}
* @example
* // get miter limit
* var miterLimit = shape.miterLimit();
*
* // set miter limit
* shape.miterLimit(10);
*/
Factory.addGetterSetter(Shape, 'sceneFunc');
/**

View File

@@ -1088,8 +1088,8 @@ export const Util = {
const prev = points[(i - 1 + sides) % sides];
const curr = points[i];
const next = points[(i + 1) % sides];
const vec1 = {x: curr.x - prev.x, y: curr.y - prev.y};
const vec2 = {x: next.x - curr.x, y: next.y - curr.y};
const vec1 = { x: curr.x - prev.x, y: curr.y - prev.y };
const vec2 = { x: next.x - curr.x, y: next.y - curr.y };
const len1 = Math.hypot(vec1.x, vec1.y);
const len2 = Math.hypot(vec2.x, vec2.y);
let currCornerRadius;
@@ -1100,9 +1100,10 @@ export const Util = {
}
const maxCornerRadius = radius * Math.cos(Math.PI / sides);
// cornerRadius creates perfect circle at 1/2 radius
currCornerRadius = maxCornerRadius * Math.min(1, (currCornerRadius / radius) * 2);
const normalVec1 = {x: vec1.x / len1, y: vec1.y / len1};
const normalVec2 = {x: vec2.x / len2, y: vec2.y / len2};
currCornerRadius =
maxCornerRadius * Math.min(1, (currCornerRadius / radius) * 2);
const normalVec1 = { x: vec1.x / len1, y: vec1.y / len1 };
const normalVec2 = { x: vec2.x / len2, y: vec2.y / len2 };
const p1 = {
x: curr.x - normalVec1.x * currCornerRadius,
y: curr.y - normalVec1.y * currCornerRadius,
@@ -1118,5 +1119,5 @@ export const Util = {
}
context.arcTo(curr.x, curr.y, p2.x, p2.y, currCornerRadius);
}
}
},
};

View File

@@ -2,7 +2,13 @@ import { Factory } from '../Factory';
import { Node, Filter } from '../Node';
import { getNumberValidator } from '../Validators';
function remap(fromValue: number, fromMin: number, fromMax: number, toMin: number, toMax: number) {
function remap(
fromValue: number,
fromMin: number,
fromMax: number,
toMin: number,
toMax: number
) {
// Compute the range of the data
const fromRange = fromMax - fromMin,
toRange = toMax - toMin;

View File

@@ -116,7 +116,8 @@ const FromPolar = function (src, dst, opt) {
const dx = x - xMid;
const dy = y - yMid;
const radius = (Math.sqrt(dx * dx + dy * dy) * rSize) / rMax;
let theta = ((Math.atan2(dy, dx) * 180) / Math.PI + 360 + phaseShift) % 360;
let theta =
((Math.atan2(dy, dx) * 180) / Math.PI + 360 + phaseShift) % 360;
theta = (theta * tSize) / 360;
x1 = Math.floor(theta);
y1 = Math.floor(radius);

View File

@@ -97,7 +97,7 @@ export interface LineConfig extends ShapeConfig {
*/
export class Line<
Config extends LineConfig = LineConfig
Config extends LineConfig = LineConfig,
> extends Shape<Config> {
constructor(config?: Config) {
super(config);

View File

@@ -1,7 +1,10 @@
import { Factory } from '../Factory';
import { Shape, ShapeConfig } from '../Shape';
import { GetSet, Vector2d } from '../types';
import { getNumberOrArrayOfNumbersValidator, getNumberValidator } from '../Validators';
import {
getNumberOrArrayOfNumbersValidator,
getNumberValidator,
} from '../Validators';
import { _registerNode } from '../Global';
import { Context } from '../Context';
import { Util } from '../Util';

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html>
<head>
<style>

View File

@@ -1,14 +1,16 @@
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>KonvaJS Sandbox</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=1.0, minimum-scale=1.0, maximum-scale=1.0">
</head>
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, user-scalable=1.0, minimum-scale=1.0, maximum-scale=1.0"
/>
</head>
<body>
<body>
<!-- testing Konva inside iframe -->
<iframe src="./sandbox.html"></iframe>
</body>
</body>
</html>

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html>
<head>
<style>
@@ -9,7 +9,7 @@
</style>
</head>
<body>
<canvas id="canvas"></div>
<canvas id="canvas"></canvas>
<script src="http://www.html5canvastutorials.com/lib/stats/stats.js"></script>
<script defer="defer">
var lastTime = 0;
@@ -45,7 +45,7 @@
stats = new Stats();
wabbitTexture = new Image();
wabbitTexture.onload = function() {
wabbitTexture.onload = function () {
_handleTextureLoaded();
};
wabbitTexture.src = '../assets/bunny.png';
@@ -66,12 +66,11 @@
count = startBunnyCount;
counter.innerHTML = startBunnyCount + ' BUNNIES';
canvas.addEventListener('mousedown', function() {
canvas.addEventListener('mousedown', function () {
isAdding = true;
});
canvas.addEventListener('mouseup', function() {
canvas.addEventListener('mouseup', function () {
isAdding = false;
});
@@ -84,8 +83,8 @@
x: 10,
y: 10,
speedX: Math.random() * 10,
speedY: Math.random() * 10 - 5
}
speedY: Math.random() * 10 - 5,
};
bunnys.push(bunny);
}
}
@@ -108,8 +107,8 @@
x: 10,
y: 10,
speedX: Math.random() * 10,
speedY: Math.random() * 10 - 5
}
speedY: Math.random() * 10 - 5,
};
bunnys.push(bunny);
count++;
}
@@ -124,21 +123,21 @@
bunny.speedY += gravity;
if (bunny.x > maxX - wabbitTexture.width) {
bunny.speedX *= -1;
bunny.x = (maxX - wabbitTexture.width);
bunny.x = maxX - wabbitTexture.width;
} else if (bunny.x < minX) {
bunny.speedX *= -1;
bunny.x = (minX);
bunny.x = minX;
}
if (bunny.y > maxY - wabbitTexture.height) {
bunny.speedY *= -0.85;
bunny.y = (maxY - wabbitTexture.height);
bunny.y = maxY - wabbitTexture.height;
if (Math.random() > 0.5) {
bunny.speedY -= Math.random() * 6;
}
} else if (bunny.y < minY) {
bunny.speedY = 0;
bunny.y = (minY);
bunny.y = minY;
}
ctx.save();
ctx.transform(1, 0, 0, 1, bunny.x, bunny.y);
@@ -146,7 +145,6 @@
ctx.restore();
}
requestAnimationFrame(update);
stats.end();
}

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html>
<head>
<style>

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html>
<head>
<style>

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html>
<head>
<meta charset="utf-8" />

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html>
<head>
<meta charset="utf-8" />

View File

@@ -247,11 +247,10 @@ describe('Arrow', function () {
});
layer.add(arrow);
stage.add(layer);
var rect = arrow.getClientRect({ skipStroke: true });
layer.add(new Konva.Rect({...rect, stroke: 'red' }));
layer.add(new Konva.Rect({ ...rect, stroke: 'red' }));
assert.equal(rect.x, 50);
assert.equal(rect.y, 40);

View File

@@ -2605,8 +2605,10 @@ describe('Container', function () {
stage.scale({ x: 2, y: 2 });
stage.draw();
var data = layer.getHitCanvas().getContext().getImageData(48, 100, 1, 1)
.data;
var data = layer
.getHitCanvas()
.getContext()
.getImageData(48, 100, 1, 1).data;
var isTransparent = data[3] == 0;
assert.equal(
isTransparent,

View File

@@ -333,230 +333,81 @@ describe('Line', function () {
x: 0,
y: 0,
points: [
494.39880507841673,
795.3696788648244,
494.49880507841675,
795.4696788648245,
494.39880507841673,
796.8633308439133,
489.9178491411501,
798.3569828230022,
480.95593726661684,
802.8379387602688,
467.513069454817,
810.3061986557132,
451.0828976848394,
820.7617625093353,
433.15907393577294,
832.7109783420462,
415.2352501867065,
846.1538461538461,
398.8050784167289,
859.596713965646,
383.8685586258402,
871.545929798357,
374.90664675130694,
880.5078416728902,
371.9193427931292,
883.4951456310679,
371.9193427931292,
883.4951456310679,
371.9193427931292,
883.4951456310679,
376.40029873039583,
882.0014936519791,
395.8177744585511,
876.0268857356235,
443.6146377893951,
856.6094100074682,
507.84167289021656,
838.6855862584017,
551.1575802837939,
825.2427184466019,
624.3465272591486,
807.3188946975355,
696.0418222554144,
789.395070948469,
758.7752053771471,
777.445855115758,
802.0911127707244,
772.9648991784914,
820.0149365197909,
771.4712471994025,
821.5085884988797,
771.4712471994025,
820.0149365197909,
775.9522031366691,
799.1038088125466,
790.8887229275579,
743.8386855862584,
825.2427184466019,
652.7259148618372,
871.545929798357,
542.1956684092606,
926.8110530246452,
455.563853622106,
977.5952203136669,
412.24794622852875,
1010.455563853622,
397.31142643764,
1026.8857356235997,
397.31142643764,
1032.8603435399552,
400.29873039581776,
1038.8349514563106,
415.2352501867065,
1043.3159073935774,
463.0321135175504,
1043.3159073935774,
563.1067961165048,
1040.3286034353996,
696.0418222554144,
1032.8603435399552,
787.1545929798357,
1026.8857356235997,
921.5832710978342,
1017.9238237490664,
1018.6706497386109,
1013.4428678117998,
1069.4548170276325,
1013.4428678117998,
1076.923076923077,
1013.4428678117998,
1075.4294249439881,
1014.9365197908887,
1051.530993278566,
1026.8857356235997,
979.8356982823002,
1053.7714712471993,
888.722927557879,
1079.1635548917102,
761.7625093353248,
1116.504854368932,
672.1433905899925,
1150.858849887976,
628.8274831964152,
1171.7699775952203,
615.3846153846154,
1180.7318894697535,
615.3846153846154,
1182.2255414488425,
618.3719193427931,
1183.7191934279313,
633.3084391336819,
1182.2255414488425,
687.0799103808812,
1171.7699775952203,
775.2053771471248,
1150.858849887976,
902.1657953696788,
1116.504854368932,
990.2912621359224,
1091.1127707244211,
1082.8976848394325,
1062.7333831217327,
1133.681852128454,
1046.303211351755,
1144.1374159820762,
1041.8222554144884,
1144.1374159820762,
1041.8222554144884,
1141.1501120238984,
1041.8222554144884,
1117.2516803584765,
1043.3159073935774,
1082.8976848394325,
1046.303211351755,
1008.2150858849888,
1062.7333831217327,
917.1023151605675,
1092.6064227035101,
861.8371919342793,
1117.9985063480208,
814.0403286034353,
1152.352501867065,
794.62285287528,
1176.250933532487,
790.1418969380135,
1189.6938013442868,
793.1292008961912,
1198.65571321882,
802.0911127707244,
1206.1239731142643,
831.9641523525019,
1216.5795369678865,
903.6594473487677,
1225.5414488424196,
1014.1896938013442,
1228.5287528005974,
1148.6183719193427,
1228.5287528005974,
1272.591486183719,
1225.5414488424196,
1314.4137415982075,
1225.5414488424196,
1326.3629574309186,
1225.5414488424196,
1326.3629574309186,
1225.5414488424196,
1314.4137415982075,
1228.5287528005974,
1272.591486183719,
1237.4906646751306,
1197.9088872292755,
1247.9462285287527,
1105.3024645257656,
1270.3510082150858,
1048.5436893203882,
1286.7811799850635,
1024.6452576549664,
1295.7430918595967,
1006.7214339058999,
1306.1986557132188,
1000.7468259895444,
1313.6669156086632,
1000.7468259895444,
1315.160567587752,
1003.7341299477222,
1316.6542195668408,
1015.6833457804331,
1319.6415235250186,
1050.0373412994772,
1321.1351755041076,
1103.8088125466766,
1321.1351755041076,
1169.529499626587,
1316.6542195668408,
1220.3136669156086,
1310.6796116504854,
1248.6930545182972,
1307.6923076923076,
1253.1740104555638,
1307.6923076923076,
1253.1740104555638,
1307.6923076923076,
1253.1740104555638,
1307.6923076923076,
1248.6930545182972,
1309.1859596713964,
1229.275578790142,
1312.1732636295742,
1199.4025392083645,
1319.6415235250186,
1172.5168035847648,
1330.0970873786407,
1154.5929798356983,
1342.0463032113516,
1144.1374159820762,
1353.9955190440626,
1139.6564600448096,
1361.463778939507,
1138.1628080657206,
1364.4510828976847,
1138.1628080657206,
1365.9447348767737,
1138.1628080657206,
1365.9447348767737,
494.39880507841673, 795.3696788648244, 494.49880507841675,
795.4696788648245, 494.39880507841673, 796.8633308439133,
489.9178491411501, 798.3569828230022, 480.95593726661684,
802.8379387602688, 467.513069454817, 810.3061986557132,
451.0828976848394, 820.7617625093353, 433.15907393577294,
832.7109783420462, 415.2352501867065, 846.1538461538461,
398.8050784167289, 859.596713965646, 383.8685586258402,
871.545929798357, 374.90664675130694, 880.5078416728902,
371.9193427931292, 883.4951456310679, 371.9193427931292,
883.4951456310679, 371.9193427931292, 883.4951456310679,
376.40029873039583, 882.0014936519791, 395.8177744585511,
876.0268857356235, 443.6146377893951, 856.6094100074682,
507.84167289021656, 838.6855862584017, 551.1575802837939,
825.2427184466019, 624.3465272591486, 807.3188946975355,
696.0418222554144, 789.395070948469, 758.7752053771471,
777.445855115758, 802.0911127707244, 772.9648991784914,
820.0149365197909, 771.4712471994025, 821.5085884988797,
771.4712471994025, 820.0149365197909, 775.9522031366691,
799.1038088125466, 790.8887229275579, 743.8386855862584,
825.2427184466019, 652.7259148618372, 871.545929798357,
542.1956684092606, 926.8110530246452, 455.563853622106,
977.5952203136669, 412.24794622852875, 1010.455563853622,
397.31142643764, 1026.8857356235997, 397.31142643764,
1032.8603435399552, 400.29873039581776, 1038.8349514563106,
415.2352501867065, 1043.3159073935774, 463.0321135175504,
1043.3159073935774, 563.1067961165048, 1040.3286034353996,
696.0418222554144, 1032.8603435399552, 787.1545929798357,
1026.8857356235997, 921.5832710978342, 1017.9238237490664,
1018.6706497386109, 1013.4428678117998, 1069.4548170276325,
1013.4428678117998, 1076.923076923077, 1013.4428678117998,
1075.4294249439881, 1014.9365197908887, 1051.530993278566,
1026.8857356235997, 979.8356982823002, 1053.7714712471993,
888.722927557879, 1079.1635548917102, 761.7625093353248,
1116.504854368932, 672.1433905899925, 1150.858849887976,
628.8274831964152, 1171.7699775952203, 615.3846153846154,
1180.7318894697535, 615.3846153846154, 1182.2255414488425,
618.3719193427931, 1183.7191934279313, 633.3084391336819,
1182.2255414488425, 687.0799103808812, 1171.7699775952203,
775.2053771471248, 1150.858849887976, 902.1657953696788,
1116.504854368932, 990.2912621359224, 1091.1127707244211,
1082.8976848394325, 1062.7333831217327, 1133.681852128454,
1046.303211351755, 1144.1374159820762, 1041.8222554144884,
1144.1374159820762, 1041.8222554144884, 1141.1501120238984,
1041.8222554144884, 1117.2516803584765, 1043.3159073935774,
1082.8976848394325, 1046.303211351755, 1008.2150858849888,
1062.7333831217327, 917.1023151605675, 1092.6064227035101,
861.8371919342793, 1117.9985063480208, 814.0403286034353,
1152.352501867065, 794.62285287528, 1176.250933532487,
790.1418969380135, 1189.6938013442868, 793.1292008961912,
1198.65571321882, 802.0911127707244, 1206.1239731142643,
831.9641523525019, 1216.5795369678865, 903.6594473487677,
1225.5414488424196, 1014.1896938013442, 1228.5287528005974,
1148.6183719193427, 1228.5287528005974, 1272.591486183719,
1225.5414488424196, 1314.4137415982075, 1225.5414488424196,
1326.3629574309186, 1225.5414488424196, 1326.3629574309186,
1225.5414488424196, 1314.4137415982075, 1228.5287528005974,
1272.591486183719, 1237.4906646751306, 1197.9088872292755,
1247.9462285287527, 1105.3024645257656, 1270.3510082150858,
1048.5436893203882, 1286.7811799850635, 1024.6452576549664,
1295.7430918595967, 1006.7214339058999, 1306.1986557132188,
1000.7468259895444, 1313.6669156086632, 1000.7468259895444,
1315.160567587752, 1003.7341299477222, 1316.6542195668408,
1015.6833457804331, 1319.6415235250186, 1050.0373412994772,
1321.1351755041076, 1103.8088125466766, 1321.1351755041076,
1169.529499626587, 1316.6542195668408, 1220.3136669156086,
1310.6796116504854, 1248.6930545182972, 1307.6923076923076,
1253.1740104555638, 1307.6923076923076, 1253.1740104555638,
1307.6923076923076, 1253.1740104555638, 1307.6923076923076,
1248.6930545182972, 1309.1859596713964, 1229.275578790142,
1312.1732636295742, 1199.4025392083645, 1319.6415235250186,
1172.5168035847648, 1330.0970873786407, 1154.5929798356983,
1342.0463032113516, 1144.1374159820762, 1353.9955190440626,
1139.6564600448096, 1361.463778939507, 1138.1628080657206,
1364.4510828976847, 1138.1628080657206, 1365.9447348767737,
1138.1628080657206, 1365.9447348767737,
],
tension: 0.5,
stroke: '#0f0',

View File

@@ -971,6 +971,9 @@ describe('Shape', function () {
rect.strokeWidth(8);
assert.equal(rect.strokeWidth(), 8);
rect.miterLimit(5);
assert.equal(rect.miterLimit(), 5);
const f = () => {};
rect.sceneFunc(f);
assert.equal(rect.sceneFunc(), f);
@@ -2408,4 +2411,59 @@ describe('Shape', function () {
const hitShape = layer.getIntersection({ x: 150, y: 150 });
assert.equal(hitShape, null);
});
it('miterLimit with buffer canvas', function () {
var stage = addStage();
var layer = new Konva.Layer();
// Sharp triangle with opacity to force buffer canvas usage
var triangle = new Konva.Shape({
x: 100,
y: 50,
sceneFunc: function (ctx, shape) {
ctx.beginPath();
ctx.moveTo(140, 5);
ctx.lineTo(0, 70);
ctx.lineTo(220, 70);
ctx.closePath();
ctx.fillStrokeShape(shape);
},
fill: 'yellow',
stroke: 'orange',
strokeWidth: 10,
lineJoin: 'miter',
miterLimit: 3,
opacity: 0.7, // Forces buffer canvas usage
});
layer.add(triangle);
stage.add(layer);
// Create expected result using native canvas with buffer approach
var canvas = createCanvas();
var context = canvas.getContext('2d');
// Draw on buffer first
context.beginPath();
context.translate(100, 50);
context.moveTo(140, 5);
context.lineTo(0, 70);
context.lineTo(220, 70);
context.closePath();
context.fillStyle = 'yellow';
context.strokeStyle = 'orange';
context.lineWidth = 10;
context.lineJoin = 'miter';
context.miterLimit = 3;
context.fill();
context.stroke();
// Apply opacity by drawing to final canvas
var finalCanvas = createCanvas();
var finalContext = finalCanvas.getContext('2d');
finalContext.globalAlpha = 0.7;
finalContext.drawImage(canvas, 0, 0);
compareLayerAndCanvas(layer, finalCanvas, 200);
});
});

View File

@@ -16,56 +16,12 @@ describe('Sprite', function () {
animation: 'standing',
animations: {
standing: [
0,
0,
49,
109,
52,
0,
49,
109,
105,
0,
49,
109,
158,
0,
49,
109,
210,
0,
49,
109,
262,
0,
49,
109,
0, 0, 49, 109, 52, 0, 49, 109, 105, 0, 49, 109, 158, 0, 49, 109,
210, 0, 49, 109, 262, 0, 49, 109,
],
kicking: [
0,
109,
45,
98,
45,
109,
45,
98,
95,
109,
63,
98,
156,
109,
70,
98,
229,
109,
60,
98,
287,
109,
41,
98,
0, 109, 45, 98, 45, 109, 45, 98, 95, 109, 63, 98, 156, 109, 70, 98,
229, 109, 60, 98, 287, 109, 41, 98,
],
},
frameRate: 10,
@@ -118,30 +74,8 @@ describe('Sprite', function () {
animation: 'standing',
animations: {
standing: [
0,
0,
49,
109,
52,
0,
49,
109,
105,
0,
49,
109,
158,
0,
49,
109,
210,
0,
49,
109,
262,
0,
49,
109,
0, 0, 49, 109, 52, 0, 49, 109, 105, 0, 49, 109, 158, 0, 49, 109,
210, 0, 49, 109, 262, 0, 49, 109,
],
},
frameRate: 5,
@@ -185,30 +119,8 @@ describe('Sprite', function () {
animation: 'standing',
animations: {
standing: [
0,
0,
49,
109,
52,
0,
49,
109,
105,
0,
49,
109,
158,
0,
49,
109,
210,
0,
49,
109,
262,
0,
49,
109,
0, 0, 49, 109, 52, 0, 49, 109, 105, 0, 49, 109, 158, 0, 49, 109,
210, 0, 49, 109, 262, 0, 49, 109,
],
},
frameRate: 5,
@@ -221,30 +133,8 @@ describe('Sprite', function () {
animation: 'standing',
animations: {
standing: [
0,
0,
49,
109,
52,
0,
49,
109,
105,
0,
49,
109,
158,
0,
49,
109,
210,
0,
49,
109,
262,
0,
49,
109,
0, 0, 49, 109, 52, 0, 49, 109, 105, 0, 49, 109, 158, 0, 49, 109,
210, 0, 49, 109, 262, 0, 49, 109,
],
},
frameRate: 20,
@@ -285,30 +175,8 @@ describe('Sprite', function () {
animation: 'standing',
animations: {
standing: [
0,
0,
49,
109,
52,
0,
49,
109,
105,
0,
49,
109,
158,
0,
49,
109,
210,
0,
49,
109,
262,
0,
49,
109,
0, 0, 49, 109, 52, 0, 49, 109, 105, 0, 49, 109, 158, 0, 49, 109,
210, 0, 49, 109, 262, 0, 49, 109,
],
},
frameRate: 50,
@@ -341,30 +209,8 @@ describe('Sprite', function () {
animation: 'standing',
animations: {
standing: [
0,
0,
49,
109,
52,
0,
49,
109,
105,
0,
49,
109,
158,
0,
49,
109,
210,
0,
49,
109,
262,
0,
49,
109,
0, 0, 49, 109, 52, 0, 49, 109, 105, 0, 49, 109, 158, 0, 49, 109,
210, 0, 49, 109, 262, 0, 49, 109,
],
},
frameRate: 50,
@@ -407,30 +253,8 @@ describe('Sprite', function () {
animation: 'standing',
animations: {
standing: [
0,
0,
49,
109,
52,
0,
49,
109,
105,
0,
49,
109,
158,
0,
49,
109,
210,
0,
49,
109,
262,
0,
49,
109,
0, 0, 49, 109, 52, 0, 49, 109, 105, 0, 49, 109, 158, 0, 49, 109,
210, 0, 49, 109, 262, 0, 49, 109,
],
},
frameRate: 50,

View File

@@ -3680,7 +3680,7 @@ describe('Transformer', function () {
layer.draw();
var rect = Konva.Util._assign({}, tr._getNodeRect());
delete rect.rotation;
assert.deepEqual(shape.getClientRect(), rect), 'change width';
(assert.deepEqual(shape.getClientRect(), rect), 'change width');
shape.height(30);
layer.draw();
@@ -3726,7 +3726,7 @@ describe('Transformer', function () {
layer.draw();
var rect = Konva.Util._assign({}, tr._getNodeRect());
delete rect.rotation;
assert.deepEqual(shape.getClientRect(), rect), 'change data';
(assert.deepEqual(shape.getClientRect(), rect), 'change data');
});
it('make sure transformer events are not cloned', function () {

View File

@@ -17,8 +17,7 @@
"skipLibCheck": true,
// probably we would never enable this one
// because it's too strict, konva generates many functions on the runtime
"strictPropertyInitialization": false,
"strictPropertyInitialization": false
},
"include": ["./src/**/*.ts"],
"include": ["./src/**/*.ts"]
}