Merge remote-tracking branch 'upstream/master' into change-text-paths

This commit is contained in:
gtktsc 2023-03-24 20:00:26 +01:00
commit c759ec43be
24 changed files with 196 additions and 123 deletions

View File

@ -3,6 +3,11 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
### 8.4.3 (2023-03-23)
- Typescript fixes
- Better validation for `Konva.Transfomer` `nodes` property
### 8.4.2 (2023-01-20)
- Fix justify on text with limited height

View File

@ -5,10 +5,10 @@
})(this, (function () { 'use strict';
/*
* Konva JavaScript Framework v8.4.2
* Konva JavaScript Framework v8.4.3
* http://konvajs.org/
* Licensed under the MIT
* Date: Fri Jan 20 2023
* Date: Thu Mar 23 2023
*
* Original work Copyright (C) 2011 - 2013 by Eric Rowell (KineticJS)
* Modified work Copyright (C) 2014 - present by Anton Lavrenov (Konva)
@ -35,7 +35,7 @@
: {};
const Konva$2 = {
_global: glob,
version: '8.4.2',
version: '8.4.3',
isBrowser: detectBrowser(),
isUnminified: /param/.test(function (param) { }.toString()),
dblClickWindow: 400,
@ -1652,7 +1652,7 @@
}
}
_applyLineCap(shape) {
var lineCap = shape.getLineCap();
const lineCap = shape.attrs.lineCap;
if (lineCap) {
this.setAttr('lineCap', lineCap);
}
@ -1664,7 +1664,7 @@
}
}
_applyLineJoin(shape) {
var lineJoin = shape.attrs.lineJoin;
const lineJoin = shape.attrs.lineJoin;
if (lineJoin) {
this.setAttr('lineJoin', lineJoin);
}
@ -2081,30 +2081,30 @@
}
}
_fillRadialGradient(shape) {
var grd = shape._getRadialGradient();
const grd = shape._getRadialGradient();
if (grd) {
this.setAttr('fillStyle', grd);
shape._fillFunc(this);
}
}
_fill(shape) {
var hasColor = shape.fill(), fillPriority = shape.getFillPriority();
const hasColor = shape.fill(), fillPriority = shape.getFillPriority();
// priority fills
if (hasColor && fillPriority === 'color') {
this._fillColor(shape);
return;
}
var hasPattern = shape.getFillPatternImage();
const hasPattern = shape.getFillPatternImage();
if (hasPattern && fillPriority === 'pattern') {
this._fillPattern(shape);
return;
}
var hasLinearGradient = shape.getFillLinearGradientColorStops();
const hasLinearGradient = shape.getFillLinearGradientColorStops();
if (hasLinearGradient && fillPriority === 'linear-gradient') {
this._fillLinearGradient(shape);
return;
}
var hasRadialGradient = shape.getFillRadialGradientColorStops();
const hasRadialGradient = shape.getFillRadialGradientColorStops();
if (hasRadialGradient && fillPriority === 'radial-gradient') {
this._fillRadialGradient(shape);
return;
@ -2124,7 +2124,7 @@
}
}
_strokeLinearGradient(shape) {
var start = shape.getStrokeLinearGradientStartPoint(), end = shape.getStrokeLinearGradientEndPoint(), colorStops = shape.getStrokeLinearGradientColorStops(), grd = this.createLinearGradient(start.x, start.y, end.x, end.y);
const start = shape.getStrokeLinearGradientStartPoint(), end = shape.getStrokeLinearGradientEndPoint(), colorStops = shape.getStrokeLinearGradientColorStops(), grd = this.createLinearGradient(start.x, start.y, end.x, end.y);
if (colorStops) {
// build color stops
for (var n = 0; n < colorStops.length; n += 2) {
@ -2198,7 +2198,7 @@
_stroke(shape) {
if (shape.hasHitStroke()) {
// ignore strokeScaleEnabled for Text
var strokeScaleEnabled = shape.getStrokeScaleEnabled();
const strokeScaleEnabled = shape.getStrokeScaleEnabled();
if (!strokeScaleEnabled) {
this.save();
var pixelRatio = this.getCanvas().getPixelRatio();
@ -14893,7 +14893,15 @@
if (this._nodes && this._nodes.length) {
this.detach();
}
this._nodes = nodes;
const filteredNodes = nodes.filter((node) => {
// check if ancestor of the transformer
if (node.isAncestorOf(this)) {
Util.error('Konva.Transformer cannot be an a child of the node you are trying to attach');
return false;
}
return true;
});
this._nodes = nodes = filteredNodes;
if (nodes.length === 1 && this.useSingleNodeRotation()) {
this.rotation(nodes[0].getAbsoluteRotation());
}
@ -14993,6 +15001,19 @@
this._nodes = [];
this._resetTransformCache();
}
/**
* bind events to the Transformer. You can use events: `transform`, `transformstart`, `transformend`, `dragstart`, `dragmove`, `dragend`
* @method
* @name Konva.Transformer#on
* @param {String} evtStr e.g. 'transform'
* @param {Function} handler The handler function. The first argument of that function is event object. Event object has `target` as main target of the event, `currentTarget` as current node listener and `evt` as native browser event.
* @returns {Konva.Transformer}
* @example
* // add click listener
* tr.on('transformstart', function() {
* console.log('transform started');
* });
*/
_resetTransformCache() {
this._clearCache(NODES_RECT);
this._clearCache('transform');

6
konva.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
{
"name": "konva",
"version": "8.4.2",
"version": "8.4.3",
"author": "Anton Lavrenov",
"files": [
"README.md",

View File

@ -1,7 +1,7 @@
import FileHound from 'filehound';
import fs from 'fs';
const files = FileHound.create().paths('./lib').ext('js').find();
const files = FileHound.create().paths('./lib').ext(['js', 'ts']).find();
files.then((filePaths) => {
filePaths.forEach((filepath) => {
@ -22,6 +22,9 @@ files.then((filePaths) => {
"import * as Canvas from 'canvas';"
);
// Handle import("./x/y/z") syntax.
text = text.replace(/(import\s*\(\s*['"])(.*)(?=['"])/g, '$1$2.js');
fs.writeFile(filepath, text, function (err) {
if (err) {
throw err;

View File

@ -3,6 +3,7 @@ import { Konva } from './Global';
import { Canvas } from './Canvas';
import { Shape } from './Shape';
import { IRect } from './types';
import type { Node } from './Node';
function simplifyArray(arr: Array<any>) {
var retArr = [],
@ -153,7 +154,7 @@ export class Context {
}
}
_stroke(shape) {
_stroke(shape: Shape) {
// abstract
}
@ -173,7 +174,7 @@ export class Context {
}
}
getTrace(relaxed?, rounded?) {
getTrace(relaxed?: boolean, rounded?: boolean) {
var traceArr = this.traceArr,
len = traceArr.length,
str = '',
@ -279,20 +280,20 @@ export class Context {
);
}
}
_applyLineCap(shape) {
var lineCap = shape.getLineCap();
_applyLineCap(shape: Shape) {
const lineCap = shape.attrs.lineCap;
if (lineCap) {
this.setAttr('lineCap', lineCap);
}
}
_applyOpacity(shape) {
_applyOpacity(shape: Node) {
var absOpacity = shape.getAbsoluteOpacity();
if (absOpacity !== 1) {
this.setAttr('globalAlpha', absOpacity);
}
}
_applyLineJoin(shape: Shape) {
var lineJoin = shape.attrs.lineJoin;
const lineJoin = shape.attrs.lineJoin;
if (lineJoin) {
this.setAttr('lineJoin', lineJoin);
}
@ -663,7 +664,7 @@ export class Context {
* @method
* @name Konva.Context#strokeText
*/
strokeText(a0: string, a1: number, a2: number, a3: number) {
strokeText(a0: string, a1: number, a2: number, a3?: number) {
this._context.strokeText(a0, a1, a2, a3);
}
/**
@ -775,11 +776,11 @@ export class SceneContext extends Context {
this.setAttr('fillStyle', fill);
shape._fillFunc(this);
}
_fillPattern(shape) {
_fillPattern(shape: Shape) {
this.setAttr('fillStyle', shape._getFillPattern());
shape._fillFunc(this);
}
_fillLinearGradient(shape) {
_fillLinearGradient(shape: Shape) {
var grd = shape._getLinearGradient();
if (grd) {
@ -787,15 +788,15 @@ export class SceneContext extends Context {
shape._fillFunc(this);
}
}
_fillRadialGradient(shape) {
var grd = shape._getRadialGradient();
_fillRadialGradient(shape: Shape) {
const grd = shape._getRadialGradient();
if (grd) {
this.setAttr('fillStyle', grd);
shape._fillFunc(this);
}
}
_fill(shape) {
var hasColor = shape.fill(),
const hasColor = shape.fill(),
fillPriority = shape.getFillPriority();
// priority fills
@ -804,19 +805,19 @@ export class SceneContext extends Context {
return;
}
var hasPattern = shape.getFillPatternImage();
const hasPattern = shape.getFillPatternImage();
if (hasPattern && fillPriority === 'pattern') {
this._fillPattern(shape);
return;
}
var hasLinearGradient = shape.getFillLinearGradientColorStops();
const hasLinearGradient = shape.getFillLinearGradientColorStops();
if (hasLinearGradient && fillPriority === 'linear-gradient') {
this._fillLinearGradient(shape);
return;
}
var hasRadialGradient = shape.getFillRadialGradientColorStops();
const hasRadialGradient = shape.getFillRadialGradientColorStops();
if (hasRadialGradient && fillPriority === 'radial-gradient') {
this._fillRadialGradient(shape);
return;
@ -834,7 +835,7 @@ export class SceneContext extends Context {
}
}
_strokeLinearGradient(shape) {
var start = shape.getStrokeLinearGradientStartPoint(),
const start = shape.getStrokeLinearGradientStartPoint(),
end = shape.getStrokeLinearGradientEndPoint(),
colorStops = shape.getStrokeLinearGradientColorStops(),
grd = this.createLinearGradient(start.x, start.y, end.x, end.y);
@ -842,7 +843,7 @@ export class SceneContext extends Context {
if (colorStops) {
// build color stops
for (var n = 0; n < colorStops.length; n += 2) {
grd.addColorStop(colorStops[n], colorStops[n + 1]);
grd.addColorStop(colorStops[n] as number, colorStops[n + 1] as string);
}
this.setAttr('strokeStyle', grd);
}
@ -914,7 +915,7 @@ export class HitContext extends Context {
willReadFrequently: true,
}) as CanvasRenderingContext2D;
}
_fill(shape) {
_fill(shape: Shape) {
this.save();
this.setAttr('fillStyle', shape.colorKey);
shape._fillFuncHit(this);
@ -928,7 +929,7 @@ export class HitContext extends Context {
_stroke(shape) {
if (shape.hasHitStroke()) {
// ignore strokeScaleEnabled for Text
var strokeScaleEnabled = shape.getStrokeScaleEnabled();
const strokeScaleEnabled = shape.getStrokeScaleEnabled();
if (!strokeScaleEnabled) {
this.save();
var pixelRatio = this.getCanvas().getPixelRatio();

View File

@ -820,6 +820,8 @@ export class Shape<
strokeHitEnabled: GetSet<boolean, this>;
strokeWidth: GetSet<number, this>;
hitStrokeWidth: GetSet<number | 'auto', this>;
strokeLinearGradientStartPoint: GetSet<Vector2d, this>;
strokeLinearGradientEndPoint: GetSet<Vector2d, this>;
strokeLinearGradientColorStops: GetSet<Array<number | string>, this>;
}

View File

@ -4,7 +4,7 @@ import { Konva } from '../Global';
import { GetSet } from '../types';
import { getNumberValidator, getBooleanValidator } from '../Validators';
import { _registerNode } from '../Global';
import { Transform, Util } from '../Util';
import { Context } from '../Context';
export interface ArcConfig extends ShapeConfig {
angle: number;
@ -38,7 +38,7 @@ export interface ArcConfig extends ShapeConfig {
* });
*/
export class Arc extends Shape<ArcConfig> {
_sceneFunc(context) {
_sceneFunc(context: Context) {
var angle = Konva.getAngle(this.angle()),
clockwise = this.clockwise();
@ -54,10 +54,10 @@ export class Arc extends Shape<ArcConfig> {
getHeight() {
return this.outerRadius() * 2;
}
setWidth(width) {
setWidth(width: number) {
this.outerRadius(width / 2);
}
setHeight(height) {
setHeight(height: number) {
this.outerRadius(height / 2);
}

View File

@ -4,6 +4,7 @@ import { GetSet } from '../types';
import { getNumberValidator } from '../Validators';
import { _registerNode } from '../Global';
import { Path } from './Path';
import { Context } from '../Context';
export interface ArrowConfig extends LineConfig {
points: number[];
@ -40,7 +41,7 @@ export interface ArrowConfig extends LineConfig {
* });
*/
export class Arrow extends Line<ArrowConfig> {
_sceneFunc(ctx) {
_sceneFunc(ctx: Context) {
super._sceneFunc(ctx);
var PI2 = Math.PI * 2;
var points = this.points();
@ -126,7 +127,7 @@ export class Arrow extends Line<ArrowConfig> {
}
}
__fillStroke(ctx) {
__fillStroke(ctx: Context) {
// here is a tricky part
// we need to disable dash for arrow pointers
var isDashEnabled = this.dashEnabled();

View File

@ -3,6 +3,7 @@ import { Shape, ShapeConfig } from '../Shape';
import { GetSet } from '../types';
import { getNumberValidator } from '../Validators';
import { _registerNode } from '../Global';
import { Context } from '../Context';
export interface CircleConfig extends ShapeConfig {
radius?: number;
@ -27,7 +28,7 @@ export interface CircleConfig extends ShapeConfig {
* });
*/
export class Circle extends Shape<CircleConfig> {
_sceneFunc(context) {
_sceneFunc(context: Context) {
context.beginPath();
context.arc(0, 0, this.attrs.radius || 0, 0, Math.PI * 2, false);
context.closePath();
@ -39,12 +40,12 @@ export class Circle extends Shape<CircleConfig> {
getHeight() {
return this.radius() * 2;
}
setWidth(width) {
setWidth(width: number) {
if (this.radius() !== width / 2) {
this.radius(width / 2);
}
}
setHeight(height) {
setHeight(height: number) {
if (this.radius() !== height / 2) {
this.radius(height / 2);
}

View File

@ -2,6 +2,7 @@ import { Factory } from '../Factory';
import { Shape, ShapeConfig } from '../Shape';
import { getNumberValidator } from '../Validators';
import { _registerNode } from '../Global';
import { Context } from '../Context';
import { GetSet, Vector2d } from '../types';
@ -29,7 +30,7 @@ export interface EllipseConfig extends ShapeConfig {
* });
*/
export class Ellipse extends Shape<EllipseConfig> {
_sceneFunc(context) {
_sceneFunc(context: Context) {
var rx = this.radiusX(),
ry = this.radiusY();
@ -49,10 +50,10 @@ export class Ellipse extends Shape<EllipseConfig> {
getHeight() {
return this.radiusY() * 2;
}
setWidth(width) {
setWidth(width: number) {
this.radiusX(width / 2);
}
setHeight(height) {
setHeight(height: number) {
this.radiusY(height / 2);
}

View File

@ -111,7 +111,7 @@ export class Image extends Shape<ImageConfig> {
}
// If you need to draw later, you need to execute save/restore
}
_hitFunc(context) {
_hitFunc(context: Context) {
var width = this.width(),
height = this.height(),
cornerRadius = this.cornerRadius();
@ -146,7 +146,7 @@ export class Image extends Shape<ImageConfig> {
* layer.draw();
* });
*/
static fromURL(url, callback, onError = null) {
static fromURL(url: string, callback: (img: Image) => void, onError: OnErrorEventHandler = null) {
var img = Util.createImageElement();
img.onload = function () {
var image = new Image({

View File

@ -1,6 +1,7 @@
import { Factory } from '../Factory';
import { Shape, ShapeConfig } from '../Shape';
import { Group } from '../Group';
import { Context } from '../Context';
import { ContainerConfig } from '../Container';
import {
getNumberOrArrayOfNumbersValidator,
@ -75,7 +76,7 @@ var ATTR_CHANGE_LIST = [
* }));
*/
export class Label extends Group {
constructor(config?) {
constructor(config?: LabelConfig) {
super(config);
this.on('add.konva', function (evt) {
this._addListeners(evt.child);
@ -198,7 +199,7 @@ export interface TagConfig extends ShapeConfig {
* @param {Number} [config.cornerRadius]
*/
export class Tag extends Shape<TagConfig> {
_sceneFunc(context) {
_sceneFunc(context: Context) {
var width = this.width(),
height = this.height(),
pointerDirection = this.pointerDirection(),

View File

@ -3,6 +3,7 @@ import { Shape, ShapeConfig } from '../Shape';
import { GetSet } from '../types';
import { getNumberValidator } from '../Validators';
import { _registerNode } from '../Global';
import { Context } from '../Context';
export interface RegularPolygonConfig extends ShapeConfig {
sides: number;
@ -30,7 +31,7 @@ export interface RegularPolygonConfig extends ShapeConfig {
* });
*/
export class RegularPolygon extends Shape<RegularPolygonConfig> {
_sceneFunc(context) {
_sceneFunc(context: Context) {
const points = this._getPoints();
context.beginPath();
@ -81,10 +82,10 @@ export class RegularPolygon extends Shape<RegularPolygonConfig> {
getHeight() {
return this.radius() * 2;
}
setWidth(width) {
setWidth(width: number) {
this.radius(width / 2);
}
setHeight(height) {
setHeight(height: number) {
this.radius(height / 2);
}

View File

@ -3,6 +3,7 @@ import { Shape, ShapeConfig } from '../Shape';
import { GetSet } from '../types';
import { getNumberValidator } from '../Validators';
import { _registerNode } from '../Global';
import { Context } from '../Context';
export interface RingConfig extends ShapeConfig {
innerRadius: number;
@ -30,7 +31,7 @@ var PIx2 = Math.PI * 2;
* });
*/
export class Ring extends Shape<RingConfig> {
_sceneFunc(context) {
_sceneFunc(context: Context) {
context.beginPath();
context.arc(0, 0, this.innerRadius(), 0, PIx2, false);
context.moveTo(this.outerRadius(), 0);
@ -44,10 +45,10 @@ export class Ring extends Shape<RingConfig> {
getHeight() {
return this.outerRadius() * 2;
}
setWidth(width) {
setWidth(width: number) {
this.outerRadius(width / 2);
}
setHeight(height) {
setHeight(height: number) {
this.outerRadius(height / 2);
}

View File

@ -1,4 +1,5 @@
import { Factory } from '../Factory';
import { Context } from '../Context';
import { Shape, ShapeConfig } from '../Shape';
import { Animation } from '../Animation';
import { getNumberValidator } from '../Validators';
@ -65,7 +66,7 @@ export class Sprite extends Shape<SpriteConfig> {
_updated = true;
anim: Animation;
interval: any;
constructor(config) {
constructor(config: SpriteConfig) {
super(config);
this.anim = new Animation(() => {
// if we don't need to redraw layer we should return false
@ -90,7 +91,7 @@ export class Sprite extends Shape<SpriteConfig> {
});
}
_sceneFunc(context) {
_sceneFunc(context: Context) {
var anim = this.animation(),
index = this.frameIndex(),
ix4 = index * 4,
@ -129,7 +130,7 @@ export class Sprite extends Shape<SpriteConfig> {
}
}
}
_hitFunc(context) {
_hitFunc(context: Context) {
var anim = this.animation(),
index = this.frameIndex(),
ix4 = index * 4,

View File

@ -1,4 +1,5 @@
import { Factory } from '../Factory';
import { Context } from '../Context';
import { Shape, ShapeConfig } from '../Shape';
import { getNumberValidator } from '../Validators';
import { _registerNode } from '../Global';
@ -35,7 +36,7 @@ export interface StarConfig extends ShapeConfig {
* });
*/
export class Star extends Shape<StarConfig> {
_sceneFunc(context) {
_sceneFunc(context: Context) {
var innerRadius = this.innerRadius(),
outerRadius = this.outerRadius(),
numPoints = this.numPoints();
@ -59,10 +60,10 @@ export class Star extends Shape<StarConfig> {
getHeight() {
return this.outerRadius() * 2;
}
setWidth(width) {
setWidth(width: number) {
this.outerRadius(width / 2);
}
setHeight(height) {
setHeight(height: number) {
this.outerRadius(height / 2);
}

View File

@ -1,4 +1,5 @@
import { Util } from '../Util';
import { Context } from '../Context';
import { Factory } from '../Factory';
import { Shape, ShapeConfig } from '../Shape';
import { Konva } from '../Global';
@ -92,23 +93,23 @@ function normalizeFontFamily(fontFamily: string) {
.join(', ');
}
var dummyContext;
var dummyContext: CanvasRenderingContext2D;
function getDummyContext() {
if (dummyContext) {
return dummyContext;
}
dummyContext = Util.createCanvasElement().getContext(CONTEXT_2D);
dummyContext = Util.createCanvasElement().getContext(CONTEXT_2D) as CanvasRenderingContext2D;
return dummyContext;
}
function _fillFunc(context) {
function _fillFunc(context: Context) {
context.fillText(this._partialText, this._partialTextX, this._partialTextY);
}
function _strokeFunc(context) {
function _strokeFunc(context: Context) {
context.strokeText(this._partialText, this._partialTextX, this._partialTextY);
}
function checkDefaultFill(config) {
function checkDefaultFill(config: TextConfig) {
config = config || {};
// set default color to black
@ -169,7 +170,7 @@ export class Text extends Shape<TextConfig> {
this._setTextData();
}
_sceneFunc(context) {
_sceneFunc(context: Context) {
var textArr = this.textArr,
textArrLen = textArr.length;
@ -311,7 +312,7 @@ export class Text extends Shape<TextConfig> {
}
}
}
_hitFunc(context) {
_hitFunc(context: Context) {
var width = this.getWidth(),
height = this.getHeight();
@ -320,7 +321,7 @@ export class Text extends Shape<TextConfig> {
context.closePath();
context.fillStrokeShape(this);
}
setText(text) {
setText(text: string) {
var str = Util._isString(text)
? text
: text === null || text === undefined
@ -390,7 +391,7 @@ export class Text extends Shape<TextConfig> {
normalizeFontFamily(this.fontFamily())
);
}
_addTextLine(line) {
_addTextLine(line: string) {
const align = this.align();
if (align === JUSTIFY) {
line = line.trim();
@ -402,7 +403,7 @@ export class Text extends Shape<TextConfig> {
lastInParagraph: false,
});
}
_getTextWidth(text) {
_getTextWidth(text: string) {
var letterSpacing = this.letterSpacing();
var length = text.length;
return (

View File

@ -1,5 +1,6 @@
import { Util } from '../Util';
import { Factory } from '../Factory';
import { Context } from '../Context';
import { Shape, ShapeConfig } from '../Shape';
import { Path } from './Path';
import { Text, stringToArray } from './Text';
@ -155,7 +156,7 @@ export class TextPath extends Shape<TextPathConfig> {
this.pathLength = this._getTextPathLength();
}
_sceneFunc(context) {
_sceneFunc(context: Context) {
context.setAttr('font', this._getContextFont());
context.setAttr('textBaseline', this.textBaseline());
context.setAttr('textAlign', 'left');
@ -205,7 +206,7 @@ export class TextPath extends Shape<TextPathConfig> {
context.restore();
}
_hitFunc(context) {
_hitFunc(context: Context) {
context.beginPath();
var glyphInfo = this.glyphInfo;
@ -235,7 +236,7 @@ export class TextPath extends Shape<TextPathConfig> {
);
return this.textHeight;
}
setText(text) {
setText(text: string) {
return Text.prototype.setText.call(this, text);
}
@ -243,7 +244,7 @@ export class TextPath extends Shape<TextPathConfig> {
return Text.prototype._getContextFont.call(this);
}
_getTextSize(text) {
_getTextSize(text: string) {
var dummyCanvas = this.dummyCanvas;
var _context = dummyCanvas.getContext('2d');

View File

@ -266,11 +266,11 @@ export class Transformer extends Group {
* @example
* transformer.attachTo(shape);
*/
attachTo(node) {
attachTo(node: Node) {
this.setNode(node);
return this;
}
setNode(node) {
setNode(node: Node) {
Util.warn(
'tr.setNode(shape), tr.node(shape) and tr.attachTo(shape) methods are deprecated. Please use tr.nodes(nodesArray) instead.'
);
@ -288,7 +288,20 @@ export class Transformer extends Group {
if (this._nodes && this._nodes.length) {
this.detach();
}
this._nodes = nodes;
const filteredNodes = nodes.filter((node) => {
// check if ancestor of the transformer
if (node.isAncestorOf(this)) {
Util.error(
'Konva.Transformer cannot be an a child of the node you are trying to attach'
);
return false;
}
return true;
});
this._nodes = nodes = filteredNodes;
if (nodes.length === 1 && this.useSingleNodeRotation()) {
this.rotation(nodes[0].getAbsoluteRotation());
} else {
@ -395,6 +408,19 @@ export class Transformer extends Group {
this._nodes = [];
this._resetTransformCache();
}
/**
* bind events to the Transformer. You can use events: `transform`, `transformstart`, `transformend`, `dragstart`, `dragmove`, `dragend`
* @method
* @name Konva.Transformer#on
* @param {String} evtStr e.g. 'transform'
* @param {Function} handler The handler function. The first argument of that function is event object. Event object has `target` as main target of the event, `currentTarget` as current node listener and `evt` as native browser event.
* @returns {Konva.Transformer}
* @example
* // add click listener
* tr.on('transformstart', function() {
* console.log('transform started');
* });
*/
_resetTransformCache() {
this._clearCache(NODES_RECT);
this._clearCache('transform');

View File

@ -1,4 +1,5 @@
import { Factory } from '../Factory';
import { Context } from '../Context';
import { Shape, ShapeConfig } from '../Shape';
import { Konva } from '../Global';
import { getNumberValidator } from '../Validators';
@ -35,7 +36,7 @@ export interface WedgeConfig extends ShapeConfig {
* });
*/
export class Wedge extends Shape<WedgeConfig> {
_sceneFunc(context) {
_sceneFunc(context: Context) {
context.beginPath();
context.arc(
0,
@ -55,10 +56,10 @@ export class Wedge extends Shape<WedgeConfig> {
getHeight() {
return this.radius() * 2;
}
setWidth(width) {
setWidth(width: number) {
this.radius(width / 2);
}
setHeight(height) {
setHeight(height: number) {
this.radius(height / 2);
}

View File

@ -1750,7 +1750,7 @@ describe('MouseEvents', function () {
assert.equal(shape, circle);
});
it('double click after click should trigger event', function (done) {
it('double click after click should trigger event', function () {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
@ -1802,37 +1802,31 @@ describe('MouseEvents', function () {
assert.equal(smallClicks, 0, 'no click on small rect');
assert.equal(smallDblClicks, 0, 'no dblclick on small rect');
setTimeout(function () {
simulateMouseDown(stage, {
x: 100,
y: 100,
});
simulateMouseUp(stage, {
x: 100,
y: 100,
});
assert.equal(bigClicks, 1, 'single click on big rect');
assert.equal(smallClicks, 1, 'single click on small rect');
assert.equal(smallDblClicks, 0, 'no dblclick on small rect');
setTimeout(function () {
simulateMouseDown(stage, {
x: 100,
y: 100,
});
simulateMouseUp(stage, {
x: 100,
y: 100,
});
assert.equal(bigClicks, 1, 'single click on big rect');
assert.equal(smallClicks, 2, 'second click on small rect');
assert.equal(smallDblClicks, 1, 'single dblclick on small rect');
done();
});
simulateMouseDown(stage, {
x: 100,
y: 100,
});
simulateMouseUp(stage, {
x: 100,
y: 100,
});
assert.equal(bigClicks, 1, 'single click on big rect');
assert.equal(smallClicks, 1, 'single click on small rect');
assert.equal(smallDblClicks, 0, 'no dblclick on small rect');
simulateMouseDown(stage, {
x: 100,
y: 100,
});
simulateMouseUp(stage, {
x: 100,
y: 100,
});
assert.equal(bigClicks, 1, 'single click on big rect');
assert.equal(smallClicks, 2, 'second click on small rect');
assert.equal(smallDblClicks, 1, 'single dblclick on small rect');
});
it('click on stage and second click on shape should not trigger double click (check after dblclick)', function (done) {

View File

@ -667,15 +667,12 @@ describe('Text', function () {
stage.add(layer);
let trace =
'clearRect(0,0,578,200);save();transform(1,0,0,1,10,10);font=normal normal 30px Arial;textBaseline=middle;textAlign=left;translate(0,0);save();fillStyle=black;fillText(Y,0,15);fillStyle=black;fillText(O,20,15);fillStyle=black;fillText(U,43,15);fillStyle=black;fillText( ,65,15);fillStyle=black;fillText(A,73,15);fillStyle=black;fillText(R,93,15);fillStyle=black;fillText(E,115,15);fillStyle=black;fillText( ,135,15);fillStyle=black;fillText(I,143,15);fillStyle=black;fillText(N,151,15);fillStyle=black;fillText(V,173,15);fillStyle=black;fillText(I,193,15);fillStyle=black;fillText(T,201,15);fillStyle=black;fillText(E,220,15);fillStyle=black;fillText(D,240,15);fillStyle=black;fillText(!,261,15);restore();restore();';
if (Konva.isBrowser) {
var trace =
'clearRect(0,0,578,200);save();transform(1,0,0,1,10,10);font=normal normal 30px Arial;textBaseline=middle;textAlign=left;translate(0,0);save();fillStyle=black;fillText(Y,0,15);fillStyle=black;fillText(O,20,15);fillStyle=black;fillText(U,43,15);fillStyle=black;fillText( ,65,15);fillStyle=black;fillText(A,73,15);fillStyle=black;fillText(R,93,15);fillStyle=black;fillText(E,115,15);fillStyle=black;fillText( ,135,15);fillStyle=black;fillText(I,143,15);fillStyle=black;fillText(N,151,15);fillStyle=black;fillText(V,173,15);fillStyle=black;fillText(I,193,15);fillStyle=black;fillText(T,201,15);fillStyle=black;fillText(E,220,15);fillStyle=black;fillText(D,240,15);fillStyle=black;fillText(!,261,15);restore();restore();';
if (!isBrowser) {
trace =
'clearRect(0,0,578,200);save();transform(1,0,0,1,10,10);font=normal normal 30px Arial;textBaseline=middle;textAlign=left;translate(0,0);save();fillStyle=black;fillText(Y,0,15);fillStyle=black;fillText(O,20,15);fillStyle=black;fillText(U,43,15);fillStyle=black;fillText( ,65,15);fillStyle=black;fillText(A,73,15);fillStyle=black;fillText(R,93,15);fillStyle=black;fillText(E,115,15);fillStyle=black;fillText( ,135,15);fillStyle=black;fillText(I,143,15);fillStyle=black;fillText(N,151,15);fillStyle=black;fillText(V,173,15);fillStyle=black;fillText(I,193,15);fillStyle=black;fillText(T,201,15);fillStyle=black;fillText(E,219,15);fillStyle=black;fillText(D,239,15);fillStyle=black;fillText(!,261,15);restore();restore();';
assert.equal(layer.getContext().getTrace(false, true), trace);
}
assert.equal(layer.getContext().getTrace(false, true), trace);
});
it('text multi line with justify align and several paragraphs', function () {

View File

@ -4769,4 +4769,17 @@ describe('Transformer', function () {
assert.equal(clone.getChildren().length, tr.getChildren().length);
assert.equal(clone.nodes().length, 0);
});
it('should filter parent of the transformer', function () {
const stage = addStage();
const layer = new Konva.Layer();
stage.add(layer);
const tr = new Konva.Transformer();
layer.add(tr);
tr.nodes([layer]);
assert.equal(tr.nodes().length, 0);
});
});