mirror of
https://github.com/konvajs/konva.git
synced 2025-04-05 20:48:28 +08:00
Fix globalCompositeOperation + cached hit detections. close #759
This commit is contained in:
parent
7909283e3d
commit
80c674eb1f
@ -5,6 +5,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## Not released:
|
||||
|
||||
* Fix globalCompositeOperation + cached hit detections.
|
||||
* Fix absolute position calculations for cached parent
|
||||
|
||||
## 4.0.13 - 2019-10-02
|
||||
|
7
konva.js
7
konva.js
@ -8,7 +8,7 @@
|
||||
* Konva JavaScript Framework v4.0.13
|
||||
* http://konvajs.org/
|
||||
* Licensed under the MIT
|
||||
* Date: Tue Oct 08 2019
|
||||
* Date: Thu Oct 10 2019
|
||||
*
|
||||
* Original work Copyright (C) 2011 - 2013 by Eric Rowell (KineticJS)
|
||||
* Modified work Copyright (C) 2014 - present by Anton Lavrenov (Konva)
|
||||
@ -2858,7 +2858,6 @@
|
||||
Node.prototype._drawCachedHitCanvas = function (context) {
|
||||
var canvasCache = this._getCanvasCache(), hitCanvas = canvasCache.hit;
|
||||
context.save();
|
||||
context._applyGlobalCompositeOperation(this);
|
||||
context.translate(canvasCache.x, canvasCache.y);
|
||||
context.drawImage(hitCanvas._canvas, 0, 0);
|
||||
context.restore();
|
||||
@ -5432,7 +5431,9 @@
|
||||
.getMatrix();
|
||||
context.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
|
||||
}
|
||||
var hasComposition = this.globalCompositeOperation() !== 'source-over' && !skipComposition;
|
||||
var hasComposition = this.globalCompositeOperation() !== 'source-over' &&
|
||||
!skipComposition &&
|
||||
drawMethod === 'drawScene';
|
||||
if (hasComposition && layer) {
|
||||
context.save();
|
||||
context._applyGlobalCompositeOperation(this);
|
||||
|
4
konva.min.js
vendored
4
konva.min.js
vendored
File diff suppressed because one or more lines are too long
@ -419,7 +419,9 @@ export abstract class Container<ChildType extends Node> extends Node<
|
||||
}
|
||||
|
||||
var hasComposition =
|
||||
this.globalCompositeOperation() !== 'source-over' && !skipComposition;
|
||||
this.globalCompositeOperation() !== 'source-over' &&
|
||||
!skipComposition &&
|
||||
drawMethod === 'drawScene';
|
||||
if (hasComposition && layer) {
|
||||
context.save();
|
||||
context._applyGlobalCompositeOperation(this);
|
||||
|
@ -575,7 +575,6 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
var canvasCache = this._getCanvasCache(),
|
||||
hitCanvas = canvasCache.hit;
|
||||
context.save();
|
||||
context._applyGlobalCompositeOperation(this);
|
||||
context.translate(canvasCache.x, canvasCache.y);
|
||||
context.drawImage(hitCanvas._canvas, 0, 0);
|
||||
context.restore();
|
||||
|
@ -50,7 +50,7 @@ function _strokeFunc(context) {
|
||||
* ' ': -0.05517578125,
|
||||
* 'T': -0.07421875,
|
||||
* 'V': -0.07421875
|
||||
* }
|
||||
* }
|
||||
* 'V': {
|
||||
* ',': -0.091796875,
|
||||
* ":": -0.037109375,
|
||||
|
@ -1030,6 +1030,17 @@ suite('Caching', function() {
|
||||
const layer = new Konva.Layer();
|
||||
stage.add(layer);
|
||||
|
||||
function getColor(pos) {
|
||||
var ratio = layer.canvas.pixelRatio;
|
||||
var p = layer.canvas.context.getImageData(
|
||||
Math.round(pos.x * ratio),
|
||||
Math.round(pos.y * ratio),
|
||||
1,
|
||||
1
|
||||
).data;
|
||||
return Konva.Util._rgbToHex(p[0], p[1], p[2]);
|
||||
}
|
||||
|
||||
const bg = new Konva.Rect({
|
||||
x: 0,
|
||||
y: 0,
|
||||
@ -1077,14 +1088,15 @@ suite('Caching', function() {
|
||||
|
||||
layer.draw();
|
||||
// no caches - mask group clipped all drawing
|
||||
assert.equal(stage.getIntersection({ x: 5, y: 20 }), null);
|
||||
assert.equal(stage.getIntersection({ x: 55, y: 20 }), rect);
|
||||
assert.equal(getColor({ x: 5, y: 20 }), '000000');
|
||||
assert.equal(getColor({ x: 55, y: 20 }), '0000ff');
|
||||
|
||||
// cache inner mask group - same result
|
||||
maskgroup.cache();
|
||||
layer.draw();
|
||||
assert.equal(stage.getIntersection({ x: 5, y: 20 }), null);
|
||||
assert.equal(stage.getIntersection({ x: 55, y: 20 }), rect);
|
||||
|
||||
assert.equal(getColor({ x: 5, y: 20 }), '000000');
|
||||
assert.equal(getColor({ x: 55, y: 20 }), '0000ff');
|
||||
|
||||
// cache group
|
||||
// background will be visible now, because globalCompositeOperation
|
||||
@ -1092,8 +1104,8 @@ suite('Caching', function() {
|
||||
group.cache();
|
||||
layer.draw();
|
||||
|
||||
assert.equal(stage.getIntersection({ x: 5, y: 20 }), bg);
|
||||
assert.equal(stage.getIntersection({ x: 55, y: 20 }), rect);
|
||||
assert.equal(getColor({ x: 5, y: 20 }), 'd3d3d3');
|
||||
assert.equal(getColor({ x: 55, y: 20 }), '0000ff');
|
||||
});
|
||||
|
||||
it('recache should update internal caching', function() {
|
||||
@ -1215,4 +1227,37 @@ suite('Caching', function() {
|
||||
assert.equal(circle.getAbsolutePosition().x, 110);
|
||||
assert.equal(circle.getAbsolutePosition().y, 110);
|
||||
});
|
||||
|
||||
test('hit from cache + global composite', function(done) {
|
||||
// blend mode should NOT effect hit detection.
|
||||
var stage = addStage();
|
||||
|
||||
var layer = new Konva.Layer({});
|
||||
stage.add(layer);
|
||||
|
||||
Konva.Image.fromURL('./assets/lion.png', lion => {
|
||||
lion.name('lion');
|
||||
lion.cache();
|
||||
lion.drawHitFromCache();
|
||||
layer.add(lion);
|
||||
|
||||
Konva.Image.fromURL('./assets/lion.png', lion2 => {
|
||||
lion2.position({
|
||||
x: 50,
|
||||
y: 50
|
||||
});
|
||||
lion2.name('lion2');
|
||||
lion2.globalCompositeOperation('overlay');
|
||||
lion2.cache();
|
||||
lion2.drawHitFromCache();
|
||||
layer.add(lion2);
|
||||
layer.draw();
|
||||
layer.toggleHitCanvas();
|
||||
|
||||
var shape = layer.getIntersection({ x: 106, y: 78 });
|
||||
assert.equal(shape, lion2);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -49,13 +49,15 @@ suite('TextPath', function() {
|
||||
});
|
||||
|
||||
// ======================================================
|
||||
test('Find Next Segment when Arc is in Path', function() {
|
||||
test.skip('Find Next Segment when Arc is in Path', function() {
|
||||
var stage = addStage();
|
||||
var layer = new Konva.Layer();
|
||||
|
||||
var c = 'M 50 50 a 150 50 0 0 1 250 50 l 50 0';
|
||||
var c = 'M10,10 C0,0 10,150 100,100 S300,150 40,130';
|
||||
var path = new Konva.Path({
|
||||
stroke: 'red',
|
||||
x: 0,
|
||||
y: 50,
|
||||
stroke: 'green',
|
||||
strokeWidth: 1,
|
||||
data: c
|
||||
});
|
||||
@ -63,15 +65,23 @@ suite('TextPath', function() {
|
||||
layer.add(path);
|
||||
|
||||
var textpath = new Konva.TextPath({
|
||||
fill: 'black',
|
||||
fontSize: 10,
|
||||
x: 0,
|
||||
y: 50,
|
||||
fill: '#333',
|
||||
fontSize: 50,
|
||||
fontFamily: 'Arial',
|
||||
text:
|
||||
"All the world's a stage, and all the men and women merely players. They have their exits and their entrances; And one man in his time plays many parts.",
|
||||
"All mhe world's a smage, and all mhe men and women merely players.",
|
||||
data: c
|
||||
});
|
||||
|
||||
layer.add(textpath);
|
||||
stage.add(layer);
|
||||
|
||||
var trace = layer.getContext().getTrace();
|
||||
console.log(trace);
|
||||
assert.equal(trace.indexOf('NaN') === -1, true, 'No NaNs');
|
||||
throw '';
|
||||
});
|
||||
|
||||
// ======================================================
|
||||
|
Loading…
Reference in New Issue
Block a user