本文将介绍Canvas画布绘制文本相关的技术细节。

一、Canvas画布绘制文本

核心API

绘制文本(描边)

语法 ctx.strokeText( text , x , y , [ maxWidth ]);

作用 用于在画布上绘制文本(描边·没有填色)。

说明 文本的颜色为黑色,可以通过strokeStyle属性来设置颜色或渐变。

参数

text                      绘制的文本信息
x 文本的X轴坐标
y 文本的Y轴坐标
maxWidth 允许的最大文本宽度,单位为像素

示例

    var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d"); //设置文字的字号大小和字体样式
ctx.font="20px Impact";
ctx.strokeText("Nice to meet you!",10,50); //创建渐变
var gradient = ctx.createLinearGradient(200,0,300,0);
gradient.addColorStop("0","black");
gradient.addColorStop("0.5","blue");
gradient.addColorStop("1.0","red"); //设置文字的字号大小和字体样式
ctx.font="25px KaiTi";
ctx.strokeStyle = gradient;
ctx.strokeText("wendingding.com",200,50);

绘制文本(填充)

语法 ctx.fillText( text , x , y , [ maxWidth ]);

作用 用于在画布上绘制填色的文本。

说明 文本的颜色为黑色,可以通过fillStyle属性来设置颜色或渐变。

参数

text              绘制的文本信息
x 文本的X轴坐标
y 文本的Y轴坐标
maxWidth 允许的最大文本宽度,单位为像素

示例

    var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d"); //设置文字的字号大小和字体样式
ctx.font="20px Georgia";
ctx.fillText("Nice to meet you!",10,50); //创建渐变
var gradient = ctx.createLinearGradient(200,0,300,0);
gradient.addColorStop("0","black");
gradient.addColorStop("0.5","blue");
gradient.addColorStop("1.0","red"); // 用渐变填色
ctx.fillStyle = gradient;
//设置文字的字号大小和字体样式
ctx.font="25px KaiTi";
ctx.fillText("wendingding.com",200,50);

计算文本信息的宽度

语法 ctx.measureText( text ).width;

作用 用于计算和返回指定文本的宽度,单位以像素计。

说明 measureText方法返回的本身是一个对象,我们需要用过width来获取宽度值。

参数 text表示要测量的文本。

文字绘制相关属性介绍

font 设置文字的字号和字体等信息。

textAlign 设置水平对齐方式,可选值有start(默认) | end | left | right | center

textBaseline 设置垂直对齐方式,可选值有alphabetic(默认) | top | middle | bottom | hanging | ideographic。其中hanging表示文本基线是悬挂基线,ideographic表示文本基线是表意基线。

    var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d"); var str = "How are you?";
ctx.font = "30px Times New Roman"; ctx.strokeText(str,50,50);
ctx.fillText(str,50,100);
ctx.fillText(str,50,150,120); //约束最大宽度
console.log(ctx.measureText(str).width); ctx.moveTo(100,0);
ctx.lineTo(100,ctx.canvas.height);
ctx.stroke();
ctx.beginPath(); var textAlignArr = ["start","end","left","right","center"];
for(var i = 0;i<textAlignArr.length;i++)
{
ctx.textAlign = textAlignArr[i];
ctx.fillText(str,100,200 + (50 *(i + 1)));
} ctx.moveTo(0,200);
ctx.lineTo(ctx.canvas.width,200);
ctx.stroke();
ctx.beginPath(); str = "正";
var textBaselineArr = ["alphabetic","top","hanging","middle","ideographic","bottom"];
for(var i = 0;i<textBaselineArr.length;i++)
{
ctx.textBaseline = textBaselineArr[i];
ctx.fillText(str,100 + (80 *(i + 1)),200);
}

二、Canvas实现文字竖排案例

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<canvas width="1000px" height="700px" id="canvas"></canvas> <script type="text/template" id="templateText">
#北冥有鱼, 其名為鲲, 鲲之大, 不知其幾千里也。 化而為鸟, 其名為鹏, 鹏之背, 不知其幾千里也。 怒而飞, 其翼若垂天之雲。 是鸟也, 海运則將徙於南冥, 南冥者, 天池也。
#齐谐者, 志怪者也。 谐之言曰: 鹏之徙於南冥也, 水擊三千里, 摶扶搖而上者九萬里。 去以六月息者也, 野马也, 塵埃也, 生物之以息相吹也。 天之苍苍, 其正色邪? 其远而無所至极邪? 其视下也, 亦若是則已矣。
#且夫水之积也不厚, 則其负大舟也無力。 覆杯水於坳堂之上, 則芥為之舟, 置杯焉則胶, 水浅而舟大也。 风之积也不厚, 則其负大翼也無力。 故九萬里, 則风斯在下矣, 而後乃今培风。 背负青天而莫之夭厄者, 而後乃今將圖南。
#蜩與學鸠笑之曰: “ 我決起而飞, 枪榆枋, 時則不至, 而控於地而已矣。 奚以之九萬里而南為? ” 适莽苍者, 三飧而反, 腹犹果然。 适百里者, 宿舂粮。 适千里者, 三月聚粮。 之二虫, 又何知?
#小知不及大知, 小年不及大年。 奚以知其然也? 朝菌不知晦朔, 惠蛄不知春秋, 此小年也。 楚之南有冥灵者, 以五百歲為春, 五百歲為秋; 上古有大椿者, 以八千歲為春, 八千歲為秋; 而彭祖乃今以久特闻, 眾人匹之, 不亦悲乎?
#汤之问棘也是已: 穷發之北有冥海者, 天池也。 有鱼焉, 其廣數千里, 未有知其修者, 其名為鲲。 有鸟焉, 其名為鹏, 背若泰山, 翼若垂天之雲, 摶扶搖羊角而上者九萬里, 绝雲气, 负青天, 然後圖南, 且适南冥也。
#斥鹌笑之曰: “ 彼且奚适也? 我腾跃而上, 不过數仞而下, 翱翔蓬蒿之间, 耻亦飞之至也。 而彼且奚适也? ” 此小大之辨也。
#故夫知效一官, 行比一鄉, 德合一君, 而征一國者, 其自视也, 亦若此矣。 而宋荣子犹然笑之。 且舉世誉之而不加勸, 舉世非之而不加沮。 定乎內外之分, 辨乎荣辱之境, 斯已矣。 彼其於世, 未數數焉也。 虽然, 犹有未树也。
#夫列子禦风而行, 泠然善也, 旬有五日而後反。 彼於致福, 未數數然也。 此虽免乎行, 犹有所待者也。
#若夫乘天地之正, 而禦六气之辩, 以游無穷者, 彼且惡乎待哉! 故曰: 至人無己, 神人無功, 聖人無名。
</script> <script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var m = 30;
var h = ctx.canvas.height;
var w = ctx.canvas.width;
var count = Math.floor(w / m); for (var i = 0; i <= count; i++) {
ctx.beginPath();
ctx.moveTo(i*m - 0.5 ,0);
ctx.lineTo(i*m - 0.5 ,h);
ctx.strokeStyle = "#1D244F";
ctx.stroke();
} CanvasRenderingContext2D.prototype.fillTextVertical = function (text, x, y) {
var self = this;
self.textAlign = 'center';
self.textBaseline = 'middle'; var arrText = text.split('');
var arrWidth = arrText.map(function (letter) {
return self.measureText(letter).width;
}); arrText.forEach(function (letter, index) { if(letter == "#")
{
y = 12 + 50;
x = x - 30;
return;
} var letterWidth = arrWidth[index];
var code = letter.charCodeAt(0);
if (code <= 256) {
self.translate(x, y);
self.rotate(90 * Math.PI / 180);
self.translate(-x, -y);
} else if (index > 0 && text.charCodeAt(index - 1) < 256) {
y = y + arrWidth[index - 1] / 2;
}
self.fillText(letter, x, y);
self.setTransform(1, 0, 0, 1, 0, 0);
var letterWidth = arrWidth[index];
y = y + letterWidth; if(y >= (self.canvas.height - 12))
{
y = 12;
x = x - 30;
}
});
}; var templateText = document.getElementById("templateText").innerText;
ctx.font = '20px STKaiti, sans-serif';
ctx.fillStyle = "#1D244F";
ctx.fillTextVertical("逍遥游( 上) · 庄子", canvas.width - 25, 0);
ctx.fillTextVertical(templateText, canvas.width - 25, 12); </script>
</body>
</html>

前端开发系列028-基础篇之Canvas绘图(文本)的更多相关文章

  1. 从0到1用react+antd+redux搭建一个开箱即用的企业级管理后台系列(基础篇)

    背景 ​ 最近因为要做一个新的管理后台项目,新公司大部分是用vue写的,技术栈这块也是想切到react上面来,所以,这次从0到1重新搭建一个react项目架子,需要考虑的东西的很多,包括目录结构.代码 ...

  2. 前端开发:css基础知识之盒模型以及浮动布局。

    前端开发:css基础知识之盒模型以及浮动布局 前言 楼主的蛮多朋友最近都在学习html5,他们都会问到同一个问题 浮动是什么东西?  为什么这个浮动没有效果?  这个问题楼主已经回答了n遍.今天则是把 ...

  3. ESP8266开发之旅 基础篇① 走进ESP8266的世界

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  4. ESP8266开发之旅 基础篇② 如何安装ESP8266的Arduino开发环境

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  5. ESP8266开发之旅 基础篇③ ESP8266与Arduino的开发说明

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  6. openlayers5-webpack 入门开发系列一初探篇(附源码下载)

    前言 openlayers5-webpack 入门开发系列环境知识点了解: node 安装包下载webpack 打包管理工具需要依赖 node 环境,所以 node 安装包必须安装,上面链接是官网下载 ...

  7. leaflet-webpack 入门开发系列一初探篇(附源码下载)

    前言 leaflet-webpack 入门开发系列环境知识点了解: node 安装包下载webpack 打包管理工具需要依赖 node 环境,所以 node 安装包必须安装,上面链接是官网下载地址 w ...

  8. 【Windows10 IoT开发系列】配置篇

    原文:[Windows10 IoT开发系列]配置篇 Windows10 For IoT是Windows 10家族的一个新星,其针对不同平台拥有不同的版本.而其最重要的一个版本是运行在Raspberry ...

  9. ESP8266开发之旅 基础篇④ ESP8266与EEPROM

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  10. ESP8266开发之旅 基础篇⑥ Ticker——ESP8266定时库

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

随机推荐

  1. 测试工作中用到的MongoDB命令

    1.远程连接MongoDB mongo host:port/dbname (host和port根据自己需要修改) 连接成功页面如下: 2.显示所有数据库 show dbs 3.切换到oversea-a ...

  2. DIY记录之 USBasp

    序 笔者在上网浏览时发现了这个项目[0].刚好另一个DIY会需要对Attiny85进行烧写,并且感觉自己做一个USBasp来干这个事比较有趣,于是就买材料打板子准备DIY一个USBasp.这篇随笔是用 ...

  3. DPDI(Dispatch PDI)kettle调度管理平台升级内容

    DPDI升级内容(20240815版) DPDI online部署方式 定时任务优化(支持轮询机制,Cron可提示近5次运行时间) 运行任务优化(支持多机器分布式运行) 其它小功能优化 1. 首页可手 ...

  4. 虚拟机里的centos设置静态ip

    centos设置静态ip: https://blog.csdn.net/zhangatle/article/details/77417310 步骤: 修改网卡配置 重启网络服务 几个网络配置相关的命令 ...

  5. DP学习总结

    动态规划是一种通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法. -----OI Wiki 例.1-最大子段和 分析 DP四步 ⑴定义状态 定义\(dp_i\)表示以\(i\)结尾的最大子段 ...

  6. 三维装箱问题(3D Bin Packing Problem, 3D-BPP)

    提出问题 集装箱海运家具, 沙发, 茶几, 椅子等等, 有多少套家具,以及每个家具的长宽高都会告诉你. 把所有的家具都装进集装箱里, 要求通过算法算出一共需要多少集装箱. 1.要考虑怎样装, 需要的集 ...

  7. sonarqube+gitlab+jenkins+maven集成搭建(四)

    安装Gitlab 关闭firewalld防火墙和selinux防火墙,如图1-2:[root@localhost ~]# systemctl stop firewalld[root@localhost ...

  8. Python3_数据类型和变量

    Python3_数据类型和变量 一.数据类型 Python有五个标准的数据类型: Numbers(数字) String(字符串) List(列表) Tuple(元组) Dictionary(字典) 在 ...

  9. 使用C#构建一个同时问多个LLM并总结的小工具

    前言 在AI编程时代,如果自己能够知道一些可行的解决方案,那么描述清楚交给AI,可以有很大的帮助. 但是我们往往不知道真正可行的解决方案是什么? 我自己有过这样的经历,遇到一个需求,我不知道有哪些解决 ...

  10. WebAssembly在实际应用中的案例探究

    @charset "UTF-8"; .markdown-body { line-height: 1.75; font-weight: 400; font-size: 15px; o ...