rewrote text array algo in Text. added newline support. now handling edge case in which the text box width is smaller than a character width. if a line is not able to wrap via space or dash, the word itself is wrapped.

This commit is contained in:
Eric Rowell 2012-07-08 13:59:43 -07:00
parent 30fd5c1fa7
commit d0f37f7c88
5 changed files with 110 additions and 46 deletions

67
dist/kinetic-core.js vendored
View File

@ -3,7 +3,7 @@
* http://www.kineticjs.com/ * http://www.kineticjs.com/
* Copyright 2012, Eric Rowell * Copyright 2012, Eric Rowell
* Licensed under the MIT or GPL Version 2 licenses. * Licensed under the MIT or GPL Version 2 licenses.
* Date: Jul 07 2012 * Date: Jul 08 2012
* *
* Copyright (C) 2011 - 2012 by Eric Rowell * Copyright (C) 2011 - 2012 by Eric Rowell
* *
@ -4134,36 +4134,63 @@ Kinetic.Text = Kinetic.Shape.extend({
_setTextData: function() { _setTextData: function() {
var charArr = this.attrs.text.split(''); var charArr = this.attrs.text.split('');
var arr = []; var arr = [];
var lastWord = '';
var row = 0; var row = 0;
this.textArr = []; var addLine = true;
this.textWidth = 0; this.textWidth = 0;
this.textHeight = this._getTextSize(this.attrs.text).height; this.textHeight = this._getTextSize(this.attrs.text).height;
var lineHeightPx = this.attrs.lineHeight * this.textHeight; var lineHeightPx = this.attrs.lineHeight * this.textHeight;
var addedToLine = true; while(charArr.length > 0 && addLine && (this.attrs.height === 'auto' || lineHeightPx * (row + 1) < this.attrs.height - this.attrs.padding * 2)) {
while(charArr.length > 0 && addedToLine && (this.attrs.height === 'auto' || lineHeightPx * (row + 1) < this.attrs.height - this.attrs.padding * 2)) { var index = 0;
addedToLine = false; var line = undefined;
var line = lastWord; addLine = false;
lastWord = '';
while(charArr[0] !== undefined && (this.attrs.width === 'auto' || this._getTextSize(line + charArr[0]).width < this.attrs.width - this.attrs.padding * 2)) {
lastWord = charArr[0] === ' ' || charArr[0] === '-' ? '' : lastWord + charArr[0];
line += charArr.splice(0, 1);
addedToLine = true;
}
// remove last word from line while(index < charArr.length) {
if(charArr.length > 0) { if(charArr.indexOf('\n') === index) {
line = line.substring(0, line.lastIndexOf(lastWord)); // remove newline char
} charArr.splice(index, 1);
line = charArr.splice(0, index).join('');
break;
}
// if line exceeds inner box width
var lineArr = charArr.slice(0, index);
if(this.attrs.width !== 'auto' && this._getTextSize(lineArr.join('')).width > this.attrs.width - this.attrs.padding * 2) {
/*
* if a single character is too large to fit inside
* the text box width, then break out of the loop
* and stop processing
*/
if(index == 0) {
break;
}
var lastSpace = lineArr.lastIndexOf(' ');
var lastDash = lineArr.lastIndexOf('-');
var wrapIndex = Math.max(lastSpace, lastDash);
if(wrapIndex >= 0) {
line = charArr.splice(0, 1 + wrapIndex).join('');
break;
}
/*
* if not able to word wrap based on space or dash,
* go ahead and wrap in the middle of a word if needed
*/
line = charArr.splice(0, index).join('');
break;
}
index++;
// if the end is reached
if(index === charArr.length) {
line = charArr.splice(0, index).join('');
}
}
this.textWidth = Math.max(this.textWidth, this._getTextSize(line).width); this.textWidth = Math.max(this.textWidth, this._getTextSize(line).width);
if(line !== undefined) {
if(line.length > 0) {
arr.push(line); arr.push(line);
addLine = true;
} }
row++; row++;
} }
this.textArr = arr; this.textArr = arr;
} }
}); });

File diff suppressed because one or more lines are too long

View File

@ -148,36 +148,63 @@ Kinetic.Text = Kinetic.Shape.extend({
_setTextData: function() { _setTextData: function() {
var charArr = this.attrs.text.split(''); var charArr = this.attrs.text.split('');
var arr = []; var arr = [];
var lastWord = '';
var row = 0; var row = 0;
this.textArr = []; var addLine = true;
this.textWidth = 0; this.textWidth = 0;
this.textHeight = this._getTextSize(this.attrs.text).height; this.textHeight = this._getTextSize(this.attrs.text).height;
var lineHeightPx = this.attrs.lineHeight * this.textHeight; var lineHeightPx = this.attrs.lineHeight * this.textHeight;
var addedToLine = true; while(charArr.length > 0 && addLine && (this.attrs.height === 'auto' || lineHeightPx * (row + 1) < this.attrs.height - this.attrs.padding * 2)) {
while(charArr.length > 0 && addedToLine && (this.attrs.height === 'auto' || lineHeightPx * (row + 1) < this.attrs.height - this.attrs.padding * 2)) { var index = 0;
addedToLine = false; var line = undefined;
var line = lastWord; addLine = false;
lastWord = '';
while(charArr[0] !== undefined && (this.attrs.width === 'auto' || this._getTextSize(line + charArr[0]).width < this.attrs.width - this.attrs.padding * 2)) {
lastWord = charArr[0] === ' ' || charArr[0] === '-' ? '' : lastWord + charArr[0];
line += charArr.splice(0, 1);
addedToLine = true;
}
// remove last word from line while(index < charArr.length) {
if(charArr.length > 0) { if(charArr.indexOf('\n') === index) {
line = line.substring(0, line.lastIndexOf(lastWord)); // remove newline char
} charArr.splice(index, 1);
line = charArr.splice(0, index).join('');
break;
}
// if line exceeds inner box width
var lineArr = charArr.slice(0, index);
if(this.attrs.width !== 'auto' && this._getTextSize(lineArr.join('')).width > this.attrs.width - this.attrs.padding * 2) {
/*
* if a single character is too large to fit inside
* the text box width, then break out of the loop
* and stop processing
*/
if(index == 0) {
break;
}
var lastSpace = lineArr.lastIndexOf(' ');
var lastDash = lineArr.lastIndexOf('-');
var wrapIndex = Math.max(lastSpace, lastDash);
if(wrapIndex >= 0) {
line = charArr.splice(0, 1 + wrapIndex).join('');
break;
}
/*
* if not able to word wrap based on space or dash,
* go ahead and wrap in the middle of a word if needed
*/
line = charArr.splice(0, index).join('');
break;
}
index++;
// if the end is reached
if(index === charArr.length) {
line = charArr.splice(0, index).join('');
}
}
this.textWidth = Math.max(this.textWidth, this._getTextSize(line).width); this.textWidth = Math.max(this.textWidth, this._getTextSize(line).width);
if(line !== undefined) {
if(line.length > 0) {
arr.push(line); arr.push(line);
addLine = true;
} }
row++; row++;
} }
this.textArr = arr; this.textArr = arr;
} }
}); });

View File

@ -109,7 +109,7 @@ Test.prototype.tests = {
easing: 'bounce-ease-out' easing: 'bounce-ease-out'
}); });
}, },
'*TRANSITION - all transition types': function(containerId) { 'TRANSITION - all transition types': function(containerId) {
document.getElementById(containerId).style.height = '300px'; document.getElementById(containerId).style.height = '300px';
var stage = new Kinetic.Stage({ var stage = new Kinetic.Stage({

View File

@ -2977,17 +2977,20 @@ Test.prototype.tests = {
var layer = new Kinetic.Layer(); var layer = new Kinetic.Layer();
var text = new Kinetic.Text({ var text = new Kinetic.Text({
x: stage.getWidth() / 2, x: 10,
y: stage.getHeight() / 2, y: 10,
stroke: '#555', stroke: '#555',
strokeWidth: 5, strokeWidth: 5,
fill: '#ddd', fill: '#ddd',
text: 'All the world\'s a stage, and all the men and women merely players. They have their exits and their entrances; And one man in his time plays many parts.', text: 'HEADING\n\nAll the world\'s a stage, and all the men and women merely players. They have their exits and their entrances; And one man in his time plays many parts.',
//text: 'HEADING\n\nThis is a really cool paragraph. \n And this is a footer.',
fontSize: 16, fontSize: 16,
fontFamily: 'Calibri', fontFamily: 'Calibri',
fontStyle: 'normal', fontStyle: 'normal',
textFill: '#555', textFill: '#555',
//width: 20,
width: 380, width: 380,
//width: 200,
padding: 20, padding: 20,
align: 'center', align: 'center',
shadow: { shadow: {
@ -3002,10 +3005,17 @@ Test.prototype.tests = {
}); });
// center text box // center text box
text.setOffset(text.getBoxWidth() / 2, text.getBoxHeight() / 2); //text.setOffset(text.getBoxWidth() / 2, text.getBoxHeight() / 2);
layer.add(text); layer.add(text);
stage.add(layer); stage.add(layer);
/*
text.transitionTo({
width: 500,
duration: 10
});
*/
}, },
'SHAPE - get shape name': function(containerId) { 'SHAPE - get shape name': function(containerId) {
var stage = new Kinetic.Stage({ var stage = new Kinetic.Stage({