Canvas 文本填充线性渐变的使用详解


Posted in HTML / CSS onJune 22, 2020

前言

在 Canvas 中对文本填充水平或垂直的线性渐变可以轻易实现,而带角度的渐变就复杂很多;就好像下面这样,假设文本矩形宽为 W, 高为 H, 左上角坐标为 X, Y

Canvas 文本填充线性渐变的使用详解

猜想与答案

给出两个答案:

Canvas 文本填充线性渐变的使用详解

正确答案是图二,因为这样得出来的坐标生成的渐变最紧接文本矩形边界,它的运动轨迹如下动图:

Canvas 文本填充线性渐变的使用详解

(图来源:Do you really know CSS linear-gradients)

渐变起点与终点坐标的计算

所以,渐变的起点与终点坐标该怎么计算呢?答:

  1. 先求得起点与终点的长度(距离)。
  2. 根据长度与文本矩形的中心点坐标分别计算出起点与终点坐标。

线性渐变长度的计算 W3C 给出了一个公式(A 表示角度):

gradientLineLength = abs(W * sin(A)) + abs(H * cos(A))

不过,该公式主要应用于 CSS 的线性渐变设置,即以 12 点钟方向为 0°,顺时针旋转。

而我们需要的是以 3 点钟方向为 0°,逆时针旋转,即公式为:

gradientLineLength = abs(W * cos(A)) + abs(H * sin(A))

// 半长:
halfGradientLineLength = (abs(W * cos(A)) + abs(H * sin(A))) / 2

那么这个公式是怎么来的呢?以下是笔者的求解:

Canvas 文本填充线性渐变的使用详解

由图可得以下方程组:

Canvas 文本填充线性渐变的使用详解

因此可推导出:

Canvas 文本填充线性渐变的使用详解

化简后为:

Canvas 文本填充线性渐变的使用详解

所以 c1 + c2 为:

Canvas 文本填充线性渐变的使用详解

由三角函数平方公式知:cos(A) * cos(A) = 1 - sin(A) * sin(A), 代入 c1 + c2

Canvas 文本填充线性渐变的使用详解

第一步化简后:

Canvas 文本填充线性渐变的使用详解

最后的结果就是:

Canvas 文本填充线性渐变的使用详解

因为 sin, cos 在函数周期内存在负值(见下面角度对应的三角函数周期图),所以线性渐变的长度需要取绝对值。

至此,我们知道了线性渐变长度,文本矩形的中心点坐标很好算,即:

centerX = X + W / 2
centerY = Y + H / 2

所以,起点与终点的坐标分别为:

startX = centerX - cos(A) * halfGradientLineLength
startY = centerY + sin(A) * halfGradientLineLength

endX = centerX + cos(A) * halfGradientLineLength
endY = centerY - sin(A) * halfGradientLineLength

看看最终效果

Canvas 文本填充线性渐变的使用详解

经验注释

进行三角函数计算时,应尽量避免先用 tan, 因为 tan 在其周期内存在无穷值,需要做特定的条件判断,而 sin, cos 没有此类问题,代码书写更为简洁清晰并且不会因疏忽产生错误,见下面三角函数与角度的对应关系周期图。

Canvas 文本填充线性渐变的使用详解

参阅

Do you really know CSS linear-gradients?

MDN linear-gradient

W3C - CSS Images Module Level 3 # linear-gradients

到此这篇关于Canvas 文本填充线性渐变的使用详解的文章就介绍到这了,更多相关Canvas文本填充线性渐变内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章,希望大家以后多多支持三水点靠木!

HTML / CSS 相关文章推荐
CSS3混合模式mix-blend-mode/background-blend-mode简介
Mar 15 HTML / CSS
CSS3文本换行word-wrap解决英文文本超过固定宽度不换行
Oct 10 HTML / CSS
纯CSS实现的大小渐变、渐远效果
Apr 15 HTML / CSS
CSS3的first-child选择器实战攻略
Apr 28 HTML / CSS
HTML5中的postMessage API基本使用教程
May 20 HTML / CSS
Html5剪切板功能的实现代码
Jun 29 HTML / CSS
基于HTML5超酷摄像头(HTML5 webcam)拍照功能实现代码
Dec 13 HTML / CSS
html5中canvas图表实现柱状图的示例
Nov 13 HTML / CSS
用canvas做一个DVD待机动画的实现代码
Apr 12 HTML / CSS
HTML5触摸事件(touchstart、touchmove和touchend)的实现
May 08 HTML / CSS
Html5嵌入钉钉的实现示例
Jun 04 HTML / CSS
HTML5播放实现rtmp流直播
Jun 16 HTML / CSS
HTML5播放实现rtmp流直播
Jun 16 #HTML / CSS
HTML5实现应用程序缓存(Application Cache)
Jun 16 #HTML / CSS
html5实现九宫格抽奖可固定抽中某项奖品
Jun 15 #HTML / CSS
HTML5页面无缝闪开的问题及解决方案
Jun 11 #HTML / CSS
Html5导航栏吸顶方案原理与对比实现
Jun 10 #HTML / CSS
浅析图片上传及canvas压缩的流程
Jun 10 #HTML / CSS
原生canvas制作画图小工具的踩坑和爬坑
Jun 09 #HTML / CSS
You might like
帅气的琦玉老师
2020/03/02 日漫
php+mysqli实现批量替换数据库表前缀的方法
2014/12/29 PHP
PHP获取指定月份第一天和最后一天的方法
2015/07/18 PHP
PHP框架Laravel学习心得体会
2015/10/28 PHP
php 实现301重定向跳转实例代码
2016/07/18 PHP
php array_slice 取出数组中的一段序列实例
2016/11/04 PHP
PHP实现的常规正则验证helper公共类完整实例
2017/04/27 PHP
PHP编程实现阳历转换为阴历的方法实例
2017/08/08 PHP
php实现的mongoDB单例模式操作类
2018/01/20 PHP
php遍历目录下文件并按修改时间排序操作示例
2019/07/12 PHP
JS实现商品倒计时实现代码
2013/05/03 Javascript
javascript 获取网页标题代码实例
2014/01/22 Javascript
jQuery实现每隔几条元素增加1条线的方法
2016/06/27 Javascript
JS控制div跳转到指定的位置的几种解决方案总结
2016/11/05 Javascript
详解Angular2组件之间如何通信
2017/06/22 Javascript
理解 javascript 中的函数表达式与函数声明
2017/07/07 Javascript
vue引入微信sdk 实现分享朋友圈获取地理位置功能
2019/07/04 Javascript
适合前端Vue开发童鞋的跨平台Weex的使用详解
2019/10/16 Javascript
JavaScript用document.write()输出换行的示例代码
2020/11/26 Javascript
[05:15]2018年度CS GO社区贡献奖-完美盛典
2018/12/16 DOTA
python re正则表达式模块(Regular Expression)
2014/07/16 Python
Python实现拼接多张图片的方法
2014/12/01 Python
在Python中操作文件之seek()方法的使用教程
2015/05/24 Python
python将.ppm格式图片转换成.jpg格式文件的方法
2018/10/27 Python
python爬虫 猫眼电影和电影天堂数据csv和mysql存储过程解析
2019/09/05 Python
Python爬取YY评级分数并保存数据实现过程解析
2020/06/01 Python
keras做CNN的训练误差loss的下降操作
2020/06/22 Python
利用python清除移动硬盘中的临时文件
2020/10/28 Python
数据库笔试题
2013/05/09 面试题
叙述DBMS对数据控制功能有哪些
2016/06/12 面试题
企业项目策划书
2014/01/11 职场文书
五十岁生日宴会答谢词
2014/01/15 职场文书
联谊会主持词
2014/03/26 职场文书
公司晚会主持词
2019/04/17 职场文书
创业计划书之牛肉汤快餐店
2019/10/08 职场文书
浅谈Go语言多态的实现与interface使用
2021/06/16 Golang