美文网首页技术专栏
Canvas模拟TextArea换行效果

Canvas模拟TextArea换行效果

作者: Cesium4Unreal | 来源:发表于2017-07-22 08:26 被阅读75次

最近项目种需求,使用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>

image.png

相关文章

网友评论

    本文标题:Canvas模拟TextArea换行效果

    本文链接:https://www.haomeiwen.com/subject/uswykxtx.html