最近项目种需求,使用Canvas模拟TextArea自动换行的效果,TextArea自动换行,考虑了中英文、考虑了英文整个单词不可拆解等因素;所以实现起来相对比较麻烦;
但是,越有麻烦的事情,才越有挑战!
理清思路
对中英文进行编码形成如:"你好AB" --> "2211"的样式,这样对中英文字符串的处理,就变成了对"2211"纯阿拉伯数字的处理。我们特别要处理的就是21连接处。
- 将中英文字符串用2和1阿拉伯编码,2代表中文,1代表英文;
- 在中英文连接处,即有21处,插入分隔符"_",编码成"22_11"等样式;
- 切割编码后的阿拉伯字符串,形成[22],[11]样式;
- 反过来将原字符处理为[你好],[AB]样式;
- 依次循环判断英文部分的宽度是否超过当前TextArea的宽度,超出即添加换行符;
- 依次循环即可;高度类似;
完整代码
<pre>
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>filltext</title>
</head>
<body>
<canvas id="ft" width="400" height="400" style="background-color: #CDC000;">您的浏览器不支持canvas。</canvas>
<textarea id="input" style="width:100px;height: 100px; font: italic normal bolder 12pt Arial">我是ABCDE</textarea>
<script type="text/javascript" src="../libs/twaver.js"></script>
<script type="text/javascript">
(function(){
function writeTextOnCanvas(cns,text){
var cns = document.getElementById(cns);
var ctx = cns.getContext("2d");
var name = text.name;
ctx.width = cns.width;
ctx.height = cns.height;
ctx.fillStyle = '#FF0000';
ctx.clearRect(0, 0, ctx.width, ctx.height);
ctx.font = "italic normal bolder 12pt Arial";
ctx.fillStyle = "#FF0000";
ctx.font = '12pt Arial';
var array = name.split('\n');
var x = 0, y= 100;
for(var i = 0;i<array.length;i++){
ctx.fillText(array[i], x, y);
y += 20;
}
}
document.getElementById("input").onkeyup = function(){
var result = hanlderText(this.value,{
font:'12pt Arial',
width:100,
height:100,
});
writeTextOnCanvas("ft", result);
console.log(result);
}
var result = hanlderText(document.getElementById("input").value, {
width:100,
height:100,
});
writeTextOnCanvas("ft", result);
console.log(result);
function hanlderText(input, style) {
var input = input, name = input;
var code = '';
for(var x = 0; x < input.length; x++){
var char = input.charAt(x);
if(char.match(/[^\x00-\x80]/g)) {
code += '2';
}else {
code += '1';
}
}
code = code.replace(/21/g,'2_1');
for(var i = 0; i < code.length; i++){
var char = code.charAt(i);
if(char.match(/\_/g)) {
name = replacePos(name, i + 1, '_');
}
}
var array = name.split("_");
var result = array[0];
var width = style.width, height = style.height;
var countHeight = 0;
for(var i = 1; i < array.length; i++){
var preSize = _twaver.g.getTextSize(style.font, array[i-1]);
var currentSize = _twaver.g.getTextSize(style.font, array[i]);
if(i - 1 == 0){
countHeight = preSize.height;
}
if(currentSize.width + preSize.width% width < width ){
result += array[i];
}else {
var a = array[i], b = _twaver.g.getCollapseTextInLength(style.font, a, width).split('\n');;
var col = Math.ceil(currentSize.width/width);
for(var j = 0; j < col; j++){
countHeight += currentSize.height;
if(countHeight < height) {
result += '\n' + b[j];
}
}
}
}
var size = _twaver.g.getTextSize(style.font, result);
return {
name:result,
height:countHeight,
};
}
function replacePos(str, pos, text) {
var str = str.substr(0,pos-1) + text + str.substring(pos - 1,str.length);
return str;
}
})();
</script>
</body>
</html>
</pre>

网友评论