mirror of
https://github.com/konvajs/konva.git
synced 2025-06-28 06:24:42 +08:00
Merge branch 'zarv1k-release-canvas' into master
This commit is contained in:
commit
4a273df683
39
konva.js
39
konva.js
@ -8,7 +8,7 @@
|
|||||||
* Konva JavaScript Framework v8.3.13
|
* Konva JavaScript Framework v8.3.13
|
||||||
* http://konvajs.org/
|
* http://konvajs.org/
|
||||||
* Licensed under the MIT
|
* Licensed under the MIT
|
||||||
* Date: Mon Oct 03 2022
|
* Date: Wed Nov 09 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)
|
||||||
@ -157,6 +157,17 @@
|
|||||||
isDragReady() {
|
isDragReady() {
|
||||||
return !!Konva$2['DD'].node;
|
return !!Konva$2['DD'].node;
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Should Konva release canvas elements on destroy. Default is true.
|
||||||
|
* Useful to avoid memory leak issues in Safari on macOS/iOS.
|
||||||
|
* @property releaseCanvasOnDestroy
|
||||||
|
* @default true
|
||||||
|
* @name releaseCanvasOnDestroy
|
||||||
|
* @memberof Konva
|
||||||
|
* @example
|
||||||
|
* Konva.releaseCanvasOnDestroy = true;
|
||||||
|
*/
|
||||||
|
releaseCanvasOnDestroy: true,
|
||||||
// user agent
|
// user agent
|
||||||
document: glob.document,
|
document: glob.document,
|
||||||
// insert Konva into global namespace (window)
|
// insert Konva into global namespace (window)
|
||||||
@ -1071,6 +1082,14 @@
|
|||||||
return evt.changedTouches[0].identifier;
|
return evt.changedTouches[0].identifier;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
releaseCanvas(...canvases) {
|
||||||
|
if (!Konva$2.releaseCanvasOnDestroy)
|
||||||
|
return;
|
||||||
|
canvases.forEach(c => {
|
||||||
|
c.width = 0;
|
||||||
|
c.height = 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function _formatValue(val) {
|
function _formatValue(val) {
|
||||||
@ -2164,6 +2183,7 @@
|
|||||||
1;
|
1;
|
||||||
return devicePixelRatio / backingStoreRatio;
|
return devicePixelRatio / backingStoreRatio;
|
||||||
})();
|
})();
|
||||||
|
Util.releaseCanvas(canvas);
|
||||||
return _pixelRatio;
|
return _pixelRatio;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -2556,7 +2576,11 @@
|
|||||||
* node.clearCache();
|
* node.clearCache();
|
||||||
*/
|
*/
|
||||||
clearCache() {
|
clearCache() {
|
||||||
this._cache.delete(CANVAS);
|
if (this._cache.has(CANVAS)) {
|
||||||
|
const { scene, filter, hit } = this._cache.get(CANVAS);
|
||||||
|
Util.releaseCanvas(scene, filter, hit);
|
||||||
|
this._cache.delete(CANVAS);
|
||||||
|
}
|
||||||
this._clearSelfAndDescendantCache();
|
this._clearSelfAndDescendantCache();
|
||||||
this._requestDraw();
|
this._requestDraw();
|
||||||
return this;
|
return this;
|
||||||
@ -3042,6 +3066,7 @@
|
|||||||
*/
|
*/
|
||||||
destroy() {
|
destroy() {
|
||||||
this.remove();
|
this.remove();
|
||||||
|
this.clearCache();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -5997,6 +6022,7 @@
|
|||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
stages.splice(index, 1);
|
stages.splice(index, 1);
|
||||||
}
|
}
|
||||||
|
Util.releaseCanvas(this.bufferCanvas._canvas, this.bufferHitCanvas._canvas);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -8620,6 +8646,10 @@
|
|||||||
parent.content.appendChild(this.hitCanvas._canvas);
|
parent.content.appendChild(this.hitCanvas._canvas);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
destroy() {
|
||||||
|
Util.releaseCanvas(this.getNativeCanvasElement(), this.getHitCanvas()._canvas);
|
||||||
|
return super.destroy();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Layer.prototype.nodeType = 'Layer';
|
Layer.prototype.nodeType = 'Layer';
|
||||||
_registerNode(Layer);
|
_registerNode(Layer);
|
||||||
@ -14407,6 +14437,10 @@
|
|||||||
height: maxY - minY + fontSize,
|
height: maxY - minY + fontSize,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
destroy() {
|
||||||
|
Util.releaseCanvas(this.dummyCanvas);
|
||||||
|
return super.destroy();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
TextPath.prototype._fillFunc = _fillFunc;
|
TextPath.prototype._fillFunc = _fillFunc;
|
||||||
TextPath.prototype._strokeFunc = _strokeFunc;
|
TextPath.prototype._strokeFunc = _strokeFunc;
|
||||||
@ -17593,6 +17627,7 @@
|
|||||||
var scratchData = tempCanvas
|
var scratchData = tempCanvas
|
||||||
.getContext('2d')
|
.getContext('2d')
|
||||||
.getImageData(0, 0, xSize, ySize);
|
.getImageData(0, 0, xSize, ySize);
|
||||||
|
Util.releaseCanvas(tempCanvas);
|
||||||
// Convert thhe original to polar coordinates
|
// Convert thhe original to polar coordinates
|
||||||
ToPolar(imageData, scratchData, {
|
ToPolar(imageData, scratchData, {
|
||||||
polarCenterX: xSize / 2,
|
polarCenterX: xSize / 2,
|
||||||
|
4
konva.min.js
vendored
4
konva.min.js
vendored
File diff suppressed because one or more lines are too long
@ -23,6 +23,7 @@ function getDevicePixelRatio() {
|
|||||||
1;
|
1;
|
||||||
return devicePixelRatio / backingStoreRatio;
|
return devicePixelRatio / backingStoreRatio;
|
||||||
})();
|
})();
|
||||||
|
Util.releaseCanvas(canvas);
|
||||||
return _pixelRatio;
|
return _pixelRatio;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ var CONTEXT_PROPERTIES = [
|
|||||||
'globalAlpha',
|
'globalAlpha',
|
||||||
'globalCompositeOperation',
|
'globalCompositeOperation',
|
||||||
'imageSmoothingEnabled',
|
'imageSmoothingEnabled',
|
||||||
];
|
] as const;
|
||||||
|
|
||||||
const traceArrMax = 100;
|
const traceArrMax = 100;
|
||||||
/**
|
/**
|
||||||
@ -701,6 +701,11 @@ export class Context {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// supported context properties
|
||||||
|
type CanvasContextProps = Pick<CanvasRenderingContext2D, typeof CONTEXT_PROPERTIES[number]>;
|
||||||
|
|
||||||
|
export interface Context extends CanvasContextProps {};
|
||||||
|
|
||||||
CONTEXT_PROPERTIES.forEach(function (prop) {
|
CONTEXT_PROPERTIES.forEach(function (prop) {
|
||||||
Object.defineProperty(Context.prototype, prop, {
|
Object.defineProperty(Context.prototype, prop, {
|
||||||
get() {
|
get() {
|
||||||
|
@ -164,6 +164,17 @@ export const Konva = {
|
|||||||
isDragReady() {
|
isDragReady() {
|
||||||
return !!Konva['DD'].node;
|
return !!Konva['DD'].node;
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Should Konva release canvas elements on destroy. Default is true.
|
||||||
|
* Useful to avoid memory leak issues in Safari on macOS/iOS.
|
||||||
|
* @property releaseCanvasOnDestroy
|
||||||
|
* @default true
|
||||||
|
* @name releaseCanvasOnDestroy
|
||||||
|
* @memberof Konva
|
||||||
|
* @example
|
||||||
|
* Konva.releaseCanvasOnDestroy = true;
|
||||||
|
*/
|
||||||
|
releaseCanvasOnDestroy: true,
|
||||||
// user agent
|
// user agent
|
||||||
document: glob.document,
|
document: glob.document,
|
||||||
// insert Konva into global namespace (window)
|
// insert Konva into global namespace (window)
|
||||||
|
@ -468,6 +468,11 @@ export class Layer extends Container<Group | Shape> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destroy(): this {
|
||||||
|
Util.releaseCanvas(this.getNativeCanvasElement(), this.getHitCanvas()._canvas);
|
||||||
|
return super.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
hitGraphEnabled: GetSet<boolean, this>;
|
hitGraphEnabled: GetSet<boolean, this>;
|
||||||
|
|
||||||
clearBeforeDraw: GetSet<boolean, this>;
|
clearBeforeDraw: GetSet<boolean, this>;
|
||||||
|
@ -243,7 +243,12 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
|||||||
* node.clearCache();
|
* node.clearCache();
|
||||||
*/
|
*/
|
||||||
clearCache() {
|
clearCache() {
|
||||||
this._cache.delete(CANVAS);
|
if (this._cache.has(CANVAS)) {
|
||||||
|
const { scene, filter, hit } = this._cache.get(CANVAS);
|
||||||
|
Util.releaseCanvas(scene, filter, hit);
|
||||||
|
this._cache.delete(CANVAS);
|
||||||
|
}
|
||||||
|
|
||||||
this._clearSelfAndDescendantCache();
|
this._clearSelfAndDescendantCache();
|
||||||
this._requestDraw();
|
this._requestDraw();
|
||||||
return this;
|
return this;
|
||||||
@ -853,6 +858,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
|||||||
*/
|
*/
|
||||||
destroy() {
|
destroy() {
|
||||||
this.remove();
|
this.remove();
|
||||||
|
this.clearCache();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -278,6 +278,9 @@ export class Stage extends Container<Layer> {
|
|||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
stages.splice(index, 1);
|
stages.splice(index, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Util.releaseCanvas(this.bufferCanvas._canvas, this.bufferHitCanvas._canvas)
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -957,4 +957,12 @@ export const Util = {
|
|||||||
return evt.changedTouches[0].identifier;
|
return evt.changedTouches[0].identifier;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
releaseCanvas(...canvases: HTMLCanvasElement[]) {
|
||||||
|
if (!Konva.releaseCanvasOnDestroy) return;
|
||||||
|
|
||||||
|
canvases.forEach(c => {
|
||||||
|
c.width = 0;
|
||||||
|
c.height = 0;
|
||||||
|
})
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@ -197,7 +197,7 @@ export const Kaleidoscope: Filter = function (imageData) {
|
|||||||
var scratchData = tempCanvas
|
var scratchData = tempCanvas
|
||||||
.getContext('2d')
|
.getContext('2d')
|
||||||
.getImageData(0, 0, xSize, ySize);
|
.getImageData(0, 0, xSize, ySize);
|
||||||
|
Util.releaseCanvas(tempCanvas);
|
||||||
// Convert thhe original to polar coordinates
|
// Convert thhe original to polar coordinates
|
||||||
ToPolar(imageData, scratchData, {
|
ToPolar(imageData, scratchData, {
|
||||||
polarCenterX: xSize / 2,
|
polarCenterX: xSize / 2,
|
||||||
|
@ -533,6 +533,10 @@ export class TextPath extends Shape<TextPathConfig> {
|
|||||||
height: maxY - minY + fontSize,
|
height: maxY - minY + fontSize,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
destroy(): this {
|
||||||
|
Util.releaseCanvas(this.dummyCanvas);
|
||||||
|
return super.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
fontFamily: GetSet<string, this>;
|
fontFamily: GetSet<string, this>;
|
||||||
fontSize: GetSet<number, this>;
|
fontSize: GetSet<number, this>;
|
||||||
|
@ -57,7 +57,7 @@ describe('Context', function () {
|
|||||||
'textBaseline',
|
'textBaseline',
|
||||||
'globalAlpha',
|
'globalAlpha',
|
||||||
'globalCompositeOperation',
|
'globalCompositeOperation',
|
||||||
];
|
] as const;
|
||||||
|
|
||||||
it('context wrapper should work like native context', function () {
|
it('context wrapper should work like native context', function () {
|
||||||
var stage = addStage();
|
var stage = addStage();
|
||||||
@ -108,10 +108,10 @@ describe('Context', function () {
|
|||||||
|
|
||||||
// test get
|
// test get
|
||||||
nativeContext.fillStyle = '#ff0000';
|
nativeContext.fillStyle = '#ff0000';
|
||||||
assert.equal(context['fillStyle'], '#ff0000');
|
assert.equal(context.fillStyle, '#ff0000');
|
||||||
|
|
||||||
// test set
|
// test set
|
||||||
context['globalAlpha'] = 0.5;
|
context.globalAlpha = 0.5;
|
||||||
assert.equal(context['globalAlpha'], 0.5);
|
assert.equal(context.globalAlpha, 0.5);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user