canvas 绘制文本自动换行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| 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); };
|
- 在链接页面还带着一些特效
借助 SVG 直接把 CSS 效果绘制上去
1 2 3 4 5 6 7 8 9 10 11 12 13
| 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 () { 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>';
|
canvas借助SVG foreignObject实现文本自动换行demo
canvas 支持字符间距
使用 css 的 letter-spacing 属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 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'; context.font = '32px sans-serif'; context.fillText('我是一段文本', 0, 50); };
range.addEventListener('change', draw);
draw();
|
使用 canvas 计算逐字绘制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| 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; 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; };
|
3.canvas 支持竖直排列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| 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); context.rotate(90 * Math.PI / 180); context.translate(-x, -y); } else if (index > 0 && text.charCodeAt(index - 1) < 256) { 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; };
|