new property for Konva.Text and Konva.TextPath: textDecoration

This commit is contained in:
Anton Lavrenov
2016-12-07 16:46:59 -05:00
parent 43fa56a381
commit 115002aaf6
8 changed files with 201 additions and 14 deletions

View File

@@ -5,7 +5,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [Not released][Not released]
## Added
- new properties for `Konva.Text`: `letterSpacing`
- 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`
- `align` support for `Konva.TextPath`
- new method `toCanvas()` for converting a node into canvas element

View File

@@ -3,5 +3,5 @@ Thank you for submitting an issue!
Please make sure to check current open and closed issues to see if your question has been asked or answered before.
If you have just a question (not a bug or a feature request) it is better to ask it in our [Gitter Chat](https://gitter.im/konvajs/konva) or in [Stackoverflow](http://stackoverflow.com/questions/tagged/konvajs).
If you have a bug, please, try to create reproducable example with jsfiddle (or any simillar service).
You can use [this JSBIN](http://jsbin.com/xinabi/edit?html,js,output) as template.
If you have a bug, please, try to create a reproducible example with jsfiddle (or any similar service).
You can use [this JSBIN](http://jsbin.com/xinabi/edit?html,js,output) as a template.

View File

@@ -3,7 +3,7 @@
* Konva JavaScript Framework v1.2.2
* http://konvajs.github.io/
* Licensed under the MIT or GPL Version 2 licenses.
* Date: Fri Nov 11 2016
* Date: Wed Dec 07 2016
*
* Original work Copyright (C) 2011 - 2013 by Eric Rowell (KineticJS)
* Modified work Copyright (C) 2014 - 2015 by Anton Lavrenov (Konva)
@@ -13085,6 +13085,8 @@
textArrLen = textArr.length,
totalWidth = this.getWidth(),
letterSpacing = this.getLetterSpacing(),
textDecoration = this.textDecoration(),
fill = this.fill(),
n;
context.setAttr('font', this._getContextFont());
@@ -13100,6 +13102,7 @@
}
// draw text lines
for(n = 0; n < textArrLen; n++) {
var obj = textArr[n],
@@ -13115,12 +13118,21 @@
context.translate((totalWidth - width - p * 2) / 2, 0);
}
if (textDecoration === 'underline') {
context.save();
context.moveTo(0, Math.round(lineHeightPx / 2));
context.lineTo(Math.round(width), Math.round(lineHeightPx / 2));
// context
context.strokeStyle = fill;
context.stroke();
context.restore();
}
if (letterSpacing !== 0) {
for(var li = 0; li < text.length; li++) {
var letter = text[li];
this.partialText = letter;
context.fillStrokeShape(this);
context.translate(this._getTextSize(letter).width + letterSpacing, 0);
context.translate(Math.round(this._getTextSize(letter).width) + letterSpacing, 0);
}
} else {
this.partialText = text;
@@ -13508,6 +13520,23 @@
* text.text('Hello world!');
*/
Konva.Factory.addGetterSetter(Konva.Text, 'textDecoration', null);
/**
* get/set text decoration of a text. Can be '' or 'underline'
* @name textDecoration
* @method
* @memberof Konva.Text.prototype
* @param {String} textDecoration
* @returns {String}
* @example
* // get text decoration
* var textDecoration = text.textDecoration();
*
* // center text
* text.textDecoration('underline');
*/
Konva.Collection.mapMethods(Konva.Text);
})();
@@ -15099,6 +15128,10 @@
context.setAttr('textAlign', 'left');
context.save();
var textDecoration = this.textDecoration();
var fill = this.fill();
var fontSize = this.fontSize();
var glyphInfo = this.glyphInfo;
for(var i = 0; i < glyphInfo.length; i++) {
context.save();
@@ -15110,10 +15143,21 @@
this.partialText = glyphInfo[i].text;
context.fillStrokeShape(this);
if (textDecoration === 'underline') {
// context.beginPath();
// context.strokeStyle = fill;
if (i === 0) {
context.moveTo(0, fontSize / 2);
}
context.lineTo(fontSize, fontSize / 2);
// context.stroke();
}
context.restore();
//// To assist with debugging visually, uncomment following
// context.beginPath();
//
// if (i % 2)
// context.strokeStyle = 'cyan';
// else
@@ -15123,6 +15167,11 @@
// context.lineTo(p1.x, p1.y);
// context.stroke();
}
if (textDecoration === 'underline') {
context.strokeStyle = fill;
context.stroke();
}
context.restore();
},
_hitFunc: function(context) {
@@ -15564,6 +15613,23 @@
* @memberof Konva.TextPath.prototype
*/
Konva.Factory.addGetterSetter(Konva.TextPath, 'textDecoration', null);
/**
* get/set text decoration of a text. Can be '' or 'underline'
* @name textDecoration
* @method
* @memberof Konva.Text.prototype
* @param {String} textDecoration
* @returns {String}
* @example
* // get text decoration
* var textDecoration = text.textDecoration();
*
* // center text
* text.textDecoration('underline');
*/
Konva.Collection.mapMethods(Konva.TextPath);
})();

12
konva.min.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -105,6 +105,8 @@
textArrLen = textArr.length,
totalWidth = this.getWidth(),
letterSpacing = this.getLetterSpacing(),
textDecoration = this.textDecoration(),
fill = this.fill(),
n;
context.setAttr('font', this._getContextFont());
@@ -120,6 +122,7 @@
}
// draw text lines
for(n = 0; n < textArrLen; n++) {
var obj = textArr[n],
@@ -135,12 +138,21 @@
context.translate((totalWidth - width - p * 2) / 2, 0);
}
if (textDecoration === 'underline') {
context.save();
context.moveTo(0, Math.round(lineHeightPx / 2));
context.lineTo(Math.round(width), Math.round(lineHeightPx / 2));
// context
context.strokeStyle = fill;
context.stroke();
context.restore();
}
if (letterSpacing !== 0) {
for(var li = 0; li < text.length; li++) {
var letter = text[li];
this.partialText = letter;
context.fillStrokeShape(this);
context.translate(this._getTextSize(letter).width + letterSpacing, 0);
context.translate(Math.round(this._getTextSize(letter).width) + letterSpacing, 0);
}
} else {
this.partialText = text;
@@ -528,5 +540,22 @@
* text.text('Hello world!');
*/
Konva.Factory.addGetterSetter(Konva.Text, 'textDecoration', null);
/**
* get/set text decoration of a text. Can be '' or 'underline'
* @name textDecoration
* @method
* @memberof Konva.Text.prototype
* @param {String} textDecoration
* @returns {String}
* @example
* // get text decoration
* var textDecoration = text.textDecoration();
*
* // center text
* text.textDecoration('underline');
*/
Konva.Collection.mapMethods(Konva.Text);
})();

View File

@@ -77,6 +77,10 @@
context.setAttr('textAlign', 'left');
context.save();
var textDecoration = this.textDecoration();
var fill = this.fill();
var fontSize = this.fontSize();
var glyphInfo = this.glyphInfo;
for(var i = 0; i < glyphInfo.length; i++) {
context.save();
@@ -88,10 +92,21 @@
this.partialText = glyphInfo[i].text;
context.fillStrokeShape(this);
if (textDecoration === 'underline') {
// context.beginPath();
// context.strokeStyle = fill;
if (i === 0) {
context.moveTo(0, fontSize / 2);
}
context.lineTo(fontSize, fontSize / 2);
// context.stroke();
}
context.restore();
//// To assist with debugging visually, uncomment following
// context.beginPath();
//
// if (i % 2)
// context.strokeStyle = 'cyan';
// else
@@ -101,6 +116,11 @@
// context.lineTo(p1.x, p1.y);
// context.stroke();
}
if (textDecoration === 'underline') {
context.strokeStyle = fill;
context.stroke();
}
context.restore();
},
_hitFunc: function(context) {
@@ -542,5 +562,22 @@
* @memberof Konva.TextPath.prototype
*/
Konva.Factory.addGetterSetter(Konva.TextPath, 'textDecoration', null);
/**
* get/set text decoration of a text. Can be '' or 'underline'
* @name textDecoration
* @method
* @memberof Konva.Text.prototype
* @param {String} textDecoration
* @returns {String}
* @example
* // get text decoration
* var textDecoration = text.textDecoration();
*
* // center text
* text.textDecoration('underline');
*/
Konva.Collection.mapMethods(Konva.TextPath);
})();

View File

@@ -330,6 +330,33 @@ suite('Text', function(){
});
// ======================================================
test('text multi line with textDecoration and spacing', function() {
var stage = addStage();
var layer = new Konva.Layer();
var text = new Konva.Text({
x: 10,
y: 10,
text: 'hello\nworld',
fontSize: 15,
fill: 'red',
letterSpacing: 5,
textDecoration: 'underline'
});
layer.add(text);
stage.add(layer);
var trace = 'clearRect(0,0,578,200);save();transform(1,0,0,1,10,10);font=normal normal 15px Arial;textBaseline=middle;textAlign=left;save();translate(0,7.5);save();save();moveTo(0,8);lineTo(52,8);stroke();restore();fillStyle=red;fillText(h,0,0);translate(13,0);fillStyle=red;fillText(e,0,0);translate(13,0);fillStyle=red;fillText(l,0,0);translate(8,0);fillStyle=red;fillText(l,0,0);translate(8,0);fillStyle=red;fillText(o,0,0);translate(13,0);restore();translate(0,15);save();save();moveTo(0,8);lineTo(56,8);stroke();restore();fillStyle=red;fillText(w,0,0);translate(16,0);fillStyle=red;fillText(o,0,0);translate(13,0);fillStyle=red;fillText(r,0,0);translate(10,0);fillStyle=red;fillText(l,0,0);translate(8,0);fillStyle=red;fillText(d,0,0);translate(13,0);restore();translate(0,15);restore();restore();';
assert.equal(layer.getContext().getTrace(), trace);
});
// ======================================================
test('change font size should update text data', function() {
var stage = addStage();

View File

@@ -145,6 +145,8 @@ suite('TextPath', function() {
});
// ======================================================
test('Render Text Along Elliptical Arc', function() {
var stage = addStage();
@@ -265,6 +267,31 @@ suite('TextPath', function() {
stage.add(layer);
});
test('Text path with underline', 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({
fill: 'orange',
fontSize: 10,
fontFamily: 'Arial',
letterSpacing: 5,
text: 'All the worlds a stage.',
textDecoration: 'underline',
data: c
});
layer.add(textpath);
stage.add(layer);
var trace = 'rotate();fillStyle;fillText();lineTo();restore();save();translate();rotate();fillStyle;fillText();lineTo();restore();save();translate();rotate();fillStyle;fillText();lineTo();restore();save();translate();rotate();fillStyle;fillText();lineTo();restore();save();translate();rotate();fillStyle;fillText();lineTo();restore();save();translate();rotate();fillStyle;fillText();lineTo();restore();save();translate();rotate();fillStyle;fillText();lineTo();restore();save();translate();rotate();fillStyle;fillText();lineTo();restore();save();translate();rotate();fillStyle;fillText();lineTo();restore();save();translate();rotate();fillStyle;fillText();lineTo();restore();save();translate();rotate();fillStyle;fillText();lineTo();restore();save();translate();rotate();fillStyle;fillText();lineTo();restore();save();translate();rotate();fillStyle;fillText();lineTo();restore();save();translate();rotate();fillStyle;fillText();lineTo();restore();stroke();restore();restore();';
assert.equal(layer.getContext().getTrace(true), trace);
});
test('Text with baseline', function() {
var stage = addStage();