Merge branch 'master' of github.com:konvajs/konva into master

This commit is contained in:
Anton Lavrenov 2023-07-26 12:10:07 -05:00
commit 4e28e1a322
6 changed files with 118 additions and 56 deletions

View File

@ -3,7 +3,7 @@ import { Layer } from './Layer';
import { IFrame, AnimationFn } from './types'; import { IFrame, AnimationFn } from './types';
import { Util } from './Util'; import { Util } from './Util';
var now = (function (): () => number { const now = (function (): () => number {
if (glob.performance && glob.performance.now) { if (glob.performance && glob.performance.now) {
return function () { return function () {
return glob.performance.now(); return glob.performance.now();
@ -61,21 +61,12 @@ export class Animation {
* @param {Konva.Layer|Array} [layers] layer(s) to be redrawn. Can be a layer, an array of layers, or null. Not specifying a node will result in no redraw. * @param {Konva.Layer|Array} [layers] layer(s) to be redrawn. Can be a layer, an array of layers, or null. Not specifying a node will result in no redraw.
* @return {Konva.Animation} this * @return {Konva.Animation} this
*/ */
setLayers(layers) { setLayers(layers:null | Layer | Layer[]) {
var lays = []; let lays: Layer[] = [];
// if passing in no layers // if passing in no layers
if (!layers) { if (layers) {
lays = []; lays = Array.isArray(layers)? layers : [layers]
} else if (layers.length > 0) {
// if passing in an array of Layers
// NOTE: layers could be an array. for simplicity, I'm just inspecting
// the length property to check for both cases
lays = layers;
} else {
// if passing in a Layer
lays = [layers];
} }
this.layers = lays; this.layers = lays;
return this; return this;
} }
@ -95,13 +86,12 @@ export class Animation {
* @param {Konva.Layer} layer to add * @param {Konva.Layer} layer to add
* @return {Bool} true if layer is added to animation, otherwise false * @return {Bool} true if layer is added to animation, otherwise false
*/ */
addLayer(layer) { addLayer(layer: Layer) {
var layers = this.layers, const layers = this.layers
len = layers.length, const len = layers.length
n;
// don't add the layer if it already exists // don't add the layer if it already exists
for (n = 0; n < len; n++) { for (let n = 0; n < len; n++) {
if (layers[n]._id === layer._id) { if (layers[n]._id === layer._id) {
return false; return false;
} }
@ -117,12 +107,11 @@ export class Animation {
* @return {Bool} is animation running? * @return {Bool} is animation running?
*/ */
isRunning() { isRunning() {
var a = Animation, const a = Animation
animations = a.animations, const animations = a.animations
len = animations.length, const len = animations.length
n;
for (n = 0; n < len; n++) { for (let n = 0; n < len; n++) {
if (animations[n].id === this.id) { if (animations[n].id === this.id) {
return true; return true;
} }
@ -152,7 +141,7 @@ export class Animation {
Animation._removeAnimation(this); Animation._removeAnimation(this);
return this; return this;
} }
_updateFrameObject(time) { _updateFrameObject(time: number) {
this.frame.timeDiff = time - this.frame.lastTime; this.frame.timeDiff = time - this.frame.lastTime;
this.frame.lastTime = time; this.frame.lastTime = time;
this.frame.time += this.frame.timeDiff; this.frame.time += this.frame.timeDiff;
@ -168,12 +157,11 @@ export class Animation {
this._handleAnimation(); this._handleAnimation();
} }
static _removeAnimation(anim) { static _removeAnimation(anim) {
var id = anim.id, const id = anim.id
animations = this.animations, const animations = this.animations
len = animations.length, const len = animations.length
n;
for (n = 0; n < len; n++) { for (let n = 0; n < len; n++) {
if (animations[n].id === id) { if (animations[n].id === id) {
this.animations.splice(n, 1); this.animations.splice(n, 1);
break; break;
@ -182,17 +170,8 @@ export class Animation {
} }
static _runFrames() { static _runFrames() {
var layerHash = {}, const layerHash = {}
animations = this.animations, const animations = this.animations
anim,
layers,
func,
n,
i,
layersLen,
layer,
key,
needRedraw;
/* /*
* loop through all animations and execute animation * loop through all animations and execute animation
* function. if the animation object has specified node, * function. if the animation object has specified node,
@ -205,15 +184,16 @@ export class Animation {
* the for loop is running, causing a JS error * the for loop is running, causing a JS error
*/ */
for (n = 0; n < animations.length; n++) { for (let n = 0; n < animations.length; n++) {
anim = animations[n]; const anim = animations[n];
layers = anim.layers; const layers = anim.layers;
func = anim.func; const func = anim.func;
anim._updateFrameObject(now()); anim._updateFrameObject(now());
layersLen = layers.length; const layersLen = layers.length;
// if animation object has a function, execute it // if animation object has a function, execute it
let needRedraw
if (func) { if (func) {
// allow anim bypassing drawing // allow anim bypassing drawing
needRedraw = func.call(anim, anim.frame) !== false; needRedraw = func.call(anim, anim.frame) !== false;
@ -223,8 +203,8 @@ export class Animation {
if (!needRedraw) { if (!needRedraw) {
continue; continue;
} }
for (i = 0; i < layersLen; i++) { for (let i = 0; i < layersLen; i++) {
layer = layers[i]; const layer = layers[i];
if (layer._id !== undefined) { if (layer._id !== undefined) {
layerHash[layer._id] = layer; layerHash[layer._id] = layer;
@ -232,7 +212,7 @@ export class Animation {
} }
} }
for (key in layerHash) { for (let key in layerHash) {
if (!layerHash.hasOwnProperty(key)) { if (!layerHash.hasOwnProperty(key)) {
continue; continue;
} }
@ -240,7 +220,7 @@ export class Animation {
} }
} }
static _animationLoop() { static _animationLoop() {
var Anim = Animation; const Anim = Animation;
if (Anim.animations.length) { if (Anim.animations.length) {
Anim._runFrames(); Anim._runFrames();
Util.requestAnimFrame(Anim._animationLoop); Util.requestAnimFrame(Anim._animationLoop);

View File

@ -220,7 +220,7 @@ export abstract class Container<
* return node.getType() === 'Shape' * return node.getType() === 'Shape'
* }) * })
*/ */
findOne<ChildNode extends Node = Node>(selector: string | Function) { findOne<ChildNode extends Node = Node>(selector: string | Function): ChildNode | undefined {
var result = this._generalFind<ChildNode>(selector, true); var result = this._generalFind<ChildNode>(selector, true);
return result.length > 0 ? result[0] : undefined; return result.length > 0 ? result[0] : undefined;
} }

View File

@ -9,7 +9,7 @@
* *
* @license * @license
*/ */
var PI_OVER_180 = Math.PI / 180; const PI_OVER_180 = Math.PI / 180;
/** /**
* @namespace Konva * @namespace Konva
*/ */

View File

@ -2011,7 +2011,7 @@ Factory.addGetterSetter(Shape, 'fillRule', undefined, getStringValidator());
* var fillRule = shape.fillRule(); * var fillRule = shape.fillRule();
* *
* // set fill rule * // set fill rule
* shape.fillRule('evenodd); * shape.fillRule('evenodd');
*/ */
Factory.backCompat(Shape, { Factory.backCompat(Shape, {

View File

@ -21,6 +21,7 @@ export interface TransformerConfig extends ContainerConfig {
rotationSnaps?: Array<number>; rotationSnaps?: Array<number>;
rotationSnapTolerance?: number; rotationSnapTolerance?: number;
rotateAnchorOffset?: number; rotateAnchorOffset?: number;
rotateAnchorCursor?: string,
borderEnabled?: boolean; borderEnabled?: boolean;
borderStroke?: string; borderStroke?: string;
borderStrokeWidth?: number; borderStrokeWidth?: number;
@ -93,9 +94,9 @@ var ANGLES = {
const TOUCH_DEVICE = 'ontouchstart' in Konva._global; const TOUCH_DEVICE = 'ontouchstart' in Konva._global;
function getCursor(anchorName, rad) { function getCursor(anchorName, rad, rotateCursor) {
if (anchorName === 'rotater') { if (anchorName === 'rotater') {
return 'crosshair'; return rotateCursor;
} }
rad += Util.degToRad(ANGLES[anchorName] || 0); rad += Util.degToRad(ANGLES[anchorName] || 0);
@ -207,6 +208,7 @@ function getSnap(snaps: Array<number>, newRotationRad: number, tol: number) {
* @param {Array} [config.rotationSnaps] Array of angles for rotation snaps. Default is [] * @param {Array} [config.rotationSnaps] Array of angles for rotation snaps. Default is []
* @param {Number} [config.rotationSnapTolerance] Snapping tolerance. If closer than this it will snap. Default is 5 * @param {Number} [config.rotationSnapTolerance] Snapping tolerance. If closer than this it will snap. Default is 5
* @param {Number} [config.rotateAnchorOffset] Default is 50 * @param {Number} [config.rotateAnchorOffset] Default is 50
* @param {String} [config.rotateAnchorCursor] Default is crosshair
* @param {Number} [config.padding] Default is 0 * @param {Number} [config.padding] Default is 0
* @param {Boolean} [config.borderEnabled] Should we draw border? Default is true * @param {Boolean} [config.borderEnabled] Should we draw border? Default is true
* @param {String} [config.borderStroke] Border stroke color * @param {String} [config.borderStroke] Border stroke color
@ -581,7 +583,8 @@ export class Transformer extends Group {
// add hover styling // add hover styling
anchor.on('mouseenter', () => { anchor.on('mouseenter', () => {
var rad = Konva.getAngle(this.rotation()); var rad = Konva.getAngle(this.rotation());
var cursor = getCursor(name, rad); var rotateCursor = this.rotateAnchorCursor();
var cursor = getCursor(name, rad, rotateCursor);
anchor.getStage().content && anchor.getStage().content &&
(anchor.getStage().content.style.cursor = cursor); (anchor.getStage().content.style.cursor = cursor);
this._cursorChange = true; this._cursorChange = true;
@ -1289,6 +1292,7 @@ export class Transformer extends Group {
rotateEnabled: GetSet<boolean, this>; rotateEnabled: GetSet<boolean, this>;
rotateAnchorOffset: GetSet<number, this>; rotateAnchorOffset: GetSet<number, this>;
rotationSnapTolerance: GetSet<number, this>; rotationSnapTolerance: GetSet<number, this>;
rotateAnchorCursor: GetSet<string, this>;
padding: GetSet<number, this>; padding: GetSet<number, this>;
borderEnabled: GetSet<boolean, this>; borderEnabled: GetSet<boolean, this>;
borderStroke: GetSet<string, this>; borderStroke: GetSet<string, this>;
@ -1454,6 +1458,21 @@ Factory.addGetterSetter(
getNumberValidator() getNumberValidator()
); );
/**
* get/set rotation anchor cursor
* @name Konva.Transformer#rotateAnchorCursor
* @method
* @param {String} cursorName
* @returns {String}
* @example
* // get
* var currentRotationAnchorCursor = transformer.rotateAnchorCursor();
*
* // set
* transformer.rotateAnchorCursor('grab');
*/
Factory.addGetterSetter(Transformer, 'rotateAnchorCursor', 'crosshair');
/** /**
* get/set distance for rotation tolerance * get/set distance for rotation tolerance
* @name Konva.Transformer#rotationSnapTolerance * @name Konva.Transformer#rotationSnapTolerance

View File

@ -2334,6 +2334,69 @@ describe('Transformer', function () {
assert.equal(stage.content.style.cursor, 'nwse-resize'); assert.equal(stage.content.style.cursor, 'nwse-resize');
}); });
it('check default cursor transformer', function () {
if (isNode) {
return;
}
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 50,
y: 50,
draggable: true,
width: 100,
height: 100,
fill: 'yellow',
});
layer.add(rect);
var tr = new Konva.Transformer({
nodes: [rect]
});
layer.add(tr);
layer.draw();
sm(stage, {
x: 100,
y: 0,
});
assert.equal(stage.content.style.cursor, 'crosshair');
});
it('using custom cursor on configured transformer should show custom cursor instead of crosshair', function () {
if (isNode) {
return;
}
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
var rect = new Konva.Rect({
x: 50,
y: 50,
draggable: true,
width: 100,
height: 100,
fill: 'yellow',
});
layer.add(rect);
var tr = new Konva.Transformer({
nodes: [rect],
rotateAnchorCursor: 'grab'
});
layer.add(tr);
layer.draw();
sm(stage, {
x: 100,
y: 0,
});
assert.equal(stage.content.style.cursor, 'grab');
});
it('changing parent transform should recalculate transformer attrs', function () { it('changing parent transform should recalculate transformer attrs', function () {
var stage = addStage(); var stage = addStage();
var layer = new Konva.Layer(); var layer = new Konva.Layer();