作者:凹凸曼 - Barrior


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

猜想与答案

给出两个答案:

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

(图来源: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

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

由图可得以下方程组:

因此可推导出:

化简后为:

所以 c1 + c2 为:

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

第一步化简后:

最后的结果就是:

因为 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

看看最终效果

经验注释

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

参阅:

Do you really know CSS linear-gradients?

MDN linear-gradient

W3C - CSS Images Module Level 3 # linear-gradients


欢迎关注凹凸实验室博客:aotu.io

或者关注凹凸实验室公众号(AOTULabs),不定时推送文章:

图形处理:给 Canvas 文本填充线性渐变的更多相关文章

  1. css之为文本添加线性渐变和外描边

    css之为文本添加线性渐变和外描边  一.效果: 描边:描边+渐变: 二.描边: api:text-stroke 问题:text-stroke的描边是居中描边,无法直接设置外描边 解决:在before ...

  2. 使用canvas来完成线性渐变和径向渐变的功能

    fillStyle的第二种使用情况就是渐变色的填充.渐变色就分为线性渐变色和径向渐变色.   线性渐变:大致分为两步 这里又会使用到canvas的两个新的函数.   第一步 : 使用一个新的函数cre ...

  3. HTML5 Canvas ( 线性渐变, 升级版的星空 ) fillStyle, createLinearGradient, addColorStop

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  4. Canvas使用渐变之-线性渐变详解

    在canvas里面,除了使用纯色,我们还能把填充和笔触样式设置为渐变色:线性渐变和径向渐变. 线性渐变 createLinearGradient(x0,y0,x1,y1)  返回 CanvasGrad ...

  5. 如何给SVG填充和描边应用线性渐变

    给SVG元素应用填充和描边有三种方法(戳这里学习SVG填充和描边的相关内容).你可以使用纯色.图案或渐变.前面两种方法我们之前已经讲过了,现在我们来讨论第三种方法——渐变. SVG提供了两种渐变——线 ...

  6. fillStyle线性渐变

    废话小说,沾待马 <!DOCTYPE HTML> <head> <meta charset = "utf-8"> <title>ca ...

  7. CSS3-canvas绘制线性渐变

    <!doctype html><html><head><meta charset="utf-8"><title>canv ...

  8. html5 基本布局+新标签+新选择器 + 线性渐变

    html5 基本布局+新标签 <!DOCTYPE html> <html lang="en"> <head> <meta charset= ...

  9. 【 D3.js 高级系列 — 5.1 】 颜色插值和线性渐变

    颜色插值指的是给出两个 RGB 颜色值,两个颜色之间的值通过插值函数计算得到.线性渐变是添加到 SVG 图形上的过滤器,只需给出两端的颜色值即可. 1. 颜色插值 在[高级 - 第 5.0 章]里已经 ...

随机推荐

  1. npm run dev启动项目,electron提示throw new Error('Electron failed to install correctly, please delete node_modules/electron and try installing again')

    npm run dev 项目,提示 throw new Error('Electron failed to install correctly, please delete node_modules/ ...

  2. 温故知新-java虚拟机

    文章目录 java虚拟机是什么? jvm的体系结构 第一个类加载子系统 类的生命周期 加载器分类 类加载机制 第二个运行时数据区(内存结构) GC算法和收集器 如何判断对象可以被回收? 如何判断一个常 ...

  3. PL/SQL编程急速上手

    结构化查询语言(SQL)是第四代编程语言的典型,这种命令式的语言更像一种指令,使用它,你只需要告诉计算机“做什么”,而不用告诉计算机“怎么做”.第四代编程语言普遍具有简单.易学.能更快的投入生产等优点 ...

  4. 如何在宝塔上的Nginx实现负载均衡

    创建一个指向服务器本身的localhost站点(127.0.0.1)和一个指向服务器的站点,域名和IP都可以.  I.对域名站点配置: upstream myproj { server 127.0.0 ...

  5. 停电后,在UPS电源下服务器自动关机脚本

    一年总有那么几次莫明停电,公司的服务器经不起这样的折腾 写了一个断电后UPS备用电源自动关机的脚本 原理就是检测路由器网关是否能ping通,长时间持续ping不通视为停电了 路由器不要接到ups上 用 ...

  6. git新手入门问题总结

    git新手入门问题总结 前言 本人为2019年6月份刚刚毕业,大三暑假中旬来到上海,实习时间大致为十个月,在这十个月里面学到了许多关于git使用方面的知识 经常会逛开源中国水水动态,看看技术帖子学习知 ...

  7. Memory layout

    Text Segment       Text Segment,通常也被称为代码段. 为了防止 heap 或是 stack 的溢出,text 段常被安排在 heap 或是 stack 之后. Text ...

  8. 不适合使用Mycat的场景

    1.非分片字段查询 Mycat中的路由结果是通过分片字段和分片方法来确定的.例如下图中的一个Mycat分库方案: 根据 tt_waybill 表的 id 字段来进行分片 分片方法为 id 值取 3 的 ...

  9. TensorFlow从0到1之程序结构(5)

    TensorFlow 与其他编程语言非常不同. 首先通过将程序分为两个独立的部分,构建任何拟创建神经网络的蓝图,包括计算图的定义及其执行.起初这对于传统程序员来说看起来很麻烦,但是正是图定义和执行的分 ...

  10. 关联函数-web_reg_save_param

    int web_reg_save_param(const char *ParamName,<List of Attributes>,LAST) 返回值:成功时返回LR_PASS,失败时返回 ...