前言
最近公司技术大佬给我们培训 canvas api 相关技术,末了给我们布置了一道 homework:<br /> image.png老实说,虽然接触 canvas 也才不到两年时间,但是由于平时工作中经常跟 canvas 原生的 api 打交道,因此对于这类培训本来是没有报多大期待的。
内心里面,感觉这类培训,无非就是老生常谈,大佬出来溜溜,刷刷存在感罢了。
果然,如我所料,培训的过程并没有给人眼前一亮的感觉,给几个 api,带你逛逛 w3c、mdn 等等网站,然后演示一下代码。
不过虽然没有太多的惊喜,但是还是涨了些见识,毕竟平时使用的时候,也只是有些 api 会高频度的使用,大部分 api 也只是了解过,尝试过,甚至于有的 api 都没有用过。
但是大佬最后布置的这个 homework,感觉还是有点意思的。
<a name="IqbDI"></a>
没有捷径可走
起先我想,这种渐变难道 canvas 原生的 api 没有吗?
于是我就上 mdn 搜了一下,果然 canvas 没有提供:<br /> image.png canvas 只提供了线性渐变和径向渐变,但是令我很诧异的是,css 居然直接有现成的 api:<br /> image.png 而且点进去一看,这个效果不就是想要的锥形渐变的效果吗!<br /> image.png看到这么个结果,不禁令我哑然失笑。
对哦,如果这么简单,有直接的 api,大佬还会留作 homework 吗?
<a name="DFK0s"></a>
自己动手
于是没办法,还是自己开动脑筋想想该怎么实现吧。
其实我还上网找了一番,发现了一篇张鑫旭大神写的有关于圆环的 css conic-gradient 效果实现文章挺有意思的。看完以后,不禁感叹,学到了!
感兴趣的小伙伴可以自己去学习学习:3种纯CSS实现中间镂空的12色彩虹渐变圆环方法
经过一番深思熟虑,我想到了两种实现方案:
- 折扇法
- 扇形拼接法
<a name="2B0bS"></a>
1. 折扇法
我想,90 后小时候应该都尝试过自己用白纸叠扇子吧,就是类似于下图这样:
image.png(图片来自网络,如果原作者不同意引用,请告知,我会及时删除!)
其实这种扇子的制作原理也很简单:
- 将纸折成这样
- 从中间对折,将一边用胶水或者透明胶黏住
从上图可以看到,这就形成一个半圆了。
如果再拿一张等大的纸,如法炮制,然后将直径对粘,就形成一个圆形了。
当然纸没有可塑性,只能采用两张纸拼接才能形成这样的效果。
想想,我先创建一个正方形,然后沿 AD 方向拉一个线性渐变,然后我找到 O 点,将 B、C 都压缩到 O,然后将 AB和 CD 绕 O 分别向两边旋转,转到一起,这不刚好就能形成一个圆形么。
过程如下图所示:
image.png虽然想法是不错,但是实现起来,却感觉并不是这么容易的,因为好像并没有发现可以通过类似变形的方式来操作图形。本来想试试是不是可以采用 transform,但是 transform 操作的对象也是整个图形,整个图形也是会作为一个整体参与变换的。
因此这个方式虽然好像挺合理的,但是目前应该是实现不了的。
<a name="fjFMp"></a>
2. 扇形拼接法
扇形拼接法,是最简单最直接的方式,也是直接可以实现的方式,比如我们可以将图形分为 360 块,也就是每 1° 就是一块扇形,通过 ctx.arc
方式或者 ctx.lineTo 等,绘制出每一块,每一块填充上对应的颜色,但是这个颜色是要通过所给色值的渐变去计算出来,然后填充进去的。
所以这种方式,唯一比较困难的地方就是计算出每一块扇形应该填充的颜色。
颜色的差值到底该怎么计算呢?
答案是,通过插值法。
所谓的插值法就是,统一将起始颜色换算成 rgba 的表示方式,比如其实点 r 值为 100,终止点 r 值为 150,如果平均分成 50 份,那么色值中的 r 值就每次递增 1。
虽然原理很简单,但是真的写起来,还是没那么容易的,里面涉及到大量的数学计算。
本来打算自己写一个的,但是后来无意中在网上找到一个解决方案,代码就不贴了,贴贴效果吧。
image.png怎么样,这个效果是不是很炫酷呢!
感觉下载源码去学习一波吧。
最后附上源代码网址:http://jsdo.it/akm2/yr9B
网友评论