canvas 原生 api 实现锥形渐变(conic-gradient)

canvas 原生 api 实现锥形渐变(conic-gradient)

前言

最近公司技术大佬给我们培训 canvas api 相关技术,末了给我们布置了一道 homework:
image.png

老实说,虽然接触 canvas 也才不到两年时间,但是由于平时工作中经常跟 canvas 原生的 api 打交道,因此对于这类培训本来是没有报多大期待的。

内心里面,感觉这类培训,无非就是老生常谈,大佬出来遛一遛,刷刷存在感罢了。

果然,如我所料,培训的过程并没有给人眼前一亮的感觉,给几个 api,带你逛逛 w3c、mdn 等等网站,然后演示一下代码。

不过虽然没有太多的惊喜,但是还是涨了些见识,毕竟平时使用的时候,也只是有些 api 会高频度的使用,大部分 api 也只是了解过,尝试过,甚至于有的 api 都没有用过。

但是大佬最后布置的这个 homework,感觉还是有点意思的。

没有捷径可走

起先我想,这种渐变难道 canvas 原生的 api 没有吗?

于是我就上 mdn 搜了一下,果然 canvas 没有提供:
image.png

canvas 只提供了线性渐变和径向渐变,但是令我很诧异的是,css 居然直接有现成的 api:
image.png

而且点进去一看,这个效果不就是想要的锥形渐变的效果吗!
image.png

看到这么个结果,不禁令我哑然失笑。

对哦,如果这么简单,有直接的 api,大佬还会留作 homework 吗?

自己动手

于是没办法,还是自己开动脑筋想想该怎么实现吧。

其实我还上网找了一番,发现了一篇张鑫旭大神写的有关于圆环的 css conic-gradient 效果实现文章挺有意思的。看完以后,不禁感叹,学到了!

感兴趣的小伙伴可以自己去学习学习:3种纯CSS实现中间镂空的12色彩虹渐变圆环方法

经过一番深思熟虑,我想到了两种实现方案:

  1. 折扇法
  2. 扇形拼接法

1. 折扇法

我想,90 后小时候应该都尝试过自己用白纸叠扇子吧,就是类似于下图这样:

image.png

(图片来自网络,如果原作者不同意引用,请告知,我会及时删除!)

其实这种扇子的制作原理也很简单:

  1. 将纸折成这样

fc7aeb3cc5d1688ab36e6e8e5db87454.jpg

  1. 从中间对折,将一边用胶水或者透明胶黏住

f43cf2d51cf1af9204b9914058e2e7ed.jpg

从上图可以看到,这就形成一个半圆了。

如果再拿一张等大的纸,如法炮制,然后将直径对粘,就形成一个圆形了。

当然纸没有可塑性,只能采用两张纸拼接才能形成这样的效果。

想想,我先创建一个正方形,然后沿 AD 方向拉一个线性渐变,然后我找到 O 点,将 B、C 都压缩到 O,然后将 AB和 CD 绕 O 分别向两边旋转,转到一起,这不刚好就能形成一个圆形么。

过程如下图所示:

image.png

虽然想法是不错,但是实现起来,却感觉并不是这么容易的,因为好像并没有发现可以通过类似变形的方式来操作图形。本来想试试是不是可以采用 transform,但是 transform 操作的对象也是整个图形,整个图形也是会作为一个整体参与变换的。

因此这个方式虽然好像挺合理的,但是目前应该是实现不了的。

2. 扇形拼接法

扇形拼接法,是最简单最直接的方式,也是直接可以实现的方式,比如我们可以将图形分为 360 块,也就是每 1° 就是一块扇形,通过 ctx.arc 方式或者 ctx.lineTo 等,绘制出每一块,每一块填充上对应的颜色,但是这个颜色是要通过所给色值的渐变去计算出来,然后填充进去的。

所以这种方式,唯一比较困难的地方就是计算出每一块扇形应该填充的颜色。

颜色的差值到底该怎么计算呢?

答案是,通过插值法。

所谓的插值法就是,统一将起始颜色换算成 rgba 的表示方式,比如其实点 r 值为 100,终止点 r 值为 150,如果平均分成 50 份,那么色值中的 r 值就每次递增 1。

虽然原理很简单,但是真的写起来,还是没那么容易的,里面涉及到大量的数学计算。

本来打算自己写一个的,但是后来无意中在网上找到一个解决方案,代码就不贴了,贴贴效果吧。

image.png

怎么样,这个效果是不是很炫酷呢!

感觉下载源码去学习一波吧。

最后附上源代码网址:http://jsdo.it/akm2/yr9B

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页