mirror of
https://github.com/konvajs/konva.git
synced 2025-10-20 19:01:04 +08:00
justify align for Text and TextPath
This commit is contained in:
@@ -5,6 +5,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
## [Not released][Not released]
|
||||
|
||||
## Added
|
||||
- new align value for `Konva.Text` and `Konva.TextPath`: `justify`
|
||||
- new property for `Konva.Text` and `Konva.TextPath`: `textDecoration`. Right now it sports only '' (no decoration) and 'underline' values.
|
||||
- new property for `Konva.Text`: `letterSpacing`
|
||||
- new event `contentContextmenu` for `Konva.Stage`
|
||||
|
30
konva.js
30
konva.js
@@ -3,7 +3,7 @@
|
||||
* Konva JavaScript Framework v1.2.2
|
||||
* http://konvajs.github.io/
|
||||
* Licensed under the MIT or GPL Version 2 licenses.
|
||||
* Date: Wed Dec 07 2016
|
||||
* Date: Thu Dec 08 2016
|
||||
*
|
||||
* Original work Copyright (C) 2011 - 2013 by Eric Rowell (KineticJS)
|
||||
* Modified work Copyright (C) 2014 - 2015 by Anton Lavrenov (Konva)
|
||||
@@ -12918,6 +12918,7 @@
|
||||
var AUTO = 'auto',
|
||||
//CANVAS = 'canvas',
|
||||
CENTER = 'center',
|
||||
JUSTIFY = 'justify',
|
||||
CHANGE_KONVA = 'Change.konva',
|
||||
CONTEXT_2D = '2d',
|
||||
DASH = '-',
|
||||
@@ -13083,6 +13084,7 @@
|
||||
lineHeightPx = this.getLineHeight() * textHeight,
|
||||
textArr = this.textArr,
|
||||
textArrLen = textArr.length,
|
||||
align = this.getAlign(),
|
||||
totalWidth = this.getWidth(),
|
||||
letterSpacing = this.getLetterSpacing(),
|
||||
textDecoration = this.textDecoration(),
|
||||
@@ -13112,10 +13114,10 @@
|
||||
|
||||
// horizontal alignment
|
||||
context.save();
|
||||
if(this.getAlign() === RIGHT) {
|
||||
if(align === RIGHT) {
|
||||
context.translate(totalWidth - width - p * 2, 0);
|
||||
}
|
||||
else if(this.getAlign() === CENTER) {
|
||||
else if(align === CENTER) {
|
||||
context.translate((totalWidth - width - p * 2) / 2, 0);
|
||||
}
|
||||
|
||||
@@ -13131,9 +13133,15 @@
|
||||
context.stroke();
|
||||
context.restore();
|
||||
}
|
||||
if (letterSpacing !== 0) {
|
||||
if ((letterSpacing !== 0) || align === JUSTIFY) {
|
||||
// var words = text.split(' ');
|
||||
var spacesNumber = text.split(' ').length - 1;
|
||||
for(var li = 0; li < text.length; li++) {
|
||||
var letter = text[li];
|
||||
// skip justify for the last line
|
||||
if ((letter === ' ') && (n !== textArrLen - 1)) {
|
||||
context.translate(Math.ceil((totalWidth - width) / spacesNumber), 0);
|
||||
}
|
||||
this.partialText = letter;
|
||||
context.fillStrokeShape(this);
|
||||
context.translate(Math.round(this._getTextSize(letter).width) + letterSpacing, 0);
|
||||
@@ -13445,7 +13453,7 @@
|
||||
Konva.Factory.addGetterSetter(Konva.Text, 'align', LEFT);
|
||||
|
||||
/**
|
||||
* get/set horizontal align of text. Can be 'left', 'center', or 'right'
|
||||
* get/set horizontal align of text. Can be 'left', 'center', 'right' or 'justify'
|
||||
* @name align
|
||||
* @method
|
||||
* @memberof Konva.Text.prototype
|
||||
@@ -15241,6 +15249,7 @@
|
||||
var that = this;
|
||||
var size = this._getTextSize(this.attrs.text);
|
||||
var letterSpacing = this.getLetterSpacing();
|
||||
var align = this.align();
|
||||
|
||||
this.textWidth = size.width;
|
||||
this.textHeight = size.height;
|
||||
@@ -15258,14 +15267,15 @@
|
||||
}
|
||||
|
||||
var offset = 0;
|
||||
if (this.align() === 'center') {
|
||||
if (align === 'center') {
|
||||
offset = Math.max(0, fullPathWidth / 2 - textFullWidth / 2);
|
||||
}
|
||||
if (this.align() === 'right') {
|
||||
if (align === 'right') {
|
||||
offset = Math.max(0, fullPathWidth - textFullWidth);
|
||||
}
|
||||
|
||||
var charArr = this.getText().split('');
|
||||
var spacesNumber = this.getText().split(' ').length - 1;
|
||||
|
||||
var p0, p1, pathCmd;
|
||||
|
||||
@@ -15307,6 +15317,10 @@
|
||||
|
||||
var glyphWidth = that._getTextSize(c).width + letterSpacing;
|
||||
|
||||
if ((c === ' ') && (align === 'justify')) {
|
||||
glyphWidth += (fullPathWidth - textFullWidth) / spacesNumber;
|
||||
}
|
||||
|
||||
var currLen = 0;
|
||||
var attempts = 0;
|
||||
|
||||
@@ -15545,7 +15559,7 @@
|
||||
Konva.Factory.addGetterSetter(Konva.TextPath, 'align', 'left');
|
||||
|
||||
/**
|
||||
* get/set horizontal align of text. Can be 'left', 'center', or 'right'
|
||||
* get/set horizontal align of text. Can be 'left', 'center', 'right' or 'justify'
|
||||
* @name align
|
||||
* @method
|
||||
* @memberof Konva.Text.prototype
|
||||
|
10
konva.min.js
vendored
10
konva.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -7,6 +7,7 @@
|
||||
var AUTO = 'auto',
|
||||
//CANVAS = 'canvas',
|
||||
CENTER = 'center',
|
||||
JUSTIFY = 'justify',
|
||||
CHANGE_KONVA = 'Change.konva',
|
||||
CONTEXT_2D = '2d',
|
||||
DASH = '-',
|
||||
@@ -103,6 +104,7 @@
|
||||
lineHeightPx = this.getLineHeight() * textHeight,
|
||||
textArr = this.textArr,
|
||||
textArrLen = textArr.length,
|
||||
align = this.getAlign(),
|
||||
totalWidth = this.getWidth(),
|
||||
letterSpacing = this.getLetterSpacing(),
|
||||
textDecoration = this.textDecoration(),
|
||||
@@ -132,10 +134,10 @@
|
||||
|
||||
// horizontal alignment
|
||||
context.save();
|
||||
if(this.getAlign() === RIGHT) {
|
||||
if(align === RIGHT) {
|
||||
context.translate(totalWidth - width - p * 2, 0);
|
||||
}
|
||||
else if(this.getAlign() === CENTER) {
|
||||
else if(align === CENTER) {
|
||||
context.translate((totalWidth - width - p * 2) / 2, 0);
|
||||
}
|
||||
|
||||
@@ -151,9 +153,15 @@
|
||||
context.stroke();
|
||||
context.restore();
|
||||
}
|
||||
if (letterSpacing !== 0) {
|
||||
if ((letterSpacing !== 0) || align === JUSTIFY) {
|
||||
// var words = text.split(' ');
|
||||
var spacesNumber = text.split(' ').length - 1;
|
||||
for(var li = 0; li < text.length; li++) {
|
||||
var letter = text[li];
|
||||
// skip justify for the last line
|
||||
if ((letter === ' ') && (n !== textArrLen - 1)) {
|
||||
context.translate(Math.ceil((totalWidth - width) / spacesNumber), 0);
|
||||
}
|
||||
this.partialText = letter;
|
||||
context.fillStrokeShape(this);
|
||||
context.translate(Math.round(this._getTextSize(letter).width) + letterSpacing, 0);
|
||||
@@ -465,7 +473,7 @@
|
||||
Konva.Factory.addGetterSetter(Konva.Text, 'align', LEFT);
|
||||
|
||||
/**
|
||||
* get/set horizontal align of text. Can be 'left', 'center', or 'right'
|
||||
* get/set horizontal align of text. Can be 'left', 'center', 'right' or 'justify'
|
||||
* @name align
|
||||
* @method
|
||||
* @memberof Konva.Text.prototype
|
||||
|
@@ -186,6 +186,7 @@
|
||||
var that = this;
|
||||
var size = this._getTextSize(this.attrs.text);
|
||||
var letterSpacing = this.getLetterSpacing();
|
||||
var align = this.align();
|
||||
|
||||
this.textWidth = size.width;
|
||||
this.textHeight = size.height;
|
||||
@@ -203,14 +204,15 @@
|
||||
}
|
||||
|
||||
var offset = 0;
|
||||
if (this.align() === 'center') {
|
||||
if (align === 'center') {
|
||||
offset = Math.max(0, fullPathWidth / 2 - textFullWidth / 2);
|
||||
}
|
||||
if (this.align() === 'right') {
|
||||
if (align === 'right') {
|
||||
offset = Math.max(0, fullPathWidth - textFullWidth);
|
||||
}
|
||||
|
||||
var charArr = this.getText().split('');
|
||||
var spacesNumber = this.getText().split(' ').length - 1;
|
||||
|
||||
var p0, p1, pathCmd;
|
||||
|
||||
@@ -252,6 +254,10 @@
|
||||
|
||||
var glyphWidth = that._getTextSize(c).width + letterSpacing;
|
||||
|
||||
if ((c === ' ') && (align === 'justify')) {
|
||||
glyphWidth += (fullPathWidth - textFullWidth) / spacesNumber;
|
||||
}
|
||||
|
||||
var currLen = 0;
|
||||
var attempts = 0;
|
||||
|
||||
@@ -490,7 +496,7 @@
|
||||
Konva.Factory.addGetterSetter(Konva.TextPath, 'align', 'left');
|
||||
|
||||
/**
|
||||
* get/set horizontal align of text. Can be 'left', 'center', or 'right'
|
||||
* get/set horizontal align of text. Can be 'left', 'center', 'right' or 'justify'
|
||||
* @name align
|
||||
* @method
|
||||
* @memberof Konva.Text.prototype
|
||||
|
@@ -295,6 +295,43 @@ suite('Text', function(){
|
||||
assert.equal(text.getLineHeight(), 20);
|
||||
});
|
||||
|
||||
|
||||
// ======================================================
|
||||
test('text multi line with justify align', function() {
|
||||
var stage = addStage();
|
||||
var layer = new Konva.Layer();
|
||||
|
||||
var rect = new Konva.Rect({
|
||||
x: 10,
|
||||
y: 10,
|
||||
width: 380,
|
||||
height: 300,
|
||||
fill: 'yellow'
|
||||
});
|
||||
|
||||
var text = new Konva.Text({
|
||||
x: 10,
|
||||
y: 10,
|
||||
text: 'HEADING\n\n All the world\'s a stage, merely players. They have their exits and their entrances; And one man in his time plays many parts.',
|
||||
fontSize: 14,
|
||||
fontFamily: 'Calibri',
|
||||
fontStyle: 'normal',
|
||||
fill: '#555',
|
||||
width: 380,
|
||||
align: 'justify',
|
||||
letterSpacing: 5,
|
||||
draggable: true
|
||||
});
|
||||
|
||||
rect.height(text.getHeight());
|
||||
layer.add(rect).add(text);
|
||||
stage.add(layer);
|
||||
|
||||
var trace = 'fillStyle=#555;fillText( ,0,0);translate(9,0);fillStyle=#555;fillText(i,0,0);translate(9,0);fillStyle=#555;fillText(n,0,0);translate(12,0);translate(1,0);fillStyle=#555;fillText( ,0,0);translate(9,0);fillStyle=#555;fillText(h,0,0);translate(12,0);fillStyle=#555;fillText(i,0,0);translate(9,0);fillStyle=#555;fillText(s,0,0);translate(10,0);translate(1,0);fillStyle=#555;fillText( ,0,0);translate(9,0);restore();translate(0,14);save();fillStyle=#555;fillText(t,0,0);translate(9,0);fillStyle=#555;fillText(i,0,0);translate(9,0);fillStyle=#555;fillText(m,0,0);translate(16,0);fillStyle=#555;fillText(e,0,0);translate(11,0);fillStyle=#555;fillText( ,0,0);translate(9,0);fillStyle=#555;fillText(p,0,0);translate(12,0);fillStyle=#555;fillText(l,0,0);translate(9,0);fillStyle=#555;fillText(a,0,0);translate(11,0);fillStyle=#555;fillText(y,0,0);translate(12,0);fillStyle=#555;fillText(s,0,0);translate(10,0);fillStyle=#555;fillText( ,0,0);translate(9,0);fillStyle=#555;fillText(m,0,0);translate(16,0);fillStyle=#555;fillText(a,0,0);translate(11,0);fillStyle=#555;fillText(n,0,0);translate(12,0);fillStyle=#555;fillText(y,0,0);translate(12,0);fillStyle=#555;fillText( ,0,0);translate(9,0);fillStyle=#555;fillText(p,0,0);translate(12,0);fillStyle=#555;fillText(a,0,0);translate(11,0);fillStyle=#555;fillText(r,0,0);translate(10,0);fillStyle=#555;fillText(t,0,0);translate(9,0);fillStyle=#555;fillText(s,0,0);translate(10,0);fillStyle=#555;fillText(.,0,0);translate(9,0);restore();translate(0,14);restore();restore();';
|
||||
|
||||
assert.equal(layer.getContext().getTrace(), trace);
|
||||
});
|
||||
|
||||
// ======================================================
|
||||
test('text multi line with shadows', function() {
|
||||
var stage = addStage();
|
||||
|
@@ -267,6 +267,36 @@ suite('TextPath', function() {
|
||||
stage.add(layer);
|
||||
});
|
||||
|
||||
test('Text path with justify align', function() {
|
||||
var stage = addStage();
|
||||
var layer = new Konva.Layer();
|
||||
|
||||
var c = "M10,10 C0,0 10,150 100,100 S300,150 400,50";
|
||||
|
||||
var textpath = new Konva.TextPath({
|
||||
stroke: 'black',
|
||||
strokeWidth: 1,
|
||||
fill: 'orange',
|
||||
fontSize: 10,
|
||||
fontFamily: 'Arial',
|
||||
letterSpacing: 5,
|
||||
text: 'All the worlds a stage.',
|
||||
align: 'justify',
|
||||
data: c
|
||||
});
|
||||
|
||||
// TODO: add test case
|
||||
|
||||
layer.add(textpath);
|
||||
stage.add(layer);
|
||||
|
||||
|
||||
// console.log(layer.getContext().getTrace(true));
|
||||
var trace = 'rotate();fillStyle;fillText();lineWidth;strokeStyle;strokeText();restore();save();translate();rotate();fillStyle;fillText();lineWidth;strokeStyle;strokeText();restore();save();translate();rotate();fillStyle;fillText();lineWidth;strokeStyle;strokeText();restore();save();translate();rotate();fillStyle;fillText();lineWidth;strokeStyle;strokeText();restore();save();translate();rotate();fillStyle;fillText();lineWidth;strokeStyle;strokeText();restore();save();translate();rotate();fillStyle;fillText();lineWidth;strokeStyle;strokeText();restore();save();translate();rotate();fillStyle;fillText();lineWidth;strokeStyle;strokeText();restore();save();translate();rotate();fillStyle;fillText();lineWidth;strokeStyle;strokeText();restore();save();translate();rotate();fillStyle;fillText();lineWidth;strokeStyle;strokeText();restore();save();translate();rotate();fillStyle;fillText();lineWidth;strokeStyle;strokeText();restore();save();translate();rotate();fillStyle;fillText();lineWidth;strokeStyle;strokeText();restore();restore();restore();';
|
||||
|
||||
assert.equal(layer.getContext().getTrace(true), trace);
|
||||
});
|
||||
|
||||
test('Text path with underline', function() {
|
||||
var stage = addStage();
|
||||
var layer = new Konva.Layer();
|
||||
|
Reference in New Issue
Block a user