mirror of
https://github.com/konvajs/konva.git
synced 2025-06-28 06:31:15 +08:00
Merge branch 'master' into config-window-global
This commit is contained in:
commit
0a5c510ade
10
CHANGELOG.md
10
CHANGELOG.md
@ -3,6 +3,16 @@
|
|||||||
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/).
|
||||||
|
|
||||||
|
### 8.3.14 (2022-11-09)
|
||||||
|
|
||||||
|
- Automatically release (destroy) used canvas elements. Should fix safari memory issues
|
||||||
|
|
||||||
|
### 8.3.13 (2022-10-03)
|
||||||
|
|
||||||
|
- Typescript fixes
|
||||||
|
- Better non-passive events usage
|
||||||
|
- Better 2d context usage to avoid Chrome warnings
|
||||||
|
|
||||||
### 8.3.12 (2022-08-29)
|
### 8.3.12 (2022-08-29)
|
||||||
|
|
||||||
- `ellipsis` fixes for `Konva.Text`
|
- `ellipsis` fixes for `Konva.Text`
|
||||||
|
6
konva.min.js
vendored
6
konva.min.js
vendored
File diff suppressed because one or more lines are too long
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "konva",
|
"name": "konva",
|
||||||
"version": "8.3.12",
|
"version": "8.3.14",
|
||||||
"author": "Anton Lavrenov",
|
"author": "Anton Lavrenov",
|
||||||
"files": [
|
"files": [
|
||||||
"README.md",
|
"README.md",
|
||||||
|
@ -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;
|
||||||
/**
|
/**
|
||||||
@ -118,7 +118,6 @@ export class Context {
|
|||||||
|
|
||||||
constructor(canvas: Canvas) {
|
constructor(canvas: Canvas) {
|
||||||
this.canvas = canvas;
|
this.canvas = canvas;
|
||||||
this._context = canvas._canvas.getContext('2d') as CanvasRenderingContext2D;
|
|
||||||
|
|
||||||
if (Konva.enableTrace) {
|
if (Konva.enableTrace) {
|
||||||
this.traceArr = [];
|
this.traceArr = [];
|
||||||
@ -702,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() {
|
||||||
@ -714,6 +718,10 @@ CONTEXT_PROPERTIES.forEach(function (prop) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
export class SceneContext extends Context {
|
export class SceneContext extends Context {
|
||||||
|
constructor(canvas: Canvas) {
|
||||||
|
super(canvas);
|
||||||
|
this._context = canvas._canvas.getContext('2d') as CanvasRenderingContext2D;
|
||||||
|
}
|
||||||
_fillColor(shape: Shape) {
|
_fillColor(shape: Shape) {
|
||||||
var fill = shape.fill();
|
var fill = shape.fill();
|
||||||
|
|
||||||
@ -853,6 +861,12 @@ export class SceneContext extends Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class HitContext extends Context {
|
export class HitContext extends Context {
|
||||||
|
constructor(canvas: Canvas) {
|
||||||
|
super(canvas);
|
||||||
|
this._context = canvas._canvas.getContext('2d', {
|
||||||
|
willReadFrequently: true,
|
||||||
|
}) as CanvasRenderingContext2D;
|
||||||
|
}
|
||||||
_fill(shape) {
|
_fill(shape) {
|
||||||
this.save();
|
this.save();
|
||||||
this.setAttr('fillStyle', shape.colorKey);
|
this.setAttr('fillStyle', shape.colorKey);
|
||||||
|
@ -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>;
|
||||||
|
10
src/Node.ts
10
src/Node.ts
@ -57,7 +57,7 @@ export interface NodeConfig {
|
|||||||
listening?: boolean;
|
listening?: boolean;
|
||||||
id?: string;
|
id?: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
opacity?: Number;
|
opacity?: number;
|
||||||
scale?: Vector2d;
|
scale?: Vector2d;
|
||||||
scaleX?: number;
|
scaleX?: number;
|
||||||
scaleY?: number;
|
scaleY?: number;
|
||||||
@ -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;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
13
src/Stage.ts
13
src/Stage.ts
@ -280,6 +280,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;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -461,9 +464,13 @@ export class Stage extends Container<Layer> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
EVENTS.forEach(([event, methodName]) => {
|
EVENTS.forEach(([event, methodName]) => {
|
||||||
this.content.addEventListener(event, (evt) => {
|
this.content.addEventListener(
|
||||||
this[methodName](evt);
|
event,
|
||||||
});
|
(evt) => {
|
||||||
|
this[methodName](evt);
|
||||||
|
},
|
||||||
|
{ passive: false }
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
_pointerenter(evt) {
|
_pointerenter(evt) {
|
||||||
|
@ -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,
|
||||||
|
@ -7,7 +7,6 @@ import { _registerNode } from '../Global';
|
|||||||
export interface RingConfig extends ShapeConfig {
|
export interface RingConfig extends ShapeConfig {
|
||||||
innerRadius: number;
|
innerRadius: number;
|
||||||
outerRadius: number;
|
outerRadius: number;
|
||||||
clockwise?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var PIx2 = Math.PI * 2;
|
var PIx2 = Math.PI * 2;
|
||||||
@ -19,7 +18,6 @@ var PIx2 = Math.PI * 2;
|
|||||||
* @param {Object} config
|
* @param {Object} config
|
||||||
* @param {Number} config.innerRadius
|
* @param {Number} config.innerRadius
|
||||||
* @param {Number} config.outerRadius
|
* @param {Number} config.outerRadius
|
||||||
* @param {Boolean} [config.clockwise]
|
|
||||||
* @@shapeParams
|
* @@shapeParams
|
||||||
* @@nodeParams
|
* @@nodeParams
|
||||||
* @example
|
* @example
|
||||||
|
@ -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>;
|
||||||
|
@ -1327,8 +1327,8 @@ Factory.addGetterSetter(
|
|||||||
* get/set resize ability. If false it will automatically hide resizing handlers
|
* get/set resize ability. If false it will automatically hide resizing handlers
|
||||||
* @name Konva.Transformer#resizeEnabled
|
* @name Konva.Transformer#resizeEnabled
|
||||||
* @method
|
* @method
|
||||||
* @param {Array} array
|
* @param {Boolean} enabled
|
||||||
* @returns {Array}
|
* @returns {Boolean}
|
||||||
* @example
|
* @example
|
||||||
* // get
|
* // get
|
||||||
* var resizeEnabled = transformer.resizeEnabled();
|
* var resizeEnabled = transformer.resizeEnabled();
|
||||||
@ -1339,9 +1339,9 @@ Factory.addGetterSetter(
|
|||||||
Factory.addGetterSetter(Transformer, 'resizeEnabled', true);
|
Factory.addGetterSetter(Transformer, 'resizeEnabled', true);
|
||||||
/**
|
/**
|
||||||
* get/set anchor size. Default is 10
|
* get/set anchor size. Default is 10
|
||||||
* @name Konva.Transformer#validateAnchors
|
* @name Konva.Transformer#anchorSize
|
||||||
* @method
|
* @method
|
||||||
* @param {Number} 10
|
* @param {Number} size
|
||||||
* @returns {Number}
|
* @returns {Number}
|
||||||
* @example
|
* @example
|
||||||
* // get
|
* // get
|
||||||
@ -1441,8 +1441,8 @@ Factory.addGetterSetter(Transformer, 'borderEnabled', true);
|
|||||||
* get/set anchor stroke color
|
* get/set anchor stroke color
|
||||||
* @name Konva.Transformer#anchorStroke
|
* @name Konva.Transformer#anchorStroke
|
||||||
* @method
|
* @method
|
||||||
* @param {Boolean} enabled
|
* @param {String} strokeColor
|
||||||
* @returns {Boolean}
|
* @returns {String}
|
||||||
* @example
|
* @example
|
||||||
* // get
|
* // get
|
||||||
* var anchorStroke = transformer.anchorStroke();
|
* var anchorStroke = transformer.anchorStroke();
|
||||||
@ -1456,8 +1456,8 @@ Factory.addGetterSetter(Transformer, 'anchorStroke', 'rgb(0, 161, 255)');
|
|||||||
* get/set anchor stroke width
|
* get/set anchor stroke width
|
||||||
* @name Konva.Transformer#anchorStrokeWidth
|
* @name Konva.Transformer#anchorStrokeWidth
|
||||||
* @method
|
* @method
|
||||||
* @param {Boolean} enabled
|
* @param {Number} anchorStrokeWidth
|
||||||
* @returns {Boolean}
|
* @returns {Number}
|
||||||
* @example
|
* @example
|
||||||
* // get
|
* // get
|
||||||
* var anchorStrokeWidth = transformer.anchorStrokeWidth();
|
* var anchorStrokeWidth = transformer.anchorStrokeWidth();
|
||||||
@ -1476,8 +1476,8 @@ Factory.addGetterSetter(
|
|||||||
* get/set anchor fill color
|
* get/set anchor fill color
|
||||||
* @name Konva.Transformer#anchorFill
|
* @name Konva.Transformer#anchorFill
|
||||||
* @method
|
* @method
|
||||||
* @param {Boolean} enabled
|
* @param {String} anchorFill
|
||||||
* @returns {Boolean}
|
* @returns {String}
|
||||||
* @example
|
* @example
|
||||||
* // get
|
* // get
|
||||||
* var anchorFill = transformer.anchorFill();
|
* var anchorFill = transformer.anchorFill();
|
||||||
@ -1491,7 +1491,7 @@ Factory.addGetterSetter(Transformer, 'anchorFill', 'white');
|
|||||||
* get/set anchor corner radius
|
* get/set anchor corner radius
|
||||||
* @name Konva.Transformer#anchorCornerRadius
|
* @name Konva.Transformer#anchorCornerRadius
|
||||||
* @method
|
* @method
|
||||||
* @param {Number} enabled
|
* @param {Number} radius
|
||||||
* @returns {Number}
|
* @returns {Number}
|
||||||
* @example
|
* @example
|
||||||
* // get
|
* // get
|
||||||
@ -1526,8 +1526,8 @@ Factory.addGetterSetter(Transformer, 'borderStroke', 'rgb(0, 161, 255)');
|
|||||||
* get/set border stroke width
|
* get/set border stroke width
|
||||||
* @name Konva.Transformer#borderStrokeWidth
|
* @name Konva.Transformer#borderStrokeWidth
|
||||||
* @method
|
* @method
|
||||||
* @param {Boolean} enabled
|
* @param {Number} strokeWidth
|
||||||
* @returns {Boolean}
|
* @returns {Number}
|
||||||
* @example
|
* @example
|
||||||
* // get
|
* // get
|
||||||
* var borderStrokeWidth = transformer.borderStrokeWidth();
|
* var borderStrokeWidth = transformer.borderStrokeWidth();
|
||||||
@ -1546,8 +1546,8 @@ Factory.addGetterSetter(
|
|||||||
* get/set border dash array
|
* get/set border dash array
|
||||||
* @name Konva.Transformer#borderDash
|
* @name Konva.Transformer#borderDash
|
||||||
* @method
|
* @method
|
||||||
* @param {Boolean} enabled
|
* @param {Array} dash array
|
||||||
* @returns {Boolean}
|
* @returns {Array}
|
||||||
* @example
|
* @example
|
||||||
* // get
|
* // get
|
||||||
* var borderDash = transformer.borderDash();
|
* var borderDash = transformer.borderDash();
|
||||||
|
@ -45,10 +45,13 @@
|
|||||||
fill: 'red',
|
fill: 'red',
|
||||||
});
|
});
|
||||||
layer.add(rect);
|
layer.add(rect);
|
||||||
|
stage.on('wheel', (e) => {
|
||||||
document.body.onclick = () => {
|
e.evt.preventDefault();
|
||||||
alert('click');
|
console.log('wheel');
|
||||||
};
|
});
|
||||||
|
stage.on('contextmenu', (e) => {
|
||||||
|
console.log('click');
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -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