mirror of
https://github.com/konvajs/konva.git
synced 2025-09-19 02:37:59 +08:00
remove rounding from getClientRect
This commit is contained in:
6
konva.js
6
konva.js
@@ -8,7 +8,7 @@
|
|||||||
* Konva JavaScript Framework v8.3.3
|
* Konva JavaScript Framework v8.3.3
|
||||||
* http://konvajs.org/
|
* http://konvajs.org/
|
||||||
* Licensed under the MIT
|
* Licensed under the MIT
|
||||||
* Date: Wed Feb 23 2022
|
* Date: Tue Mar 08 2022
|
||||||
*
|
*
|
||||||
* Original work Copyright (C) 2011 - 2013 by Eric Rowell (KineticJS)
|
* Original work Copyright (C) 2011 - 2013 by Eric Rowell (KineticJS)
|
||||||
* Modified work Copyright (C) 2014 - present by Anton Lavrenov (Konva)
|
* Modified work Copyright (C) 2014 - present by Anton Lavrenov (Konva)
|
||||||
@@ -15001,9 +15001,9 @@
|
|||||||
x: pos.x - ap.x,
|
x: pos.x - ap.x,
|
||||||
y: pos.y - ap.y,
|
y: pos.y - ap.y,
|
||||||
};
|
};
|
||||||
this._fire('transformstart', { evt: e, target: this.getNode() });
|
this._fire('transformstart', { evt: e.evt, target: this.getNode() });
|
||||||
this._nodes.forEach((target) => {
|
this._nodes.forEach((target) => {
|
||||||
target._fire('transformstart', { evt: e, target });
|
target._fire('transformstart', { evt: e.evt, target });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
_handleMouseMove(e) {
|
_handleMouseMove(e) {
|
||||||
|
4
konva.min.js
vendored
4
konva.min.js
vendored
File diff suppressed because one or more lines are too long
21
src/Node.ts
21
src/Node.ts
@@ -322,8 +322,8 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
|||||||
var width = Math.ceil(conf.width || rect.width),
|
var width = Math.ceil(conf.width || rect.width),
|
||||||
height = Math.ceil(conf.height || rect.height),
|
height = Math.ceil(conf.height || rect.height),
|
||||||
pixelRatio = conf.pixelRatio,
|
pixelRatio = conf.pixelRatio,
|
||||||
x = conf.x === undefined ? rect.x : conf.x,
|
x = conf.x === undefined ? Math.floor(rect.x) : conf.x,
|
||||||
y = conf.y === undefined ? rect.y : conf.y,
|
y = conf.y === undefined ? Math.floor(rect.y) : conf.y,
|
||||||
offset = conf.offset || 0,
|
offset = conf.offset || 0,
|
||||||
drawBorder = conf.drawBorder || false,
|
drawBorder = conf.drawBorder || false,
|
||||||
hitCanvasPixelRatio = conf.hitCanvasPixelRatio || 1;
|
hitCanvasPixelRatio = conf.hitCanvasPixelRatio || 1;
|
||||||
@@ -335,12 +335,25 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
width += offset * 2;
|
// let's just add 1 pixel extra,
|
||||||
height += offset * 2;
|
// because using Math.floor on x, y position may shift drawing
|
||||||
|
width += offset * 2 + 1;
|
||||||
|
height += offset * 2 + 1;
|
||||||
|
|
||||||
x -= offset;
|
x -= offset;
|
||||||
y -= offset;
|
y -= offset;
|
||||||
|
|
||||||
|
// if (Math.floor(x) < x) {
|
||||||
|
// x = Math.floor(x);
|
||||||
|
// // width += 1;
|
||||||
|
// }
|
||||||
|
// if (Math.floor(y) < y) {
|
||||||
|
// y = Math.floor(y);
|
||||||
|
// // height += 1;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// console.log({ x, y, width, height }, rect);
|
||||||
|
|
||||||
var cachedSceneCanvas = new SceneCanvas({
|
var cachedSceneCanvas = new SceneCanvas({
|
||||||
pixelRatio: pixelRatio,
|
pixelRatio: pixelRatio,
|
||||||
width: width,
|
width: width,
|
||||||
|
16
src/Shape.ts
16
src/Shape.ts
@@ -538,19 +538,19 @@ export class Shape<
|
|||||||
// if stroke, for example = 3
|
// if stroke, for example = 3
|
||||||
// we need to set x to 1.5, but after Math.round it will be 2
|
// we need to set x to 1.5, but after Math.round it will be 2
|
||||||
// as we have additional offset we need to increase width and height by 1 pixel
|
// as we have additional offset we need to increase width and height by 1 pixel
|
||||||
let roundingOffset = 0;
|
// let roundingOffset = 0;
|
||||||
if (Math.round(strokeWidth / 2) !== strokeWidth / 2) {
|
// if (Math.round(strokeWidth / 2) !== strokeWidth / 2) {
|
||||||
roundingOffset = 1;
|
// roundingOffset = 1;
|
||||||
}
|
// }
|
||||||
const rect = {
|
const rect = {
|
||||||
width: width + roundingOffset,
|
width: width,
|
||||||
height: height + roundingOffset,
|
height: height,
|
||||||
x:
|
x:
|
||||||
-Math.round(strokeWidth / 2 + blurRadius) +
|
-(strokeWidth / 2 + blurRadius) +
|
||||||
Math.min(shadowOffsetX, 0) +
|
Math.min(shadowOffsetX, 0) +
|
||||||
fillRect.x,
|
fillRect.x,
|
||||||
y:
|
y:
|
||||||
-Math.round(strokeWidth / 2 + blurRadius) +
|
-(strokeWidth / 2 + blurRadius) +
|
||||||
Math.min(shadowOffsetY, 0) +
|
Math.min(shadowOffsetY, 0) +
|
||||||
fillRect.y,
|
fillRect.y,
|
||||||
};
|
};
|
||||||
|
@@ -62,26 +62,32 @@ export class Arc extends Shape<ArcConfig> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getSelfRect() {
|
getSelfRect() {
|
||||||
const innerRadius = this.innerRadius()
|
const innerRadius = this.innerRadius();
|
||||||
const outerRadius = this.outerRadius()
|
const outerRadius = this.outerRadius();
|
||||||
const clockwise = this.clockwise()
|
const clockwise = this.clockwise();
|
||||||
const angle = Konva.getAngle(clockwise ? 360 - this.angle() : this.angle());
|
const angle = Konva.getAngle(clockwise ? 360 - this.angle() : this.angle());
|
||||||
|
|
||||||
const boundLeftRatio = Math.cos(Math.min(angle, Math.PI))
|
const boundLeftRatio = Math.cos(Math.min(angle, Math.PI));
|
||||||
const boundRightRatio = 1
|
const boundRightRatio = 1;
|
||||||
const boundTopRatio = Math.sin(Math.min(Math.max(Math.PI, angle), 3 * Math.PI / 2))
|
const boundTopRatio = Math.sin(
|
||||||
const boundBottomRatio = Math.sin(Math.min(angle, Math.PI / 2))
|
Math.min(Math.max(Math.PI, angle), (3 * Math.PI) / 2)
|
||||||
const boundLeft = boundLeftRatio * (boundLeftRatio > 0 ? innerRadius : outerRadius)
|
);
|
||||||
const boundRight = boundRightRatio * (boundRightRatio > 0 ? outerRadius : innerRadius)
|
const boundBottomRatio = Math.sin(Math.min(angle, Math.PI / 2));
|
||||||
const boundTop = boundTopRatio * (boundTopRatio > 0 ? innerRadius : outerRadius)
|
const boundLeft =
|
||||||
const boundBottom = boundBottomRatio * (boundBottomRatio > 0 ? outerRadius : innerRadius)
|
boundLeftRatio * (boundLeftRatio > 0 ? innerRadius : outerRadius);
|
||||||
|
const boundRight =
|
||||||
|
boundRightRatio * (boundRightRatio > 0 ? outerRadius : innerRadius);
|
||||||
|
const boundTop =
|
||||||
|
boundTopRatio * (boundTopRatio > 0 ? innerRadius : outerRadius);
|
||||||
|
const boundBottom =
|
||||||
|
boundBottomRatio * (boundBottomRatio > 0 ? outerRadius : innerRadius);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
x: Math.round(boundLeft),
|
x: boundLeft,
|
||||||
y: Math.round(clockwise ? -1 * boundBottom : boundTop),
|
y: clockwise ? -1 * boundBottom : boundTop,
|
||||||
width: Math.round(boundRight - boundLeft),
|
width: boundRight - boundLeft,
|
||||||
height: Math.round(boundBottom - boundTop)
|
height: boundBottom - boundTop,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
innerRadius: GetSet<number, this>;
|
innerRadius: GetSet<number, this>;
|
||||||
|
@@ -188,10 +188,10 @@ export class Path extends Shape<PathConfig> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
x: Math.round(minX),
|
x: minX,
|
||||||
y: Math.round(minY),
|
y: minY,
|
||||||
width: Math.round(maxX - minX),
|
width: maxX - minX,
|
||||||
height: Math.round(maxY - minY),
|
height: maxY - minY,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@@ -646,10 +646,10 @@ Factory.addGetterSetter(TextPath, 'align', 'left');
|
|||||||
* @param {Number} letterSpacing
|
* @param {Number} letterSpacing
|
||||||
* @returns {Number}
|
* @returns {Number}
|
||||||
* @example
|
* @example
|
||||||
* // get line height
|
* // get letter spacing value
|
||||||
* var letterSpacing = shape.letterSpacing();
|
* var letterSpacing = shape.letterSpacing();
|
||||||
*
|
*
|
||||||
* // set the line height
|
* // set the letter spacing value
|
||||||
* shape.letterSpacing(2);
|
* shape.letterSpacing(2);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -662,10 +662,10 @@ Factory.addGetterSetter(TextPath, 'letterSpacing', 0, getNumberValidator());
|
|||||||
* @param {String} textBaseline
|
* @param {String} textBaseline
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
* @example
|
* @example
|
||||||
* // get line height
|
* // get current text baseline
|
||||||
* var textBaseline = shape.textBaseline();
|
* var textBaseline = shape.textBaseline();
|
||||||
*
|
*
|
||||||
* // set the line height
|
* // set new text baseline
|
||||||
* shape.textBaseline('top');
|
* shape.textBaseline('top');
|
||||||
*/
|
*/
|
||||||
Factory.addGetterSetter(TextPath, 'textBaseline', 'middle');
|
Factory.addGetterSetter(TextPath, 'textBaseline', 'middle');
|
||||||
|
@@ -5,6 +5,7 @@ import {
|
|||||||
Konva,
|
Konva,
|
||||||
createCanvas,
|
createCanvas,
|
||||||
compareLayerAndCanvas,
|
compareLayerAndCanvas,
|
||||||
|
assertAlmostDeepEqual,
|
||||||
} from './test-utils';
|
} from './test-utils';
|
||||||
|
|
||||||
describe('Arc', function () {
|
describe('Arc', function () {
|
||||||
@@ -88,7 +89,7 @@ describe('Arc', function () {
|
|||||||
layer.add(arc);
|
layer.add(arc);
|
||||||
stage.add(layer);
|
stage.add(layer);
|
||||||
|
|
||||||
assert.deepEqual(arc.getSelfRect(), {
|
assertAlmostDeepEqual(arc.getSelfRect(), {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
width: 80,
|
width: 80,
|
||||||
@@ -116,7 +117,7 @@ describe('Arc', function () {
|
|||||||
layer.add(arc);
|
layer.add(arc);
|
||||||
stage.add(layer);
|
stage.add(layer);
|
||||||
|
|
||||||
assert.deepEqual(arc.getSelfRect(), {
|
assertAlmostDeepEqual(arc.getSelfRect(), {
|
||||||
x: -80,
|
x: -80,
|
||||||
y: -80,
|
y: -80,
|
||||||
width: 160,
|
width: 160,
|
||||||
@@ -140,7 +141,7 @@ describe('Arc', function () {
|
|||||||
layer.add(arc);
|
layer.add(arc);
|
||||||
stage.add(layer);
|
stage.add(layer);
|
||||||
|
|
||||||
assert.deepEqual(arc.getSelfRect(), {
|
assertAlmostDeepEqual(arc.getSelfRect(), {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: -80,
|
y: -80,
|
||||||
width: 80,
|
width: 80,
|
||||||
@@ -163,14 +164,14 @@ describe('Arc', function () {
|
|||||||
layer.add(arc);
|
layer.add(arc);
|
||||||
stage.add(layer);
|
stage.add(layer);
|
||||||
|
|
||||||
assert.deepEqual(arc.getSelfRect(), {
|
assertAlmostDeepEqual(arc.getSelfRect(), {
|
||||||
x: 25,
|
x: 25,
|
||||||
y: 0,
|
y: 0,
|
||||||
width: 55,
|
width: 55,
|
||||||
height: 69,
|
height: 69.282032302755,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('cache', function () {
|
it('cache', function () {
|
||||||
var stage = addStage();
|
var stage = addStage();
|
||||||
var layer = new Konva.Layer();
|
var layer = new Konva.Layer();
|
||||||
|
@@ -831,7 +831,8 @@ describe('Caching', function () {
|
|||||||
group.cache();
|
group.cache();
|
||||||
|
|
||||||
const canvas = group._cache.get('canvas').scene;
|
const canvas = group._cache.get('canvas').scene;
|
||||||
assert.equal(canvas.width, 105 * canvas.pixelRatio);
|
console.log(canvas.width / 2);
|
||||||
|
assert.equal(canvas.width, 106 * canvas.pixelRatio);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('cache group with rectangle with fill and opacity', function () {
|
it('cache group with rectangle with fill and opacity', function () {
|
||||||
@@ -1468,7 +1469,7 @@ describe('Caching', function () {
|
|||||||
layer.draw();
|
layer.draw();
|
||||||
assert.equal(
|
assert.equal(
|
||||||
circle._cache.get('canvas').filter.width,
|
circle._cache.get('canvas').filter.width,
|
||||||
20 * circle._cache.get('canvas').filter.pixelRatio
|
21 * circle._cache.get('canvas').filter.pixelRatio
|
||||||
);
|
);
|
||||||
circle.filters([]);
|
circle.filters([]);
|
||||||
// TODO: should we clear cache canvas?
|
// TODO: should we clear cache canvas?
|
||||||
|
@@ -10,6 +10,7 @@ import {
|
|||||||
compareLayerAndCanvas,
|
compareLayerAndCanvas,
|
||||||
cloneAndCompareLayer,
|
cloneAndCompareLayer,
|
||||||
isNode,
|
isNode,
|
||||||
|
assertAlmostDeepEqual,
|
||||||
} from './test-utils';
|
} from './test-utils';
|
||||||
|
|
||||||
describe('Path', function () {
|
describe('Path', function () {
|
||||||
@@ -1280,7 +1281,12 @@ describe('Path', function () {
|
|||||||
});
|
});
|
||||||
layer.add(path);
|
layer.add(path);
|
||||||
var rect = path.getClientRect();
|
var rect = path.getClientRect();
|
||||||
assert.deepEqual(rect, { x: 60, y: 184, width: 106, height: 102 });
|
assertAlmostDeepEqual(rect, {
|
||||||
|
x: 59.55,
|
||||||
|
y: 183.55,
|
||||||
|
width: 106,
|
||||||
|
height: 102,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('getClientRect of complex path', function () {
|
it('getClientRect of complex path', function () {
|
||||||
@@ -1310,7 +1316,12 @@ describe('Path', function () {
|
|||||||
layer.add(back);
|
layer.add(back);
|
||||||
layer.draw();
|
layer.draw();
|
||||||
|
|
||||||
assert.deepEqual(rect, { x: 9, y: 66, width: 95, height: 55 });
|
assertAlmostDeepEqual(rect, {
|
||||||
|
x: 8.6440882161882,
|
||||||
|
y: 65.75902834,
|
||||||
|
width: 94.74182356762,
|
||||||
|
height: 55.4919433,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('getClientRect of another complex path', function () {
|
it('getClientRect of another complex path', function () {
|
||||||
@@ -1339,11 +1350,11 @@ describe('Path', function () {
|
|||||||
layer.add(back);
|
layer.add(back);
|
||||||
layer.draw();
|
layer.draw();
|
||||||
|
|
||||||
assert.deepEqual(rect, {
|
assertAlmostDeepEqual(rect, {
|
||||||
x: 49,
|
x: 49,
|
||||||
y: 49.7,
|
y: 49.7086649,
|
||||||
width: 215,
|
width: 215,
|
||||||
height: 71.39999999999999,
|
height: 71.3826701999,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1372,7 +1383,12 @@ describe('Path', function () {
|
|||||||
layer.add(back);
|
layer.add(back);
|
||||||
layer.draw();
|
layer.draw();
|
||||||
|
|
||||||
assert.deepEqual(rect, { x: 49, y: 49, width: 43, height: 48 });
|
assertAlmostDeepEqual(rect, {
|
||||||
|
x: 48.981379,
|
||||||
|
y: 48.996825,
|
||||||
|
width: 42.84717526,
|
||||||
|
height: 48.057550000000006,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('getClientRect for arc', function () {
|
it('getClientRect for arc', function () {
|
||||||
@@ -1408,15 +1424,15 @@ describe('Path', function () {
|
|||||||
layer.add(back);
|
layer.add(back);
|
||||||
layer.draw();
|
layer.draw();
|
||||||
|
|
||||||
assert.deepEqual(rect, {
|
assertAlmostDeepEqual(rect, {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
width: 132.53012048192795,
|
width: 132.4001878816343,
|
||||||
height: 100,
|
height: 100,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip('getClientRect on scaled', function () {
|
it('getClientRect on scaled', function () {
|
||||||
var stage = addStage();
|
var stage = addStage();
|
||||||
var layer = new Konva.Layer();
|
var layer = new Konva.Layer();
|
||||||
stage.add(layer);
|
stage.add(layer);
|
||||||
@@ -1444,7 +1460,7 @@ describe('Path', function () {
|
|||||||
layer.add(back);
|
layer.add(back);
|
||||||
layer.draw();
|
layer.draw();
|
||||||
|
|
||||||
assert.deepEqual(rect, {
|
assertAlmostDeepEqual(rect, {
|
||||||
height: 201.99999999999994,
|
height: 201.99999999999994,
|
||||||
width: 201.99999999999994,
|
width: 201.99999999999994,
|
||||||
x: 99,
|
x: 99,
|
||||||
|
@@ -203,7 +203,7 @@ describe('RegularPolygon', function () {
|
|||||||
|
|
||||||
var box = poly.getClientRect();
|
var box = poly.getClientRect();
|
||||||
|
|
||||||
assertAlmostEqual(box.width, 92.60254037844388);
|
assertAlmostEqual(box.width, 91.60254037844388);
|
||||||
assertAlmostEqual(box.height, 81.00000000000003);
|
assertAlmostEqual(box.height, 80.00000000000003);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -2509,7 +2509,7 @@ describe('Transformer', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it.only('transform events check', function () {
|
it('transform events check', function () {
|
||||||
var stage = addStage();
|
var stage = addStage();
|
||||||
var layer = new Konva.Layer();
|
var layer = new Konva.Layer();
|
||||||
stage.add(layer);
|
stage.add(layer);
|
||||||
|
@@ -384,3 +384,9 @@ export const assertAlmostEqual = function (val1, val2) {
|
|||||||
throw new Error('Expected ' + val1 + ' to be almost equal to ' + val2);
|
throw new Error('Expected ' + val1 + ' to be almost equal to ' + val2);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const assertAlmostDeepEqual = function (obj1, obj2) {
|
||||||
|
for (var key1 in obj1) {
|
||||||
|
assertAlmostEqual(obj1[key1], obj2[key1]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Reference in New Issue
Block a user