mirror of
https://github.com/konvajs/konva.git
synced 2025-06-28 06:31:15 +08:00
fix buffer export
This commit is contained in:
parent
a1660e1ccb
commit
0d502baccd
@ -3,6 +3,11 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
|
### 9.3.1 (2024-01-17)
|
||||||
|
|
||||||
|
- Fix Pixelate filter work/fix caching size
|
||||||
|
- Fix node export when large buffer canvas is used
|
||||||
|
|
||||||
### 9.3.0 (2023-12-20)
|
### 9.3.0 (2023-12-20)
|
||||||
|
|
||||||
- New attribute `rotateLineVisible` for `Konva.Transformer` to show/hide rotate line
|
- New attribute `rotateLineVisible` for `Konva.Transformer` to show/hide rotate line
|
||||||
|
@ -342,7 +342,7 @@ export abstract class Container<
|
|||||||
});
|
});
|
||||||
this._requestDraw();
|
this._requestDraw();
|
||||||
}
|
}
|
||||||
drawScene(can?: SceneCanvas, top?: Node) {
|
drawScene(can?: SceneCanvas, top?: Node, bufferCanvas?: SceneCanvas) {
|
||||||
var layer = this.getLayer()!,
|
var layer = this.getLayer()!,
|
||||||
canvas = can || (layer && layer.getCanvas()),
|
canvas = can || (layer && layer.getCanvas()),
|
||||||
context = canvas && canvas.getContext(),
|
context = canvas && canvas.getContext(),
|
||||||
@ -361,7 +361,7 @@ export abstract class Container<
|
|||||||
this._drawCachedSceneCanvas(context);
|
this._drawCachedSceneCanvas(context);
|
||||||
context.restore();
|
context.restore();
|
||||||
} else {
|
} else {
|
||||||
this._drawChildren('drawScene', canvas, top);
|
this._drawChildren('drawScene', canvas, top, bufferCanvas);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -387,7 +387,7 @@ export abstract class Container<
|
|||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
_drawChildren(drawMethod, canvas, top) {
|
_drawChildren(drawMethod, canvas, top, bufferCanvas?) {
|
||||||
var context = canvas && canvas.getContext(),
|
var context = canvas && canvas.getContext(),
|
||||||
clipWidth = this.clipWidth(),
|
clipWidth = this.clipWidth(),
|
||||||
clipHeight = this.clipHeight(),
|
clipHeight = this.clipHeight(),
|
||||||
@ -426,7 +426,7 @@ export abstract class Container<
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.children?.forEach(function (child) {
|
this.children?.forEach(function (child) {
|
||||||
child[drawMethod](canvas, top);
|
child[drawMethod](canvas, top, bufferCanvas);
|
||||||
});
|
});
|
||||||
if (hasComposition) {
|
if (hasComposition) {
|
||||||
context.restore();
|
context.restore();
|
||||||
|
10
src/Node.ts
10
src/Node.ts
@ -449,7 +449,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
|||||||
return this._cache.has(CANVAS);
|
return this._cache.has(CANVAS);
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract drawScene(canvas?: Canvas, top?: Node): void;
|
abstract drawScene(canvas?: Canvas, top?: Node, bufferCanvas?: Canvas): void;
|
||||||
abstract drawHit(canvas?: Canvas, top?: Node): void;
|
abstract drawHit(canvas?: Canvas, top?: Node): void;
|
||||||
/**
|
/**
|
||||||
* Return client rectangle {x, y, width, height} of node. This rectangle also include all styling (strokes, shadows, etc).
|
* Return client rectangle {x, y, width, height} of node. This rectangle also include all styling (strokes, shadows, etc).
|
||||||
@ -1932,6 +1932,12 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
|||||||
}),
|
}),
|
||||||
context = canvas.getContext();
|
context = canvas.getContext();
|
||||||
|
|
||||||
|
const bufferCanvas = new SceneCanvas({
|
||||||
|
width: canvas.width,
|
||||||
|
height: canvas.height,
|
||||||
|
pixelRatio: canvas.pixelRatio,
|
||||||
|
});
|
||||||
|
|
||||||
if (config.imageSmoothingEnabled === false) {
|
if (config.imageSmoothingEnabled === false) {
|
||||||
context._context.imageSmoothingEnabled = false;
|
context._context.imageSmoothingEnabled = false;
|
||||||
}
|
}
|
||||||
@ -1941,7 +1947,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
|||||||
context.translate(-1 * x, -1 * y);
|
context.translate(-1 * x, -1 * y);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.drawScene(canvas);
|
this.drawScene(canvas, undefined, bufferCanvas);
|
||||||
context.restore();
|
context.restore();
|
||||||
|
|
||||||
return canvas;
|
return canvas;
|
||||||
|
21
src/Shape.ts
21
src/Shape.ts
@ -469,10 +469,6 @@ export class Shape<
|
|||||||
// so they use that method with forced fill
|
// so they use that method with forced fill
|
||||||
// it probably will be simpler, then copy/paste the code
|
// it probably will be simpler, then copy/paste the code
|
||||||
|
|
||||||
// buffer canvas is available only inside the stage
|
|
||||||
if (!this.getStage()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// force skip buffer canvas
|
// force skip buffer canvas
|
||||||
const perfectDrawEnabled = this.attrs.perfectDrawEnabled ?? true;
|
const perfectDrawEnabled = this.attrs.perfectDrawEnabled ?? true;
|
||||||
if (!perfectDrawEnabled) {
|
if (!perfectDrawEnabled) {
|
||||||
@ -573,7 +569,7 @@ export class Shape<
|
|||||||
}
|
}
|
||||||
return rect;
|
return rect;
|
||||||
}
|
}
|
||||||
drawScene(can?: SceneCanvas, top?: Node) {
|
drawScene(can?: SceneCanvas, top?: Node, bufferCanvas?: SceneCanvas) {
|
||||||
// basically there are 3 drawing modes
|
// basically there are 3 drawing modes
|
||||||
// 1 - simple drawing when nothing is cached.
|
// 1 - simple drawing when nothing is cached.
|
||||||
// 2 - when we are caching current
|
// 2 - when we are caching current
|
||||||
@ -586,7 +582,6 @@ export class Shape<
|
|||||||
drawFunc = this.getSceneFunc(),
|
drawFunc = this.getSceneFunc(),
|
||||||
hasShadow = this.hasShadow(),
|
hasShadow = this.hasShadow(),
|
||||||
stage,
|
stage,
|
||||||
bufferCanvas,
|
|
||||||
bufferContext;
|
bufferContext;
|
||||||
|
|
||||||
var skipBuffer = canvas.isCache;
|
var skipBuffer = canvas.isCache;
|
||||||
@ -614,8 +609,8 @@ export class Shape<
|
|||||||
// if buffer canvas is needed
|
// if buffer canvas is needed
|
||||||
if (this._useBufferCanvas() && !skipBuffer) {
|
if (this._useBufferCanvas() && !skipBuffer) {
|
||||||
stage = this.getStage();
|
stage = this.getStage();
|
||||||
bufferCanvas = stage.bufferCanvas;
|
const bc = bufferCanvas || stage.bufferCanvas;
|
||||||
bufferContext = bufferCanvas.getContext();
|
bufferContext = bc.getContext();
|
||||||
bufferContext.clear();
|
bufferContext.clear();
|
||||||
bufferContext.save();
|
bufferContext.save();
|
||||||
bufferContext._applyLineJoin(this);
|
bufferContext._applyLineJoin(this);
|
||||||
@ -626,20 +621,14 @@ export class Shape<
|
|||||||
drawFunc.call(this, bufferContext, this);
|
drawFunc.call(this, bufferContext, this);
|
||||||
bufferContext.restore();
|
bufferContext.restore();
|
||||||
|
|
||||||
var ratio = bufferCanvas.pixelRatio;
|
var ratio = bc.pixelRatio;
|
||||||
|
|
||||||
if (hasShadow) {
|
if (hasShadow) {
|
||||||
context._applyShadow(this);
|
context._applyShadow(this);
|
||||||
}
|
}
|
||||||
context._applyOpacity(this);
|
context._applyOpacity(this);
|
||||||
context._applyGlobalCompositeOperation(this);
|
context._applyGlobalCompositeOperation(this);
|
||||||
context.drawImage(
|
context.drawImage(bc._canvas, 0, 0, bc.width / ratio, bc.height / ratio);
|
||||||
bufferCanvas._canvas,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
bufferCanvas.width / ratio,
|
|
||||||
bufferCanvas.height / ratio
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
context._applyLineJoin(this);
|
context._applyLineJoin(this);
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ import {
|
|||||||
compareLayers,
|
compareLayers,
|
||||||
loadImage,
|
loadImage,
|
||||||
Konva,
|
Konva,
|
||||||
|
compareCanvases,
|
||||||
} from './test-utils';
|
} from './test-utils';
|
||||||
|
|
||||||
describe('Shape', function () {
|
describe('Shape', function () {
|
||||||
@ -1479,6 +1480,40 @@ describe('Shape', function () {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('export when buffer canvas is used should handle scaling correctly', async function () {
|
||||||
|
var stage = addStage();
|
||||||
|
|
||||||
|
var layer = new Konva.Layer();
|
||||||
|
stage.add(layer);
|
||||||
|
|
||||||
|
var group = new Konva.Group();
|
||||||
|
layer.add(group);
|
||||||
|
|
||||||
|
var text = new Konva.Text({
|
||||||
|
text: 'hello',
|
||||||
|
fontSize: 300,
|
||||||
|
fill: 'green',
|
||||||
|
shadowColor: 'black',
|
||||||
|
});
|
||||||
|
group.add(text);
|
||||||
|
|
||||||
|
const canvas1 = group.toCanvas({
|
||||||
|
x: group.x(),
|
||||||
|
y: group.y(),
|
||||||
|
width: text.width(),
|
||||||
|
height: text.height(),
|
||||||
|
});
|
||||||
|
text.stroke('transparent');
|
||||||
|
const canvas2 = group.toCanvas({
|
||||||
|
x: group.x(),
|
||||||
|
y: group.y(),
|
||||||
|
width: text.width(),
|
||||||
|
height: text.height(),
|
||||||
|
});
|
||||||
|
|
||||||
|
compareCanvases(canvas2, canvas1, 255, 10);
|
||||||
|
});
|
||||||
|
|
||||||
// ======================================================
|
// ======================================================
|
||||||
it('optional disable shadow for stroke', function () {
|
it('optional disable shadow for stroke', function () {
|
||||||
var stage = addStage();
|
var stage = addStage();
|
||||||
|
Loading…
Reference in New Issue
Block a user