canvas 绘制文本自动换行

栏目: Html5 · 发布时间: 7年前

内容简介:终于找到一个 canvas 自动换行的处理脚本,记录啊下来link:example :

终于找到一个 canvas 自动换行的处理脚本,记录啊下来

CanvasRenderingContext2D.prototype.wrapText = function (text, x, y, maxWidth, lineHeight){
    if (typeof text != 'string' || typeof x != 'number' || typeof y != 'number') {
        return;
    }
    
    var context = this;
    var canvas = context.canvas;
    
    if (typeof maxWidth == 'undefined') {
        maxWidth = (canvas && canvas.width) || 300;
    }
    if (typeof lineHeight == 'undefined') {
        lineHeight = (canvas && parseInt(window.getComputedStyle(canvas).lineHeight)) || parseInt(window.getComputedStyle(document.body).lineHeight);
    }
    
    // 字符分隔为数组
    var arrText = text.split('');
    var line = '';
    
    for (var n = 0; n < arrText.length; n++) {
        var testLine = line + arrText[n];
        var metrics = context.measureText(testLine);
        var testWidth = metrics.width;
        if (testWidth > maxWidth && n > 0) {
            context.fillText(line, x, y);
            line = arrText[n];
            y += lineHeight;
        } else {
            line = testLine;
        }
    }
    context.fillText(line, x, y);
};

link: canvas文本绘制自动换行、字间距、竖排等实现

example : 自动换行扩展API wrapText演示demo

在链接页面还带着一些特效

  1. 借助SVG 直接把CSS效果绘制上去

    var canvas = document.querySelector('canvas');
    var context = canvas.getContext('2d');
    context.font = '16px sans-serif';
    var width = canvas.width;
    var height = canvas.height;
    var tempImg = new Image();
    tempImg.width = width;
    tempImg.height = height;
    tempImg.onload = function (){
        // 把img绘制在canvas画布上
        context.drawImage(this, 0, 0, width, height);
    };
    tempImg.src = 'data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg"><foreignObject width="'+ width +'" height="'+ height +'"><body xmlns="http://www.w3.org/1999/xhtml" style="margin:0;font:'+ context.font +';">我是一段需要换行的文字啦啦啦</body></foreignObject></svg>';
    
    link [canvas借助SVG foreignObject实现文本自动换行demo](http://www.zhangxinxu.com/study/201802/canvas-wraptext-foreignobject.html)
  2. canvas支持字符间距

    使用 cssletter-spacing 属性

    var canvas = document.querySelector('canvas');
    var context = canvas.getContext('2d');
    var range = document.querySelector('input[type=range]');
    // 绘制方法
    var draw = function (){
        // 清除之前的绘制
        context.clearRect(0, 0, canvas.width, canvas.height);
        // 字符间距设置
        canvas.style.letterSpacing = range.value + 'px';
        // 并绘制文本,font属性值设置一定要在这里
        context.font = '32px sans-serif';
        context.fillText('我是一段文本', 0, 50);
    };
    // 改变字符间距后重绘
    range.addEventListener('change', draw);
    // 一进来根据默认值绘制
    draw();
    

使用 canvas 计算逐字绘制

CanvasRenderingContext2D.prototype.letterSpacingText = function (text, x, y, letterSpacing){
    var context = this;
    var canvas = context.canvas;
    
    if (!letterSpacing && canvas) {
        letterSpacing = parseFloat(window.getComputedStyle(canvas).letterSpacing);
    }
    if (!letterSpacing) {
        return this.fillText(text, x, y);
    }
    
    var arrText = text.split('');
    var align = context.textAlign || 'left';
    
    // 这里仅考虑水平排列
    var originWidth = context.measureText(text).width;
    // 应用letterSpacing占据宽度
    var actualWidth = originWidth + letterSpacing * (arrText.length - 1);
    // 根据水平对齐方式确定第一个字符的坐标
    if (align == 'center') {
        x = x - actualWidth / 2;
    } else if (align == 'right') {
        x = x - actualWidth;
    }
    
    // 临时修改为文本左对齐
    context.textAlign = 'left';
    // 开始逐字绘制
    arrText.forEach(function (letter){
        var letterWidth = context.measureText(letter).width;
        context.fillText(letter, x, y);
        // 确定下一个字符的横坐标
        x = x + letterWidth + letterSpacing;
    });
    // 对齐方式还原
    context.textAlign = align;
};
  1. canvas支持竖直排列

     CanvasRenderingContext2D.prototype.fillTextVertical = function (text, x, y){
        var context = this;
        var canvas = context.canvas;
        
        var arrText = text.split('');
        var arrWidth = arrText.map(function (letter){
            return context.measureText(letter).width;
        });
        
        var align = context.textAlign;
        var baseline = context.textBaseline;
        
        if (align == 'left') {
            x = x + Math.max.apply(null, arrWidth) / 2;
        } else if (align == 'right') {
            x = x - Math.max.apply(null, arrWidth) / 2;
        }
        if (baseline == 'bottom' || baseline == 'alphabetic' || baseline == 'ideographic') {
            y = y - arrWidth[0] / 2;
        } else if (baseline == 'top' || baseline == 'hanging') {
            y = y + arrWidth[0] / 2;
        }
        
        context.textAlign = 'center';
        context.textBaseline = 'middle';
        
        // 开始逐字绘制
        arrText.forEach(function (letter, index){
            // 确定下一个字符的纵坐标位置
            var letterWidth = arrWidth[index];
            // 是否需要旋转判断
            var code = letter.charCodeAt(0);
            if (code <= 256) {
                context.translate(x, y);
                // 英文字符,旋转90°
                context.rotate(90 * Math.PI / 180);
                context.translate(-x, -y);
            } else if (index > 0 && text.charCodeAt(index - 1) < 256) {
                // y修正
                y = y + arrWidth[index - 1] / 2;
            }
            context.fillText(letter, x, y);
            // 旋转坐标系还原成初始态
            context.setTransform(1, 0, 0, 1, 0, 0);
            // 确定下一个字符的纵坐标位置
            var letterWidth = arrWidth[index];
            y = y + letterWidth;
        });
        // 水平垂直对齐方式还原
        context.textAlign = align;
        context.textBaseline = baseline;
    };
    

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Haskell School of Expression

The Haskell School of Expression

Paul Hudak / Cambridge University Press / 2000-01 / USD 95.00

Functional programming is a style of programming that emphasizes the use of functions (in contrast to object-oriented programming, which emphasizes the use of objects). It has become popular in recen......一起来看看 《The Haskell School of Expression》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

MD5 加密
MD5 加密

MD5 加密工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具