mirror of
https://github.com/konvajs/konva.git
synced 2025-10-15 12:34:52 +08:00
Better unicode support in Konva.Text
and Konva.TextPath
. Emoji should work better now 👍. fix #690
This commit is contained in:
@@ -3,6 +3,8 @@
|
|||||||
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/).
|
||||||
|
|
||||||
|
* Better unicode support in `Konva.Text` and `Konva.TextPath`. Emoji should work better now 👍
|
||||||
|
|
||||||
## 7.1.0
|
## 7.1.0
|
||||||
|
|
||||||
* Multi row support for `ellipsis` config for `Konva.Text`
|
* Multi row support for `ellipsis` config for `Konva.Text`
|
||||||
|
112
konva.js
112
konva.js
@@ -8,7 +8,7 @@
|
|||||||
* Konva JavaScript Framework v7.1.0
|
* Konva JavaScript Framework v7.1.0
|
||||||
* http://konvajs.org/
|
* http://konvajs.org/
|
||||||
* Licensed under the MIT
|
* Licensed under the MIT
|
||||||
* Date: Mon Sep 07 2020
|
* Date: Mon Sep 14 2020
|
||||||
*
|
*
|
||||||
* 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)
|
||||||
@@ -1260,6 +1260,21 @@
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function getNumberOrArrayOfNumbersValidator(noOfElements) {
|
||||||
|
if (Konva.isUnminified) {
|
||||||
|
return function (val, attr) {
|
||||||
|
var isNumber = Util._isNumber(val);
|
||||||
|
var isValidArray = Util._isArray(val) && val.length == noOfElements;
|
||||||
|
if (!isNumber && !isValidArray) {
|
||||||
|
Util.warn(_formatValue(val) +
|
||||||
|
' is a not valid value for "' +
|
||||||
|
attr +
|
||||||
|
'" attribute. The value should be a number or Array<number>(' + noOfElements + ')');
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
function getNumberOrAutoValidator() {
|
function getNumberOrAutoValidator() {
|
||||||
if (Konva.isUnminified) {
|
if (Konva.isUnminified) {
|
||||||
return function (val, attr) {
|
return function (val, attr) {
|
||||||
@@ -4833,7 +4848,7 @@
|
|||||||
*/
|
*/
|
||||||
addGetterSetter(Node, 'globalCompositeOperation', 'source-over', getStringValidator());
|
addGetterSetter(Node, 'globalCompositeOperation', 'source-over', getStringValidator());
|
||||||
/**
|
/**
|
||||||
* get/set globalCompositeOperation of a shape
|
* get/set globalCompositeOperation of a node. globalCompositeOperation DOESN'T affect hit graph of nodes. So they are still trigger to events as they have default "source-over" globalCompositeOperation.
|
||||||
* @name Konva.Node#globalCompositeOperation
|
* @name Konva.Node#globalCompositeOperation
|
||||||
* @method
|
* @method
|
||||||
* @param {String} type
|
* @param {String} type
|
||||||
@@ -11378,59 +11393,50 @@
|
|||||||
return _super !== null && _super.apply(this, arguments) || this;
|
return _super !== null && _super.apply(this, arguments) || this;
|
||||||
}
|
}
|
||||||
Tag.prototype._sceneFunc = function (context) {
|
Tag.prototype._sceneFunc = function (context) {
|
||||||
var width = this.width(), height = this.height(), pointerDirection = this.pointerDirection(), pointerWidth = this.pointerWidth(), pointerHeight = this.pointerHeight(), cornerRadius = Math.min(this.cornerRadius(), width / 2, height / 2);
|
var width = this.width(), height = this.height(), pointerDirection = this.pointerDirection(), pointerWidth = this.pointerWidth(), pointerHeight = this.pointerHeight(), cornerRadius = this.cornerRadius();
|
||||||
context.beginPath();
|
var topLeft = 0;
|
||||||
if (!cornerRadius) {
|
var topRight = 0;
|
||||||
context.moveTo(0, 0);
|
var bottomLeft = 0;
|
||||||
|
var bottomRight = 0;
|
||||||
|
if (typeof cornerRadius === 'number') {
|
||||||
|
topLeft = topRight = bottomLeft = bottomRight = Math.min(cornerRadius, width / 2, height / 2);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
context.moveTo(cornerRadius, 0);
|
topLeft = Math.min(cornerRadius[0] || 0, width / 2, height / 2);
|
||||||
|
topRight = Math.min(cornerRadius[1] || 0, width / 2, height / 2);
|
||||||
|
bottomRight = Math.min(cornerRadius[2] || 0, width / 2, height / 2);
|
||||||
|
bottomLeft = Math.min(cornerRadius[3] || 0, width / 2, height / 2);
|
||||||
}
|
}
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(topLeft, 0);
|
||||||
if (pointerDirection === UP) {
|
if (pointerDirection === UP) {
|
||||||
context.lineTo((width - pointerWidth) / 2, 0);
|
context.lineTo((width - pointerWidth) / 2, 0);
|
||||||
context.lineTo(width / 2, -1 * pointerHeight);
|
context.lineTo(width / 2, -1 * pointerHeight);
|
||||||
context.lineTo((width + pointerWidth) / 2, 0);
|
context.lineTo((width + pointerWidth) / 2, 0);
|
||||||
}
|
}
|
||||||
if (!cornerRadius) {
|
context.lineTo(width - topRight, 0);
|
||||||
context.lineTo(width, 0);
|
context.arc(width - topRight, topRight, topRight, (Math.PI * 3) / 2, 0, false);
|
||||||
}
|
|
||||||
else {
|
|
||||||
context.lineTo(width - cornerRadius, 0);
|
|
||||||
context.arc(width - cornerRadius, cornerRadius, cornerRadius, (Math.PI * 3) / 2, 0, false);
|
|
||||||
}
|
|
||||||
if (pointerDirection === RIGHT) {
|
if (pointerDirection === RIGHT) {
|
||||||
context.lineTo(width, (height - pointerHeight) / 2);
|
context.lineTo(width, (height - pointerHeight) / 2);
|
||||||
context.lineTo(width + pointerWidth, height / 2);
|
context.lineTo(width + pointerWidth, height / 2);
|
||||||
context.lineTo(width, (height + pointerHeight) / 2);
|
context.lineTo(width, (height + pointerHeight) / 2);
|
||||||
}
|
}
|
||||||
if (!cornerRadius) {
|
context.lineTo(width, height - bottomRight);
|
||||||
context.lineTo(width, height);
|
context.arc(width - bottomRight, height - bottomRight, bottomRight, 0, Math.PI / 2, false);
|
||||||
}
|
|
||||||
else {
|
|
||||||
context.lineTo(width, height - cornerRadius);
|
|
||||||
context.arc(width - cornerRadius, height - cornerRadius, cornerRadius, 0, Math.PI / 2, false);
|
|
||||||
}
|
|
||||||
if (pointerDirection === DOWN) {
|
if (pointerDirection === DOWN) {
|
||||||
context.lineTo((width + pointerWidth) / 2, height);
|
context.lineTo((width + pointerWidth) / 2, height);
|
||||||
context.lineTo(width / 2, height + pointerHeight);
|
context.lineTo(width / 2, height + pointerHeight);
|
||||||
context.lineTo((width - pointerWidth) / 2, height);
|
context.lineTo((width - pointerWidth) / 2, height);
|
||||||
}
|
}
|
||||||
if (!cornerRadius) {
|
context.lineTo(bottomLeft, height);
|
||||||
context.lineTo(0, height);
|
context.arc(bottomLeft, height - bottomLeft, bottomLeft, Math.PI / 2, Math.PI, false);
|
||||||
}
|
|
||||||
else {
|
|
||||||
context.lineTo(cornerRadius, height);
|
|
||||||
context.arc(cornerRadius, height - cornerRadius, cornerRadius, Math.PI / 2, Math.PI, false);
|
|
||||||
}
|
|
||||||
if (pointerDirection === LEFT) {
|
if (pointerDirection === LEFT) {
|
||||||
context.lineTo(0, (height + pointerHeight) / 2);
|
context.lineTo(0, (height + pointerHeight) / 2);
|
||||||
context.lineTo(-1 * pointerWidth, height / 2);
|
context.lineTo(-1 * pointerWidth, height / 2);
|
||||||
context.lineTo(0, (height - pointerHeight) / 2);
|
context.lineTo(0, (height - pointerHeight) / 2);
|
||||||
}
|
}
|
||||||
if (cornerRadius) {
|
context.lineTo(0, topLeft);
|
||||||
context.lineTo(0, cornerRadius);
|
context.arc(topLeft, topLeft, topLeft, Math.PI, (Math.PI * 3) / 2, false);
|
||||||
context.arc(cornerRadius, cornerRadius, cornerRadius, Math.PI, (Math.PI * 3) / 2, false);
|
|
||||||
}
|
|
||||||
context.closePath();
|
context.closePath();
|
||||||
context.fillStrokeShape(this);
|
context.fillStrokeShape(this);
|
||||||
};
|
};
|
||||||
@@ -11500,8 +11506,12 @@
|
|||||||
* @returns {Number}
|
* @returns {Number}
|
||||||
* @example
|
* @example
|
||||||
* tag.cornerRadius(20);
|
* tag.cornerRadius(20);
|
||||||
|
*
|
||||||
|
* // set different corner radius values
|
||||||
|
* // top-left, top-right, bottom-right, bottom-left
|
||||||
|
* tag.cornerRadius([0, 10, 20, 30]);
|
||||||
*/
|
*/
|
||||||
Factory.addGetterSetter(Tag, 'cornerRadius', 0, getNumberValidator());
|
Factory.addGetterSetter(Tag, 'cornerRadius', 0, getNumberOrArrayOfNumbersValidator(4));
|
||||||
Collection.mapMethods(Tag);
|
Collection.mapMethods(Tag);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -12433,10 +12443,10 @@
|
|||||||
topLeft = topRight = bottomLeft = bottomRight = Math.min(cornerRadius, width / 2, height / 2);
|
topLeft = topRight = bottomLeft = bottomRight = Math.min(cornerRadius, width / 2, height / 2);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
topLeft = Math.min(cornerRadius[0], width / 2, height / 2);
|
topLeft = Math.min(cornerRadius[0] || 0, width / 2, height / 2);
|
||||||
topRight = Math.min(cornerRadius[1], width / 2, height / 2);
|
topRight = Math.min(cornerRadius[1] || 0, width / 2, height / 2);
|
||||||
bottomRight = Math.min(cornerRadius[2], width / 2, height / 2);
|
bottomRight = Math.min(cornerRadius[2] || 0, width / 2, height / 2);
|
||||||
bottomLeft = Math.min(cornerRadius[3], width / 2, height / 2);
|
bottomLeft = Math.min(cornerRadius[3] || 0, width / 2, height / 2);
|
||||||
}
|
}
|
||||||
context.moveTo(topLeft, 0);
|
context.moveTo(topLeft, 0);
|
||||||
context.lineTo(width - topRight, 0);
|
context.lineTo(width - topRight, 0);
|
||||||
@@ -12472,7 +12482,7 @@
|
|||||||
* // top-left, top-right, bottom-right, bottom-left
|
* // top-left, top-right, bottom-right, bottom-left
|
||||||
* rect.cornerRadius([0, 10, 20, 30]);
|
* rect.cornerRadius([0, 10, 20, 30]);
|
||||||
*/
|
*/
|
||||||
Factory.addGetterSetter(Rect, 'cornerRadius', 0);
|
Factory.addGetterSetter(Rect, 'cornerRadius', 0, getNumberOrArrayOfNumbersValidator(4));
|
||||||
Collection.mapMethods(Rect);
|
Collection.mapMethods(Rect);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -13329,6 +13339,13 @@
|
|||||||
Factory.addGetterSetter(Star, 'outerRadius', 0, getNumberValidator());
|
Factory.addGetterSetter(Star, 'outerRadius', 0, getNumberValidator());
|
||||||
Collection.mapMethods(Star);
|
Collection.mapMethods(Star);
|
||||||
|
|
||||||
|
function stringToArray(string) {
|
||||||
|
// we need to use `Array.from` because it can split unicode string correctly
|
||||||
|
// we also can use some regexp magic from lodash:
|
||||||
|
// https://github.com/lodash/lodash/blob/fb1f99d9d90ad177560d771bc5953a435b2dc119/lodash.toarray/index.js#L256
|
||||||
|
// but I decided it is too much code for that small fix
|
||||||
|
return Array.from(string);
|
||||||
|
}
|
||||||
// constants
|
// constants
|
||||||
var AUTO = 'auto',
|
var AUTO = 'auto',
|
||||||
//CANVAS = 'canvas',
|
//CANVAS = 'canvas',
|
||||||
@@ -13569,8 +13586,9 @@
|
|||||||
if (letterSpacing !== 0 || align === JUSTIFY) {
|
if (letterSpacing !== 0 || align === JUSTIFY) {
|
||||||
// var words = text.split(' ');
|
// var words = text.split(' ');
|
||||||
spacesNumber = text.split(' ').length - 1;
|
spacesNumber = text.split(' ').length - 1;
|
||||||
for (var li = 0; li < text.length; li++) {
|
var array = stringToArray(text);
|
||||||
var letter = text[li];
|
for (var li = 0; li < array.length; li++) {
|
||||||
|
var letter = array[li];
|
||||||
// skip justify for the last line
|
// skip justify for the last line
|
||||||
if (letter === ' ' && n !== textArrLen - 1 && align === JUSTIFY) {
|
if (letter === ' ' && n !== textArrLen - 1 && align === JUSTIFY) {
|
||||||
lineTranslateX += (totalWidth - padding * 2 - width) / spacesNumber;
|
lineTranslateX += (totalWidth - padding * 2 - width) / spacesNumber;
|
||||||
@@ -14283,7 +14301,7 @@
|
|||||||
_context.restore();
|
_context.restore();
|
||||||
return {
|
return {
|
||||||
width: metrics.width,
|
width: metrics.width,
|
||||||
height: parseInt(this.attrs.fontSize, 10)
|
height: parseInt(this.attrs.fontSize, 10),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
TextPath.prototype._setTextData = function () {
|
TextPath.prototype._setTextData = function () {
|
||||||
@@ -14309,7 +14327,7 @@
|
|||||||
if (align === 'right') {
|
if (align === 'right') {
|
||||||
offset = Math.max(0, fullPathWidth - textFullWidth);
|
offset = Math.max(0, fullPathWidth - textFullWidth);
|
||||||
}
|
}
|
||||||
var charArr = this.text().split('');
|
var charArr = stringToArray(this.text());
|
||||||
var spacesNumber = this.text().split(' ').length - 1;
|
var spacesNumber = this.text().split(' ').length - 1;
|
||||||
var p0, p1, pathCmd;
|
var p0, p1, pathCmd;
|
||||||
var pIndex = -1;
|
var pIndex = -1;
|
||||||
@@ -14333,7 +14351,7 @@
|
|||||||
else if (pathData[j].command === 'M') {
|
else if (pathData[j].command === 'M') {
|
||||||
p0 = {
|
p0 = {
|
||||||
x: pathData[j].points[0],
|
x: pathData[j].points[0],
|
||||||
y: pathData[j].points[1]
|
y: pathData[j].points[1],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14485,7 +14503,7 @@
|
|||||||
text: charArr[i],
|
text: charArr[i],
|
||||||
rotation: rotation,
|
rotation: rotation,
|
||||||
p0: p0,
|
p0: p0,
|
||||||
p1: p1
|
p1: p1,
|
||||||
});
|
});
|
||||||
p0 = p1;
|
p0 = p1;
|
||||||
}
|
}
|
||||||
@@ -14496,7 +14514,7 @@
|
|||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
width: 0,
|
width: 0,
|
||||||
height: 0
|
height: 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
var points = [];
|
var points = [];
|
||||||
@@ -14524,7 +14542,7 @@
|
|||||||
x: minX - fontSize / 2,
|
x: minX - fontSize / 2,
|
||||||
y: minY - fontSize / 2,
|
y: minY - fontSize / 2,
|
||||||
width: maxX - minX + fontSize,
|
width: maxX - minX + fontSize,
|
||||||
height: maxY - minY + fontSize
|
height: maxY - minY + fontSize,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
return TextPath;
|
return TextPath;
|
||||||
@@ -14989,7 +15007,7 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
Transformer.prototype.getNodes = function () {
|
Transformer.prototype.getNodes = function () {
|
||||||
return this._nodes;
|
return this._nodes || [];
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* return the name of current active anchor
|
* return the name of current active anchor
|
||||||
|
4
konva.min.js
vendored
4
konva.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -2745,7 +2745,7 @@ addGetterSetter(
|
|||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get/set globalCompositeOperation of a shape
|
* get/set globalCompositeOperation of a node. globalCompositeOperation DOESN'T affect hit graph of nodes. So they are still trigger to events as they have default "source-over" globalCompositeOperation.
|
||||||
* @name Konva.Node#globalCompositeOperation
|
* @name Konva.Node#globalCompositeOperation
|
||||||
* @method
|
* @method
|
||||||
* @param {String} type
|
* @param {String} type
|
||||||
|
@@ -12,6 +12,14 @@ import { _registerNode } from '../Global';
|
|||||||
|
|
||||||
import { GetSet } from '../types';
|
import { GetSet } from '../types';
|
||||||
|
|
||||||
|
export function stringToArray(string: string) {
|
||||||
|
// we need to use `Array.from` because it can split unicode string correctly
|
||||||
|
// we also can use some regexp magic from lodash:
|
||||||
|
// https://github.com/lodash/lodash/blob/fb1f99d9d90ad177560d771bc5953a435b2dc119/lodash.toarray/index.js#L256
|
||||||
|
// but I decided it is too much code for that small fix
|
||||||
|
return Array.from(string);
|
||||||
|
}
|
||||||
|
|
||||||
export interface TextConfig extends ShapeConfig {
|
export interface TextConfig extends ShapeConfig {
|
||||||
text?: string;
|
text?: string;
|
||||||
fontFamily?: string;
|
fontFamily?: string;
|
||||||
@@ -264,8 +272,9 @@ export class Text extends Shape<TextConfig> {
|
|||||||
if (letterSpacing !== 0 || align === JUSTIFY) {
|
if (letterSpacing !== 0 || align === JUSTIFY) {
|
||||||
// var words = text.split(' ');
|
// var words = text.split(' ');
|
||||||
spacesNumber = text.split(' ').length - 1;
|
spacesNumber = text.split(' ').length - 1;
|
||||||
for (var li = 0; li < text.length; li++) {
|
var array = stringToArray(text);
|
||||||
var letter = text[li];
|
for (var li = 0; li < array.length; li++) {
|
||||||
|
var letter = array[li];
|
||||||
// skip justify for the last line
|
// skip justify for the last line
|
||||||
if (letter === ' ' && n !== textArrLen - 1 && align === JUSTIFY) {
|
if (letter === ' ' && n !== textArrLen - 1 && align === JUSTIFY) {
|
||||||
lineTranslateX += (totalWidth - padding * 2 - width) / spacesNumber;
|
lineTranslateX += (totalWidth - padding * 2 - width) / spacesNumber;
|
||||||
|
@@ -2,7 +2,7 @@ import { Util, Collection } from '../Util';
|
|||||||
import { Factory } from '../Factory';
|
import { Factory } from '../Factory';
|
||||||
import { Shape, ShapeConfig } from '../Shape';
|
import { Shape, ShapeConfig } from '../Shape';
|
||||||
import { Path } from './Path';
|
import { Path } from './Path';
|
||||||
import { Text } from './Text';
|
import { Text, stringToArray } from './Text';
|
||||||
import { getNumberValidator } from '../Validators';
|
import { getNumberValidator } from '../Validators';
|
||||||
import { _registerNode } from '../Global';
|
import { _registerNode } from '../Global';
|
||||||
|
|
||||||
@@ -213,7 +213,7 @@ export class TextPath extends Shape<TextPathConfig> {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
width: metrics.width,
|
width: metrics.width,
|
||||||
height: parseInt(this.attrs.fontSize, 10)
|
height: parseInt(this.attrs.fontSize, 10),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
_setTextData() {
|
_setTextData() {
|
||||||
@@ -248,7 +248,7 @@ export class TextPath extends Shape<TextPathConfig> {
|
|||||||
offset = Math.max(0, fullPathWidth - textFullWidth);
|
offset = Math.max(0, fullPathWidth - textFullWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
var charArr = this.text().split('');
|
var charArr = stringToArray(this.text());
|
||||||
var spacesNumber = this.text().split(' ').length - 1;
|
var spacesNumber = this.text().split(' ').length - 1;
|
||||||
|
|
||||||
var p0, p1, pathCmd;
|
var p0, p1, pathCmd;
|
||||||
@@ -276,7 +276,7 @@ export class TextPath extends Shape<TextPathConfig> {
|
|||||||
} else if (pathData[j].command === 'M') {
|
} else if (pathData[j].command === 'M') {
|
||||||
p0 = {
|
p0 = {
|
||||||
x: pathData[j].points[0],
|
x: pathData[j].points[0],
|
||||||
y: pathData[j].points[1]
|
y: pathData[j].points[1],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -494,7 +494,7 @@ export class TextPath extends Shape<TextPathConfig> {
|
|||||||
text: charArr[i],
|
text: charArr[i],
|
||||||
rotation: rotation,
|
rotation: rotation,
|
||||||
p0: p0,
|
p0: p0,
|
||||||
p1: p1
|
p1: p1,
|
||||||
});
|
});
|
||||||
p0 = p1;
|
p0 = p1;
|
||||||
}
|
}
|
||||||
@@ -505,7 +505,7 @@ export class TextPath extends Shape<TextPathConfig> {
|
|||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
width: 0,
|
width: 0,
|
||||||
height: 0
|
height: 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
var points = [];
|
var points = [];
|
||||||
@@ -534,7 +534,7 @@ export class TextPath extends Shape<TextPathConfig> {
|
|||||||
x: minX - fontSize / 2,
|
x: minX - fontSize / 2,
|
||||||
y: minY - fontSize / 2,
|
y: minY - fontSize / 2,
|
||||||
width: maxX - minX + fontSize,
|
width: maxX - minX + fontSize,
|
||||||
height: maxY - minY + fontSize
|
height: maxY - minY + fontSize,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -234,7 +234,7 @@ beforeEach(function () {
|
|||||||
this.currentTest.body.toLowerCase().indexOf('compare') !== -1
|
this.currentTest.body.toLowerCase().indexOf('compare') !== -1
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
debugger;
|
console.error(this.currentTest.title);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -250,7 +250,7 @@ afterEach(function () {
|
|||||||
|
|
||||||
if (!isFailed && !isManual) {
|
if (!isFailed && !isManual) {
|
||||||
Konva.stages.forEach(function (stage) {
|
Konva.stages.forEach(function (stage) {
|
||||||
stage.destroy();
|
// stage.destroy();
|
||||||
});
|
});
|
||||||
if (Konva.DD._dragElements.size) {
|
if (Konva.DD._dragElements.size) {
|
||||||
throw 'Why drag elements are not cleaned?';
|
throw 'Why drag elements are not cleaned?';
|
||||||
|
@@ -21,6 +21,12 @@ suite('Container', function () {
|
|||||||
layer.add(group);
|
layer.add(group);
|
||||||
group.add(circle);
|
group.add(circle);
|
||||||
layer.draw();
|
layer.draw();
|
||||||
|
|
||||||
|
var trace = layer.getContext().getTrace();
|
||||||
|
assert.equal(
|
||||||
|
trace,
|
||||||
|
'clearRect(0,0,578,200);save();transform(1,0,0,1,0,0);beginPath();rect(0,0,289,100);clip();transform(1,0,0,1,0,0);restore();clearRect(0,0,578,200);save();transform(1,0,0,1,0,0);beginPath();rect(0,0,289,100);clip();transform(1,0,0,1,0,0);save();transform(1,0,0,1,289,100);beginPath();arc(0,0,70,0,6.283,false);closePath();fillStyle=green;fill();lineWidth=4;strokeStyle=black;stroke();restore();restore();'
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// ======================================================
|
// ======================================================
|
||||||
@@ -203,6 +209,12 @@ suite('Container', function () {
|
|||||||
layer.add(group);
|
layer.add(group);
|
||||||
group.add(circle);
|
group.add(circle);
|
||||||
layer.draw();
|
layer.draw();
|
||||||
|
|
||||||
|
var trace = layer.getContext().getTrace();
|
||||||
|
assert.equal(
|
||||||
|
trace,
|
||||||
|
'clearRect(0,0,578,200);clearRect(0,0,578,200);save();transform(1,0,0,1,289,100);beginPath();arc(0,0,70,0,6.283,false);closePath();fillStyle=green;fill();lineWidth=4;strokeStyle=black;stroke();restore();'
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// ======================================================
|
// ======================================================
|
||||||
@@ -223,6 +235,14 @@ suite('Container', function () {
|
|||||||
group.add(circle);
|
group.add(circle);
|
||||||
stage.add(layer);
|
stage.add(layer);
|
||||||
layer.add(group);
|
layer.add(group);
|
||||||
|
|
||||||
|
layer.draw();
|
||||||
|
|
||||||
|
var trace = layer.getContext().getTrace();
|
||||||
|
assert.equal(
|
||||||
|
trace,
|
||||||
|
'clearRect(0,0,578,200);clearRect(0,0,578,200);save();transform(1,0,0,1,289,100);beginPath();arc(0,0,70,0,6.283,false);closePath();fillStyle=green;fill();lineWidth=4;strokeStyle=black;stroke();restore();'
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// ======================================================
|
// ======================================================
|
||||||
|
@@ -1813,6 +1813,12 @@ suite('Node', function () {
|
|||||||
|
|
||||||
layer.add(circle);
|
layer.add(circle);
|
||||||
stage.add(layer);
|
stage.add(layer);
|
||||||
|
|
||||||
|
var trace = layer.getContext().getTrace();
|
||||||
|
assert.equal(
|
||||||
|
trace,
|
||||||
|
'clearRect(0,0,578,200);save();transform(1.879,0.684,-0.342,0.94,14.581,42.306);beginPath();rect(0,0,100,50);closePath();fillStyle=green;fill();lineWidth=4;strokeStyle=black;stroke();restore();'
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// ======================================================
|
// ======================================================
|
||||||
|
@@ -137,6 +137,31 @@ suite('Text', function () {
|
|||||||
compareLayerAndCanvas(layer, canvas, 254);
|
compareLayerAndCanvas(layer, canvas, 254);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('check emoji with letterSpacing', function () {
|
||||||
|
var stage = addStage();
|
||||||
|
var layer = new Konva.Layer();
|
||||||
|
|
||||||
|
var text = new Konva.Text({
|
||||||
|
x: 10,
|
||||||
|
y: 10,
|
||||||
|
text: '😬',
|
||||||
|
fontSize: 50,
|
||||||
|
letterSpacing: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
layer.add(text);
|
||||||
|
stage.add(layer);
|
||||||
|
|
||||||
|
var canvas = createCanvas();
|
||||||
|
var context = canvas.getContext('2d');
|
||||||
|
context.textBaseline = 'middle';
|
||||||
|
context.font = 'normal normal 50px Arial';
|
||||||
|
context.fillStyle = 'darkgrey';
|
||||||
|
context.fillText('😬', 10, 10 + 25);
|
||||||
|
|
||||||
|
compareLayerAndCanvas(layer, canvas, 254);
|
||||||
|
});
|
||||||
|
|
||||||
test('text cache with fill and shadow', function () {
|
test('text cache with fill and shadow', function () {
|
||||||
var stage = addStage();
|
var stage = addStage();
|
||||||
var layer1 = new Konva.Layer();
|
var layer1 = new Konva.Layer();
|
||||||
|
@@ -315,6 +315,31 @@ suite('TextPath', function () {
|
|||||||
assert.equal(layer.getContext().getTrace(true), trace);
|
assert.equal(layer.getContext().getTrace(true), trace);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Text path with emoji', function () {
|
||||||
|
var stage = addStage();
|
||||||
|
var layer = new Konva.Layer();
|
||||||
|
|
||||||
|
var c = 'M10,10 300, 10';
|
||||||
|
|
||||||
|
var textpath = new Konva.TextPath({
|
||||||
|
fill: 'black',
|
||||||
|
fontSize: 10,
|
||||||
|
fontFamily: 'Arial',
|
||||||
|
letterSpacing: 5,
|
||||||
|
text: '😬',
|
||||||
|
align: 'center',
|
||||||
|
data: c,
|
||||||
|
});
|
||||||
|
|
||||||
|
layer.add(textpath);
|
||||||
|
stage.add(layer);
|
||||||
|
|
||||||
|
var trace =
|
||||||
|
'clearRect(0,0,578,200);save();transform(1,0,0,1,0,0);font=normal normal 10px Arial;textBaseline=middle;textAlign=left;save();save();translate(144.438,10);rotate(0);fillStyle=black;fillText(😬,0,0);restore();restore();restore();';
|
||||||
|
|
||||||
|
assert.equal(layer.getContext().getTrace(), trace);
|
||||||
|
});
|
||||||
|
|
||||||
test.skip('Text path with center align - arc', function () {
|
test.skip('Text path with center align - arc', function () {
|
||||||
var stage = addStage();
|
var stage = addStage();
|
||||||
var layer = new Konva.Layer();
|
var layer = new Konva.Layer();
|
||||||
|
Reference in New Issue
Block a user