由于工作需求 , 需要写一个翻角效果;
demo链接
右上角需要从无的状态撕开一个标记 , 且有动画过程 , 上图是实现的效果图 , 不是gif
对这个翻角效果的难点在于没有翻开的时候露出的是dom下面的内容 , 实现角度来说 纯dom + css动画的设计方案并没有相出一个好的对策 ; 于是捡起了好久之前学的入门级别的canvas;
下面说一下实现思路:
将此动画分解成两部分 , 一部分是翻页出现的黑色三角区域 , 另一个是露出的橘色展示内容
对于橘色的展示内容区域相对好一些 , 因为是一个规则图形 , 而黑色区域相对较难;
先从基础canvas使用方法说起 :
布局如上 , 这里要说一点踩过的坑是 , canvas必须要设置上width 与 height , 此处并非为css中的width与height;而是写在dom上的属性 ; 因为dom上的width与height标识了canvas的分辨率(个人理解); 所以此canvas画布分辨率为100*100 , 而展示尺寸是可以通过css控制;
js中首先要做的是获取canvas对象 ,
ctx这个绘画上下文在这个教程中起到的作用至关重要 ; 它提供了非常强大的api , 比如用于画线 , 填充 , 写文字等 , 这样看来理解为画笔会更为简明一些;
此处效果需要用到的api如下 ( 不做详细解释 , 可w3c自行查询 );
可能方法列举的不够详尽 , 见谅.
首先是绘制黑色翻出的部分 , 图形分解为如下几部分(请根据上图脑补)
于是第一步 我们要先将画笔移动到 起始位置
然后
于是第一个向右下的半弧完成 , 此时canvas上没有任何绘制内容 , 因为还没有执行过绘制方法例如stroke或fill,
接下来直线向下就是简单的移动
这个时候我们接下来应该画向右的半圆 , 这个时候再用贝塞尔曲线绘制 实在有些不太合适 , 因为从图上来看 , 这里完全是1/4的圆 , 所以要使用canvas提供的画圆的api
上述画圆的代码意为 : 以(60,40)点为圆心 , 5为半径 , 逆时针从 180度绘制到90度 , 180度就是圆心的水平向左 到达点(55,40) , 与上一步连接上 , 然后又因为屏幕向下为正 , 90度在圆心正下方 , 所以绘制出此半圆
于是按照相同的步骤 水平向右
然后再次使用贝塞尔曲线用第一步的思路画出向右下的弧;
同理 上述贝塞尔曲线可以理解为一条从( 75 , 45 ) 到 ( 100 , 50 )的线被 ( 95 , 45 )”吸”成曲线
最后链接起点 , 闭合绘画区域
这个时候黑色区域的翻页就画完了 , 然后此时开始填充颜色 ;
我们通过上述代码创建一个 从( 50 , 50 )点到(75 , 75)点的线性渐变 , 颜色从 #ccc 到 #111 到 #000 ; 创建高光效果;
然后填充:
于是翻页效果的一半就算完成了。
至此 , 我要说一点我领悟的canvas的绘画”套路”;
对于上述教程中 , 有一步我们使用了一个词叫做 闭合 , 闭合的概念在canvas中是真是存在的 , 对于fill方法来说 填充的区间是有一个空间尺寸才可以的 , 比如我们绘画的这个黑色的三角形 , 加入我们最后没有将终点与起点相连接 , 同样canvas会自动帮我们链接最后一笔绘画的位置到起点 , 强制行程闭合空间 , 而这样我们想再多画几个新的闭合空间就麻烦了 , 所以canvas提供了如下api 新建闭合路径:
所以对于我们接下来要绘制右上角橘色区域来说 , 我们在绘制黑色区域之前首先要做的是
然后在fill之前 我们应该
也就是说beginPath 到 closePath之间标识着我们自己的一个完整的绘画阶段.
那么接下来绘制右上角的橘色区域就简单很多了:
于是右上角的橘色区域我们就绘制完成了;
文字绘制
接下来绘制”new” , 实际上是使用canvas简单的文本绘制 , 代码如下:
对于上述代码中 , 文字的相关api是属于没有难度的 , 只是设置而已 , 需要理解的部分在于 translate和rotate,
这两个方法中 translate的意思为移动canvas画布的( 0 , 0 )点到 (78,22),然后旋转45度, 再将文字渲染在原点 , 实际就是 ( 78 , 22 ) 这个点上, 此时我们对canvas的画笔做出了非常大的修改
比如我们修改了旋转角度以及画布圆点 , 这种操作或许只在我们需要绘制倾斜的new 的时候需要 , 后期可能就不需要使用了 ,
还好canvas的画笔是存在”状态”的, 通过ctx.save();可以保存当前画笔的状态 , 通过ctx.restore();可以恢复到上次画笔保存的状态.