canvas翻角效果,canvas纯绘制雨伞

一句话来说的 canvas 翻角效果

2017/12/07 · HTML5 ·
Canvas

原稿出处: 敖爽   

由于工作要求 ,
须要写一个翻角效果;亚洲必赢官网 1

demo链接

右上角必要从无的动静撕开一个标记 , 且有动画进程 , 上图是贯彻的作用图 ,
不是gif

对那几个翻角效果的难处在于没有翻动的时候揭穿的是dom上边的始末 ,
已毕角度来说 纯dom + css动画的设计方案并不曾相出一个好的预谋 ;
于是捡起了好久事先学的入门级其余canvas;

上面说一下兑现思路:

  1. 动画片拆分 :
    将此动画分解成两局地 , 一部分是翻页出现的棕色三角区域 ,
    另一个是发泄的橘色显示内容
    对此橘色的显得内容区域相对好有的 , 因为是一个规则图形 ,
    而灰色区域相对较难;

先从基础canvas使用方式说起 :

<div class=”container”> <canvas class=”myCanvas” width=”100″
height=”100″></canvas> </div>

1
2
3
<div class="container">
    <canvas class="myCanvas" width="100" height="100"></canvas>
</div>

布局如上 , 那里要说一点踩过的坑是 , canvas必须求安装上width 与 height ,
此处并非为css中的width与height;而是写在dom上的属性 ;
因为dom上的width与height标识了canvas的分辨率(个人领悟);
所以此canvas画布分辨率为100*100 , 而呈现尺寸是足以因而css控制;

js中率先要做的是获取canvas对象 ,

var canvas = document.querySelector(‘.myCanvas’); //获取canvas对应dom
var ctx = canvas.getContext(‘2d’); //此方法比较基础 ,
意为取得canvas绘画2d内容的工具(上下文) var cw = 100; //分辨率 ,
其实直接从dom上获得可能更好些 var ch = 100; //分辨率 ,
其实直接从dom上得到可能更好些

1
2
3
4
var canvas = document.querySelector(‘.myCanvas’); //获取canvas对应dom
var ctx = canvas.getContext(‘2d’); //此方法较为基础 , 意为获取canvas绘画2d内容的工具(上下文)
var cw = 100; //分辨率 , 其实直接从dom上获取可能更好些
var ch = 100; //分辨率 , 其实直接从dom上获取可能更好些

ctx那些绘画上下文在那一个课程中起到的功效重点 ; 它提供了相当强大的api
, 比如用于画线 , 填充 , 写文字等 , 那样看来精晓为画笔会愈来愈显然一些;

那里效果须要运用的api如下 ( 不做详细分解 , 可w3c自行查询 );

ctx.save() //保存上下文状态 (比如画笔尺寸 颜色 旋转角度) ctx.restore()
//重临上次保存的上下文状态 ctx.moveTo(x,y) //上下文移动到具体地点ctx.lineTo(x,y) //上下文以划线的花样活动到某地方 ctx.stroke() //
画线动作 ctx.quadraticCurveTo()
//上下文(画笔)按贝塞尔曲线移动(简单了解为可控的曲线即可) ctx.arc()
//画圆 ctx.beginPath() //开启新的画笔路径 ctx.closePath()
//关闭当前画笔路径 ctx.createLinearGradient() //成立canvas渐变对象
ctx.fill() //对闭合区域开展填充 ctx.globalCompositeOperation
//画笔的交汇情势

1
2
3
4
5
6
7
8
9
10
11
12
ctx.save() //保存上下文状态 (比如画笔尺寸 颜色 旋转角度)
ctx.restore() //返回上次保存的上下文状态
ctx.moveTo(x,y) //上下文移动到具体位置
ctx.lineTo(x,y) //上下文以划线的形式移动到某位置
ctx.stroke() // 画线动作
ctx.quadraticCurveTo() //上下文(画笔)按贝塞尔曲线移动(简单理解为可控的曲线即可)
ctx.arc() //画圆
ctx.beginPath() //开启新的画笔路径
ctx.closePath() //关闭当前画笔路径
ctx.createLinearGradient() //创建canvas渐变对象
ctx.fill() //对闭合区域进行填充
ctx.globalCompositeOperation //画笔的重叠模式

或许方法列举的不够详尽 , 见谅.

首先是绘制黑色翻出的部分 , 图形分解为如下几部分(请按照上图脑补)

  1. 左上角向右下的半弧 ╮
  2. 接下来是竖直向下的竖线 |
  3. 下一场是向右的半圆 ╰
  4. 再然后是向右的横线
  5. 继而如故向右下的半弧 ╮
  6. 说到底是将线连接会源点

于是第一步 大家要先将画笔移动到 伊始地点

ctx.moveTo(50,0);

1
ctx.moveTo(50,0);

然后

ctx.quadraticCurveTo(55 , 5 , 55 , 25); //
可以知晓为从(50,0)那些点划线到(55,25)那些点 ,
中间会遭遇(55,5)那一个点将直线想磁铁一样”吸”成曲线;

1
ctx.quadraticCurveTo(55 , 5 , 55 , 25); // 可以理解为从(50,0)这个点划线到(55,25)这个点 , 中间会受到(55,5)这个点将直线想磁铁一样"吸"成曲线;

于是首个向右下的半弧落成 , 此时canvas上从未有过其他绘制内容 ,
因为还尚未进行过绘制方法例如stroke或fill,

接下去直线向下就是概括的运动

ctx.lineTo(55 , 40);

1
ctx.lineTo(55 , 40);

本条时候大家接下去应该画向右的半圆 , 这一个时候再用贝塞尔曲线绘制
实在有点不太合适 , 因为从图上来看 , 那里完全是1/4的圆 ,
所以要动用canvas提供的画圆的api

ctx.arc(60 , 40 , 5 , Math.PI , Math.PI / 2 , true);

1
ctx.arc(60 , 40 , 5 , Math.PI , Math.PI / 2 , true);

上述画圆的代码意为 : 以(60,40)点为圆心 , 5为半径 , 逆时针从
180度绘制到90度 , 180度就是圆心的水平向左 到达点(55,40) , 与上一步连接上
, 然后又因为显示器向下为正 , 90度在圆心正下方 , 所以绘制出此半圆

于是乎按照同样的步骤 水平向右

ctx.lineTo(75 , 45);

1
ctx.lineTo(75 , 45);

然后重新行使贝塞尔曲线用第一步的思路画出向右下的弧;

ctx.quadraticCurveTo( 95 , 45 , 100 , 50 );

1
ctx.quadraticCurveTo( 95 , 45 , 100 , 50 );

同理 上述贝塞尔曲线可以知道为一条从( 75 , 45 ) 到 ( 100 , 50 )的线被 (
95 , 45 )”吸”成曲线

末尾链接源点 , 闭合绘画区域

ctx.lineTo(50 , 0);

1
ctx.lineTo(50 , 0);

其一时候黄色区域的翻页就画完了 , 然后此时开始填写颜色 ;

var gradient = ctx.createLinearGradient(50 , 50 , 75 , 75);
gradient.addColorStop(0 , ‘#ccc’); gradient.addColorStop(0.7 ,
‘#111’); gradient.addColorStop(1 , ‘#000’);

1
2
3
4
var gradient = ctx.createLinearGradient(50 , 50 , 75 , 75);
gradient.addColorStop(0 , ‘#ccc’);
gradient.addColorStop(0.7 , ‘#111’);
gradient.addColorStop(1 , ‘#000’);

大家经过上述代码成立一个 从( 50 , 50 )点到(75 , 75)点的线性渐变 , 颜色从
#ccc 到 #111 到 #000 ; 创设高光效果;
然后填充:

ctx.fillStyle = gradient; ctx.fill();

1
2
ctx.fillStyle = gradient;
ctx.fill();

于是翻页效果的一半即便完事了。

至此 , 我要说一点自己了解的canvas的绘画”套路”;

对于上述教程中 , 有一步大家采纳了一个词叫做 闭合 ,
闭合的定义在canvas中是真是存在的 , 对于fill方法来说
填充的间距是有一个上空尺寸才方可的 , 比如大家描绘的这几个青色的三角形形 ,
参预大家最后没有将终点与起源相接接 ,
同样canvas会自动帮大家链接最终一笔绘画的职分到起源 , 强制行程闭合空间 ,
而那样大家想再多画多少个新的密闭空间就麻烦了 , 所以canvas提供了如下api
新建闭合路径:

ctx.beginPath(); //新建路径 ctx.closePath(); //闭合路径

1
2
ctx.beginPath(); //新建路径
ctx.closePath(); //闭合路径

因而对于大家接下去要绘制右上角橘色区域来说 ,
大家在绘制褐色区域此前率先要做的是

ctx.beginPath(); …

1
2
ctx.beginPath();

下一场在fill之前 我们相应

ctx.closePath();

1
ctx.closePath();

也就是说beginPath 到 closePath之间标识着大家协调的一个整机的绘画阶段.

那么接下去绘制右上角的橘色区域就不难很多了:

ctx.beginPath(); ctx.moveTo(50,0); ctx.lineTo(100,50);
ctx.lineTo(100,0); ctx.lineTo(50,0); ctx.closePath(); ctx.fillStyle =
‘#ff6600’; ctx.fill();

1
2
3
4
5
6
7
8
ctx.beginPath();
ctx.moveTo(50,0);
ctx.lineTo(100,50);
ctx.lineTo(100,0);
ctx.lineTo(50,0);
ctx.closePath();
ctx.fillStyle = ‘#ff6600’;
ctx.fill();

于是乎右上角的橘色区域我们就绘制达成了;

文字绘制

接下去绘制”new” , 实际上是选拔canvas不难的公文绘制 , 代码如下:

var deg = Math.PI / 180; ctx.globalCompositeOperation = ‘source-atop’;
//canvas层叠格局 ctx.beginPath(); ctx.font = ’14px Arial’;
//设置字体大小 字体 ctx.textAlign = ‘center’; // 字体对齐格局ctx.translate(78 , 22); // 移动canvas画布圆点 ctx.rotate(45 * deg); //
旋转画布 ctx.fillStyle = ‘#fff’; // 设置文字颜色 ctx.fillText(‘NEW’ , 0
, 0); //文字绘制动作 ctx.closePath();

1
2
3
4
5
6
7
8
9
10
var deg = Math.PI / 180;
ctx.globalCompositeOperation = ‘source-atop’; //canvas层叠模式
ctx.beginPath();
ctx.font = ’14px Arial’; //设置字体大小 字体
ctx.textAlign = ‘center’; // 字体对齐方式
ctx.translate(78 , 22);  // 移动canvas画布圆点
ctx.rotate(45 * deg);    // 旋转画布
ctx.fillStyle = ‘#fff’;  // 设置文字颜色
ctx.fillText(‘NEW’ , 0 , 0); //文字绘制动作
ctx.closePath();

对于上述代码中 , 文字的连带api是属于尚未难度的 , 只是安装而已 ,
要求精通的一部分在于 translate和rotate,

那多少个艺术中 translate的意味为运动canvas画布的( 0 , 0 )点到
(78,22),然后旋转45度, 再将文字渲染在原点 , 实际就是 ( 78 , 22 )
这些点上, 此时我们对canvas的画笔做出了要命大的改动

比如我们修改了旋转角度以及画布圆点 ,
那种操作可能只在大家须求绘制倾斜的new 的时候需要 ,
前期可能就不必要动用了 ,

还好canvas的画笔是存在”状态”的, 通过ctx.save();可以保留当前画笔的场馆 ,
通过ctx.restore();可以苏醒到上次画笔保存的状态.

于是自己个人知道到 , 在开发canvas动画时 , 一个较好的习惯就是 ,
在beginPath以前先ctx.save();保存画笔状态 ,
在closePath后ctx.restore();复苏在此以前的画笔状态 ,
那样大家的每一个绘制阶段对于画笔的改动都将是不会有影响的.( 个人经验 )

ctx.globalCompositeOperation = ‘source-atop’; //canvas层叠格局

1
ctx.globalCompositeOperation = ‘source-atop’; //canvas层叠模式

代码中那部分是指 大家绘制的文字new 与 橘色三角形区域的重合关系 ,
此方法取值较多 , 此处不做过多介绍 , source-atop值可以使重叠区域保留 ,
新绘制的情节在重叠区域以外的一部分消失 , 以此达到new在中间的法力

到此地大家就付出好了翻角效果的一心突显的图景 ,
那么如何让这些区域动起来吧?

此间需求运用h5提供的用来刷帧的函数 requestAnimationFrame ;

此格局可概括明了为 16微秒的定时器 ,
然而决定的是可以再相继环境中机动匹配到可完成的相持顺利的帧率 ,
实际并不是定时器哈~

大家须要在那一个轮回执行的函数中 , 将上述的绘图内容重复绘制 , 例如 :

function draw(){ drawMethod(); //绘制三角等内容
window.requestAnimationFrame(function(){ draw(); }) } function
drawMethod(){ //… }

1
2
3
4
5
6
7
8
9
function draw(){
    drawMethod(); //绘制三角等内容
    window.requestAnimationFrame(function(){
        draw();
    })
}
function drawMethod(){
    //…
}

那样大家就可以达到刷帧的意义了 ,
于是随即大家要做的就是决定绘制时各类数值的参数.

比如大家是以 (50,0)为起源 , ( 100 , 50
)为终端那样的七个运动点为绘制标记的 , 若是大家将多个点展开仓储 ,
并且每便执行drawMethod的时候更新点的职位 , 然后清空canvas ,再绘制新的点
那么就足以达标canvas动起来的目标了;

实际效果链接在那里

在地点的demo链接中 , 自己定义了一个进程与加快度的关系 ,
比如每回绘制四回canvas后 , 将积存的点坐标进行追加一个speed值 ,
然后speed值也增多 , 那样speed对应的概念就是速度 ,
而speed的扩大值对应的就是加速度. 所以就表现了一种加快移动的场合;

如上内容纯属个人了解内容 , 若果有哪个地方知道错了 欢迎各位大大指导 ,
另demo链接失效可私信.

1 赞 1 收藏
评论

亚洲必赢官网 2

<!DOCTYPE html>

栅格EDIT

由于网上广大都是用比比皆是算法和逻辑使用canvas进行绘图,但奇迹也无能为力缓解一些小众要求

<html lang=”en”>

在我们开端画画此前,大家必要掌握一下画布栅格(canvas
grid)以及坐标空间。上一页中的HTML模板中有个宽150px,
高150px的canvas元素。如右图所示,canvas元素默许被网格所覆盖。常常来说网格中的一个单元相当于canvas元素中的一像素。栅格的起源为左上角(坐标为(0,0))。所有因素的岗位都相对于原点定位。所以图中灰色方形左上角的坐标为离开左边(X轴)x像素,距离上边(Y轴)y像素(坐标为(x,y))。在学科的终极我们会移动原点到差其他坐标上,旋转网格以及缩放。现在大家依旧使用原来的安装。

亚洲必赢官网 3

<head>

制图矩形

   
为了满足须求无法写运算纯手写,感觉真的很浪费时间,唯有团结踩过的坑,才不想看到人家也被坑。我很懒,也想过弄个工具,方今先放代码吧,方便须求的人copy。

<meta charset=”UTF-8″>

差异于SVG,HTML中的元素canvas只扶助一种原生的图形绘制:矩形。所有其他的图片的绘图都至少须求生成一条路子。可是,大家所有许多门路生成的形式让复杂图形的绘图成为了或者。

    <canvas> H5标签,只是图形容器,您必须使用脚本来绘制图形。

<meta name=”viewport” content=”width=device-width,
initial-scale=1.0″>

率先,我们回来矩形的绘图中。canvas提供了三种艺术绘制矩形:

    lineTo() 方法 添加一个新点,然后创立从该点到画布中最终指定点的线条

<meta http-equiv=”X-UA-Compatible” content=”ie=edge”>

fillRect(x, y, width,
height)

    bezierCurveTo() 方法
 通过行使表示三回贝塞尔曲线的指定控制点,向当前路线添加一个点

<title>canvas翻角效果</title>

制图一个填写的矩形

    提醒:一次贝塞尔曲线需求多少个点。前四个点是用以一回贝塞尔计算中的控制点,第七个点是曲线的完工 
 点。曲线的开头点是眼前路线中最终一个点。即便路径不设有,那么请使用 beginPath() 和 moveTo() 方
    法来定义初始点。

<style>

strokeRect(x, y, width,
height)

 

.container{background: #abcdef;display:
inline-block;font-size:0;position:relative;}

绘图一个矩形的边框

证实:网上有高档算法的绘图,很利索也很有益于,纵然不是特使意况,千万别用自己的章程,请上网右转看外人的案例,哈哈。

.container:before{content:””;position:absolute;left:50px;top:0;width:1px;height:102px;background:#fff;}

clearRect(x, y, width,
height)

 

.container:after{content:””;position:absolute;left:0px;top:50px;width:102px;height:1px;background:#fff;}

解除指定矩形区域,让清除部分完全透明。

☆ canvas画布节点(仅供参考)

*{margin:0;padding:0;}

地方提供的主意之中每一个都包蕴了一致的参数。x与y指定了在canvas画布上所绘制的矩形的左上角(相对于原点)的坐标。width和height设置矩形的尺寸。

<canvas id=”myCanvas” width=”264″ height=”264″ style=”border:red 1px
solid;position:absolute;top:0;left:0″></canvas>

.myCanvas{width:100px;height:100px;border:0px solid #000;display:
inline-block;}

下边的draw() 函数是前一页中取得的,现在就来行使方面的多个函数。

 

</style>

矩形(Rectangular)例子

  1. 雨伞

</head>

functiondraw(){varcanvas=document.getElementById(‘canvas’);if(canvas.getContext){varctx=canvas.getContext(‘2d’);ctx.fillRect(25,25,100,100);ctx.clearRect(45,45,60,60);ctx.strokeRect(50,50,50,50);}}

<script type=”text/javascript”>
    
        function draw(id) {
                var canvas=document.getElementById(id);
                if(canvas==null)
                return false;
                var ctx=canvas.getContext(‘2d’);
                ctx.beginPath();
                
                // 小雨点
                ctx.moveTo(47,32);
                ctx.bezierCurveTo(40,42,38,56,46,60);
                ctx.bezierCurveTo(64,52,50,40,47,32);
                
                // 大雨点
                ctx.moveTo(78,32);
                ctx.bezierCurveTo(70,44,62,66,78,70);
                ctx.bezierCurveTo(104,60,80,40,78,32);
                
                // 伞身
                ctx.moveTo(44,118);
                ctx.bezierCurveTo(48,114,50,90,72,76);
                ctx.bezierCurveTo(82,82,104,70,102,54);
                ctx.bezierCurveTo(138,26,222,76,224,118);
                ctx.lineTo(146,118);
                ctx.lineTo(146,200);
                
                ctx.bezierCurveTo(147,212,162,216,162,192);
                ctx.bezierCurveTo(168,188,172,186,178,192);
                ctx.bezierCurveTo(180,200,182,218,162,231);
                ctx.bezierCurveTo(154,240,116,226,122,200);
                
                ctx.lineTo(122,118);
                ctx.lineTo(44,118);
                var gradient=ctx.createRadialGradient(0,0,0,0,0,150);
                gradient.addColorStop(0,”rgba(244,28,285,0.1)”);
                gradient.addColorStop(1,”rgba(255,255,255,1)”);
                
                ctx.strokeStyle = “red”;
//设置或回到用于笔触的颜色、渐变
                ctx.stroke();
                
                ctx.fillStyle=gradient;
                ctx.fill();
        }
    </script>

<body>

该例子的输出如下图所示。

 

<div class=”container”>

ScreenshotLive sample

  1. 飞机

<canvas class=”myCanvas” width=”100″ height=”100″></canvas>

在 CODEPEN 中打开在 JSFIDDLE 中打开

<script type=”text/javascript”>
    
        function draw(id) {
                var canvas=document.getElementById(id);
                if(canvas==null)
                return false;
                var ctx=canvas.getContext(‘2d’);
                ctx.beginPath();
                ctx.moveTo(65,50);
                ctx.lineTo(156,70);
                ctx.lineTo(190,38);
                ctx.bezierCurveTo(222,10,250,40,230,70);
                ctx.lineTo(195,106);
                ctx.lineTo(218,204);
                ctx.lineTo(186,228);
                ctx.lineTo(150,146);
                ctx.lineTo(110,186);
                ctx.bezierCurveTo(118,200,126,220,98,234);
                ctx.lineTo(30,162);
                ctx.bezierCurveTo(30,134,70,140,78,152);
                ctx.lineTo(118,114);
                ctx.lineTo(40,78);
                ctx.lineTo(65,50);
                /*ctx.bezierCurveTo(75,37,70,25,50,25);
                ctx.bezierCurveTo(20,25,22,62.5,22,55);
                ctx.bezierCurveTo(20,80,40,102,75,120);
                ctx.bezierCurveTo(110,102,130,80,128,55);
                ctx.bezierCurveTo(128,55,130,25,100,25);
                ctx.bezierCurveTo(85,25,75,37,75,40);*/
                
                var gradient=ctx.createRadialGradient(0,0,0,0,0,150);
                gradient.addColorStop(0,”rgba(244,28,285,0.1)”);
                gradient.addColorStop(1,”rgba(255,255,255,1)”);
                
                ctx.strokeStyle = “red”;
//设置或回到用于笔触的颜料、渐变
                ctx.stroke();
                
                ctx.fillStyle=gradient;
                ctx.fill();
        }
    </script>

canvas翻角效果,canvas纯绘制雨伞。</div>

fillRect()函数绘制了一个边长为100px的灰色正方形。clearRect()函数从正方形的为主开始擦除了一个60*60px的正方形,接着strokeRect()在破除区域内生成一个50*50的正方形边框。

 

<!– <script>

接下去大家可以看出clearRect()的七个可选方法,然后大家会领会如何改变渲染图形的填写颜色及描边颜色。

  1. 五角星

var canvas = document.querySelector(‘.myCanvas’); //获取canvas对应dom

分裂于下一节所要介绍的门径函数(path
function),以上的多少个函数绘制之后会立时表现在canvas上,即时生效。

<script>
        //function init() {
        
            var canvas = document.getElementById(‘stars’);
            var ctx = canvas.getContext(‘2d’);
            ctx.fillStyle = “#827839”;
            //ctx.shadowColor = “#000000”;
            ctx.shadowOffsetX = 1;
            ctx.shadowOffsetY = 12;
            ctx.shadowBlur = 18;
            
            
            // 初阶一条新路线
            ctx.beginPath();
            /*ctx.moveTo(15,150)   +30   -8
            ctx.lineTo(100,140);        // 2
            ctx.lineTo(170,80);            // 3
            ctx.lineTo(230,140);        // 4
            ctx.lineTo(315,150);        // 5
            ctx.lineTo(230,200);        // 6
            ctx.lineTo(300,263);        // 7
            ctx.lineTo(170,220);        // 8
            ctx.lineTo(30,263);            // 9
            ctx.lineTo(100,200);        // 10
            
            //ctx.lineTo(15,150);    // 结束
            ctx.closePath();
            ctx.fill();*/
           
            ctx.moveTo(45,142);        // 起点
            ctx.lineTo(129,126);        // 2
            ctx.lineTo(172,40);            // 3
            ctx.lineTo(215,126);        // 4
            ctx.lineTo(299,142);        // 5
            ctx.lineTo(240,203);        // 6
            ctx.lineTo(252,288);        // 7
            ctx.lineTo(172,252);        // 8
            ctx.lineTo(92,288);            // 9
            ctx.lineTo(105,203);        // 10
            
            //ctx.lineTo(15,150);    // 结束
            ctx.closePath();
            ctx.fill();
        //}
        
        //window.addEventListener(“load”,init.false);
    </script>

var ctx = canvas.getContext(‘2d’); //此方法比较基础 ,
意为博得canvas绘画2d内容的工具(上下文)

绘制路径

 

var cw = 100; //分辨率 , 其实直接从dom上收获可能更好些

图形的宗旨因素是途径。路径是通过差异颜色和宽度的线条或曲线相连形成的例外造型的点的集结。一个途径,甚至一个子路径,都是密闭的。使用路径绘制图形须要部分额外的步骤。

  1. 桃心

var ch = 100; //分辨率 , 其实直接从dom上收获可能更好些

率先,你必要创制路径初阶点。

<script type=”text/javascript”>
        function draw(id) {
                var canvas=document.getElementById(id);
                if(canvas==null)
                return false;
                var ctx=canvas.getContext(‘2d’);
                ctx.beginPath();
                ctx.moveTo(75,40);
                ctx.bezierCurveTo(75,37,70,25,50,25);
                ctx.bezierCurveTo(20,25,22,62.5,22,55);
                ctx.bezierCurveTo(20,80,40,102,75,120);
                ctx.bezierCurveTo(110,102,130,80,128,55);
                ctx.bezierCurveTo(128,55,130,25,100,25);
                ctx.bezierCurveTo(85,25,75,37,75,40);
                var gradient=ctx.createRadialGradient(0,0,0,0,0,150);
                gradient.addColorStop(0,”rgba(244,28,285,0.5)”);
                gradient.addColorStop(1,”rgba(255,255,255,1)”);
                ctx.fillStyle=gradient;
                ctx.fill();
        }

 

下一场您利用画图命令去画出路径。

    </script>

 

自此你把路子封闭。

村办公众号(ZEROFC_DEV),关于web开发的,欢迎关怀O(∩_∩)O~

// ctx.save() //保存上下文状态 (比如画笔尺寸 颜色 旋转角度)

设若路径生成,你就能透过描边或填充路径区域来渲染图形。

亚洲必赢官网 4

//    ctx.restore() //重临上次保存的上下文状态

以下是所要用到的函数:

//    ctx.moveTo(x,y) //上下文移动到具体地方

beginPath()

//    ctx.lineTo(x,y) //上下文以划线的款型活动到某地点

新建一条路子,生成之后,图形绘制命令被针对到路径上生成路径。

//    ctx.stroke() // 画线动作

closePath()

//    ctx.quadraticCurveTo()
//上下文(画笔)按贝塞尔曲线移动(简单了然为可控的曲线即可)

关闭路径之后图片绘制命令又重新指向到上下文中。

//    ctx.arc() //画圆

stroke()

//    ctx.beginPath() //开启新的画笔路径

经过线条来绘制图形概况。

//    ctx.closePath() //关闭当前画笔路径

fill()

//     ctx.createLinearGradient() //成立canvas渐变对象

由此填写路径的内容区域变化实心的图形。

//     ctx.fill() //对闭合区域展开填空

扭转路径的第一步叫做beginPath()。本质上,路径是由很多子路径构成,那些子路径都是在一个列表中,所有的子路径(线、弧形、等等)构成图形。而每趟这几个点子调用之后,列表清空重置,然后我们就可以再度绘制新的图形。

//     ctx.globalCompositeOperation //画笔的重合情势

小心:当前路线为空,即调用beginPath()之后,或者canvas刚建的时候,第一条途径构造命令平常被视为是moveTo(),无论最终的是什么。出于这些原因,你几乎总是要在安装路径之后专门指定你的苗头地方。

// 阴影部分

第二步就是调用函数指定绘制路径,本文稍后我们就能来看了。

ctx.moveTo(50,0);

其三,就是密闭路径closePath(),不是少不了的。那么些方法会通过绘制一条从当下点到起来点的直线来关闭图形。如果图形是一度关闭了的,即眼前点为开头点,该函数什么也不做。

ctx.quadraticCurveTo(55,5,55,25);//可以知道为从(50,0)那一个点划线到(55,25)那么些点,中间会遭逢(55,5)这些店将直线像磁贴一样“吸”成曲线

注意:当你调用fill()函数时,所有没有密闭的形态都会自动关闭,所以你不必要调用closePath()函数。可是调用stroke()时不会自行关闭。

ctx.lineTo(55,40);

绘图一个三角形

ctx.arc(60,40,5,Math.PI,Math.PI/2,true);

譬如说,绘制三角形的代码如下:

ctx.lineTo(75,45);

functiondraw(){varcanvas=document.getElementById(‘canvas’);if(canvas.getContext){varctx=canvas.getContext(‘2d’);ctx.beginPath();ctx.moveTo(75,50);ctx.lineTo(100,75);ctx.lineTo(100,25);ctx.fill();}}

ctx.quadraticCurveTo(95,45,100,50);

出口看上去如下:

ctx.lineTo(50,0);

ScreenshotLive sample

var gradient = ctx.createLinearGradient(50,50,75,75);

在 CODEPEN 中打开在 JSFIDDLE 中打开

gradient.addColorStop(0,’#ccc’);

挪动笔触

gradient.addColorStop(0.7,’#111′);

一个极度有效的函数,而以此函数实际上并无法画出别样事物,也是上面所讲述的路径列表的一局地,那个函数就是moveTo()。或者你能够设想一下在纸上作业,一支钢笔或者铅笔的笔尖从一个点到另一个点的运动进度。

gradient.addColorStop(1,’#000′);

moveTo(x,y)

ctx.fillStyle = gradient;

将笔触移动到指定的坐标x以及y上。

ctx.fill();

当canvas初阶化或者beginPath()调用后,你层见迭出会采纳moveTo()函数设置起源。大家也可以利用moveTo()绘制一些不总是的路线。看一下上面的笑颜例子。我将运用moveTo()方法(红线处)的地点标记了。

// 橘黄部分

您可以品尝一下,使用下面的代码片。只须要将其复制到之前的draw()函数即可。

ctx.beginPath();//新建路径

functiondraw(){varcanvas=document.getElementById(‘canvas’);if(canvas.getContext){varctx=canvas.getContext(‘2d’);ctx.beginPath();ctx.arc(75,75,50,0,Math.PI*2,true);//
绘制ctx.moveTo(110,75);ctx.arc(75,75,35,0,Math.PI,false);//
口(顺时针)ctx.moveTo(65,65);ctx.arc(60,65,5,0,Math.PI*2,true);//
左眼ctx.moveTo(95,65);ctx.arc(90,65,5,0,Math.PI*2,true);//
右眼ctx.stroke();}}

ctx.moveTo(50,0);

结果看起来是这么的:

ctx.lineTo(100,50);

ScreenshotLive sample

ctx.lineTo(100,0);

在 CODEPEN 中打开在 JSFIDDLE 中打开

ctx.lineTo(50,0);

假使您想见见两次三番的线,你可以移除调用的moveTo()。

ctx.closePath();//闭合路径

注意:须要上学更加多关于arc()函数的始末,请看上边的Arcs

ctx.fillStyle = ‘#ff6600’;

线

ctx.fill();

绘图直线,须要选择的格局lineTo()。

// 文字绘制

lineTo(x,
y)

var deg = Math.PI/180;

绘制一条从近来地点到指定x以及y地方的直线。

ctx.globalCompositeOperation = ‘source-atop’;//canvas层叠方式

该措施有多少个参数:x以及y
,代表坐标系中直线截至的点。初叶点和事先的绘图路径有关,以前路径的甘休点就是接下去的起头点,等等。。。初阶点也得以透过moveTo()函数改变。

ctx.beginPath();

上面的例子绘制七个三角,一个是填写的,另一个是描边的。

ctx.font = ’14px Arial’;//设置字体大小 字体

functiondraw(){varcanvas=document.getElementById(‘canvas’);if(canvas.getContext){varctx=canvas.getContext(‘2d’);//
填充三角形ctx.beginPath();ctx.moveTo(25,25);ctx.lineTo(105,25);ctx.lineTo(25,105);ctx.fill();//
描边三角形ctx.beginPath();ctx.moveTo(125,125);ctx.lineTo(125,45);ctx.lineTo(45,125);ctx.closePath();ctx.stroke();}}

ctx.textAlign = ‘center’;//字体对齐格局

那边从调用beginPath()函数准备绘制一个新的样子路径始于。然后使用moveTo()函数移动到对象地方上。然后上面,两条线条绘制后组成三角形的两条边。

ctx.translate(78,22);//移动canvas画布圆点

ScreenshotLive sample

ctx.rotate(45*deg);//旋转画布

在 CODEPEN 中打开在 JSFIDDLE 中打开

ctx.fillStyle = ‘#fff’;//设置字体颜色

您会小心到填充与描边三角形步骤有所差异。正如上面所波及的,因为路径使用填充(filled)时,路径自动关闭,使用描边(stroked)则不会关闭路径。如若没有添加闭合路径closePath()到描述三角形函数中,则只绘制了两条线条,并不是一个总体的三角。

ctx.fillText(‘NEW’,0,0);//文字绘制动作

圆弧

ctx.closePath();

绘图圆弧或者圆,大家应用arc()方法。当然可以动用arcTo(),但是那几个的得以完结并不是那么的可相信,所以我们那里不作介绍。

function draw(){

arc(x, y, radius, startAngle, endAngle,
anticlockwise)

drawMethod();//绘制三角等情节

画一个以(x,y)为圆心的以radius为半径的拱形(圆),从startAngle开头到endAngle为止,根据anticlockwise给定的样子(默许为顺时针)来变化。

window.requestAnimationFrame(function(){

arcTo(x1, y1, x2, y2,
radius)

draw();

基于给定的控制点和半径画一段圆弧,再以直线连接五个控制点。

})

此地详细介绍一下arc方法,该办法有多少个参数:x,y为绘制圆弧所在圆上的圆心坐标。radius为半径。startAngle以及endAngle参数用弧度定义了发轫以及截至的弧度。那么些都是以x轴为条件。参数anticlockwise为一个布尔值。为true时,是逆时针方向,否则顺时针方向。

function drawMethod(){

留意:arc()函数中的角度单位是弧度,不是度数。角度与弧度的js表明式:radians=(Math.PI/180)*degrees。

}

上面的事例比地方的要复杂一下,上面绘制了12个不等的角度以及填充的圆弧。

}

上面八个for循环,生成圆弧的队列(x,y)坐标。每一段圆弧的起始都调用beginPath()。代码中,每个圆弧的参数都是可变的,实际生活中,我们并不须求那样做。

</script> –>

x,y坐标是可变的。半径(radius)和开首角度(startAngle)都是向来的。截止角度(endAngle)在率先列始发时是180度(半圆)然后每列伸张90度。最终一列形成一个全体的圆。

<script>

clockwise语句功用于第一、三行是顺时针的半圆形,anticlockwise成效于二、四行为逆时针圆弧。if语句让一、二行描边圆弧,下边两行填充路径。

var canvas = document.querySelector(‘.myCanvas’);

注意:那些示例所需的画布大小略大于本页面的别的例子: 150 x 200 像素。

        var ctx = canvas.getContext(‘2d’);

functiondraw(){varcanvas=document.getElementById(‘canvas’);if(canvas.getContext){varctx=canvas.getContext(‘2d’);for(vari=0;i<4;i++){for(varj=0;j<3;j++){ctx.beginPath();varx=25+j*50;//
x 坐标值vary=25+i*50;// y 坐标值varradius=20;//
圆弧半径varstartAngle=0;// 开端点varendAngle=Math.PI+(Math.PI*j)/2;//
截至点varanticlockwise=i%2==0?false:true;//
顺时针或逆时针ctx.arc(x,y,radius,startAngle,endAngle,anticlockwise);if(i>1){ctx.fill();}else{ctx.stroke();}}}}}

        var cw = 100;

ScreenshotLive sample

        var ch = 100;

在 CODEPEN 中打开在 JSFIDDLE 中打开

        var percent = 0;

贝塞尔(bezier)以及二次贝塞尔

        var points = {

下一个不行立见成效的途径类型就是贝塞尔曲线。四遍以及二次贝塞尔曲线都相当有用,一般用来绘制复杂有规律的图样。

            x1 : 100,

quadraticCurveTo(cp1x, cp1y, x, y)

            y1 : 0,

绘制贝塞尔曲线,cp1x,cp1y为控制点,x,y为停止点。

            x2 : 100,

bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)

            y2 : 0

绘制二次贝塞尔曲线,cp1x,cp1y为控制点一,cp2x,cp2y为控制点二,x,y为停止点。

        }

左边的图可以很好的描述两者的涉嫌,贝塞尔曲线有一个开头、为止点(青色)以及一个控制点(黄色),而二次贝塞尔曲线使用多少个控制点。

        var speed = 1;

参数x、y在那四个法子中都是得了点坐标。cp1x,cp1y为坐标中的第三个控制点,cp2x,cp2y为坐标中的第一个控制点。

        var aSpeed = 0.1;

运用一次以及二次贝塞尔曲线是有自然的难度的,因为不一样于像Adobe
Illustrators那样的矢量软件,我们所绘制的曲线没有直接的视觉反馈给大家。那让绘制复杂的图纸非凡的难堪。在上边的事例中,大家会绘制一些简约有规律的图样,假诺你有时间,以及越来越多的耐性很多参差不齐的图纸你都得以绘制出来。

        ctx.moveTo(0,0);

上边的那几个事例没有稍微是劳苦的。那四个例证中大家会接连绘制贝塞尔曲线,最终会形成复杂的图片。

        ctx.strokeStyle = ‘black’;

贝塞尔曲线

        ctx.strokeWidth= 1;

其一事例使用多少个贝塞尔曲线来渲染对话气泡。

        ctx.save();

functiondraw(){varcanvas=document.getElementById(‘canvas’);if(canvas.getContext){varctx=canvas.getContext(‘2d’);//
贝尔赛曲线ctx.beginPath();ctx.moveTo(75,25);ctx.quadraticCurveTo(25,25,25,62.5);ctx.quadraticCurveTo(25,100,50,100);ctx.quadraticCurveTo(50,120,30,125);ctx.quadraticCurveTo(60,120,65,100);ctx.quadraticCurveTo(125,100,125,62.5);ctx.quadraticCurveTo(125,25,75,25);ctx.stroke();}}

        var deg = Math.PI / 180;

ScreenshotLive sample

        

在 CODEPEN 中打开在 JSFIDDLE 中打开

        function start(type){

二次贝塞尔曲线

            if(type === ‘show’){

其一例子使用贝塞尔曲线绘制心形。

                points = {

functiondraw(){varcanvas=document.getElementById(‘canvas’);if(canvas.getContext){varctx=canvas.getContext(‘2d’);//二次曲线ctx.beginPath();ctx.moveTo(75,40);ctx.bezierCurveTo(75,37,70,25,50,25);ctx.bezierCurveTo(20,25,20,62.5,20,62.5);ctx.bezierCurveTo(20,80,40,102,75,120);ctx.bezierCurveTo(110,102,130,80,130,62.5);ctx.bezierCurveTo(130,62.5,130,25,100,25);ctx.bezierCurveTo(85,25,75,37,75,40);ctx.fill();}}

                    x1 : 100,

ScreenshotLive sample

                    y1 : 0,

矩形

                    x2 : 100,

直白在画布上绘制矩形的八个附加措施,正如大家先河所见的Drawing
rectangles,同样,也有rect()方法,将一个矩形路径扩充到近年来路线上。

                    y2 : 0

rect(x,y,width,height)

                }

制图一个左上角坐标为(x,y),宽高为width以及height的矩形。

                aSpeed = .1;

当该措施执行的时候,moveTo()方法自动安装坐标参数(0,0)。也就是说,当前笔触自动重置会默许坐标。

                speed = 1;

构成使用

            }else{

近期截至,每一个例证中的每个图形都只用到一种档次的路线。可是,绘制一个图片并不曾范围使用数据以及项目。所以在终极的一个例证里,让大家结合使用所有的路径函数来再次出现一组知名的娱乐人物。

                points = {

functiondraw(){varcanvas=document.getElementById(‘canvas’);if(canvas.getContext){varctx=canvas.getContext(‘2d’);roundedRect(ctx,12,12,150,150,15);roundedRect(ctx,19,19,150,150,9);roundedRect(ctx,53,53,49,33,10);roundedRect(ctx,53,119,49,16,6);roundedRect(ctx,135,53,49,33,10);roundedRect(ctx,135,119,25,49,10);ctx.beginPath();ctx.arc(37,37,13,Math.PI/7,-Math.PI/7,false);ctx.lineTo(31,37);ctx.fill();for(vari=0;i<8;i++){ctx.fillRect(51+i*16,35,4,4);}for(i=0;i<6;i++){ctx.fillRect(115,51+i*16,4,4);}for(i=0;i<8;i++){ctx.fillRect(51+i*16,99,4,4);}ctx.beginPath();ctx.moveTo(83,116);ctx.lineTo(83,102);ctx.bezierCurveTo(83,94,89,88,97,88);ctx.bezierCurveTo(105,88,111,94,111,102);ctx.lineTo(111,116);ctx.lineTo(106.333,111.333);ctx.lineTo(101.666,116);ctx.lineTo(97,111.333);ctx.lineTo(92.333,116);ctx.lineTo(87.666,111.333);ctx.lineTo(83,116);ctx.fill();ctx.fillStyle=”white”;ctx.beginPath();ctx.moveTo(91,96);ctx.bezierCurveTo(88,96,87,99,87,101);ctx.bezierCurveTo(87,103,88,106,91,106);ctx.bezierCurveTo(94,106,95,103,95,101);ctx.bezierCurveTo(95,99,94,96,91,96);ctx.moveTo(103,96);ctx.bezierCurveTo(100,96,99,99,99,101);ctx.bezierCurveTo(99,103,100,106,103,106);ctx.bezierCurveTo(106,106,107,103,107,101);ctx.bezierCurveTo(107,99,106,96,103,96);ctx.fill();ctx.fillStyle=”black”;ctx.beginPath();ctx.arc(101,102,2,0,Math.PI*2,true);ctx.fill();ctx.beginPath();ctx.arc(89,102,2,0,Math.PI*2,true);ctx.fill();}}//
封装的一个用以绘制圆角矩形的函数.functionroundedRect(ctx,x,y,width,height,radius){ctx.beginPath();ctx.moveTo(x,y+radius);ctx.lineTo(x,y+height-radius);ctx.quadraticCurveTo(x,y+height,x+radius,y+height);ctx.lineTo(x+width-radius,y+height);ctx.quadraticCurveTo(x+width,y+height,x+width,y+height-radius);ctx.lineTo(x+width,y+radius);ctx.quadraticCurveTo(x+width,y,x+width-radius,y);ctx.lineTo(x+radius,y);ctx.quadraticCurveTo(x,y,x,y+radius);ctx.stroke();}

                    x1 : 50,

结果画面如下:

                    y1 : 0,

ScreenshotLive sample

                    x2 : 100,

在 CODEPEN 中打开在 JSFIDDLE 中打开

                    y2 : 50

咱们不会很详细地讲学上边的代码,因为实在那很不难驾驭。紧要的一些是绘制上下文中使用到了fillStyle属性,以及封装函数(例子中的roundedRect())。使用封装函数对于收缩代码量以及复杂度非凡实惠。

                }

在稍后的科目里,我们会回头再看看fillStyle样式的更加多细节。那章节中,大家所做的有关fillStyle样式仅是改变填充颜色,由默许的肉色到白色,然后又是藏青色。

                aSpeed = -.1;

Path2D 对象

                speed = -1;

正如我辈在眼前例子中见到的,你可以动用一密密麻麻的路子和画画命令来把目的“画”在画布上。为了简化代码和升高品质,Path2D目标已足以在较新本子的浏览器中运用,用来缓存或记录绘画命令,这样你将能很快地回想路径。

            }

怎么着爆发一个Path2D对象啊?

            draw(points , type);

Path2D()

        }

Path2D()会重临一个新开首化的Path2D对象(可能将某一个路子作为变量——创造一个它的副本,或者将一个饱含SVG
path数据的字符串作为变量)。

        

newPath2D();// 空的Path对象newPath2D(path);//
克隆Path对象newPath2D(d);// 从SVG建立Path对象

        function draw(points , type){

怀有的门径方法比如moveTo,rect,arc或quadraticCurveTo等,如我辈前边见过的,都可以在Path2D中运用。

            var disX = Math.floor(points.x2 – points.x1);

Path2D API
添加了addPath作为将path结合起来的格局。当您想要从多少个元素中来创制对象时,那将会很实用。比如:

            var disY = Math.floor(points.y2 – points.y1);

Path2D.addPath(path [,
transform])​

            if(disY < 0 && type == ‘hide’){

添加了一条途径到眼前路线(可能添加了一个变换矩阵)。

//              console.log(‘改展开动画了’);

Path2D 示例

                ctx.clearRect(0,0,cw,ch);

在那几个事例中,大家创造了一个矩形和一个圆。它们都被存为Path2D对象,后边再派上用场。随着新的Path2D
API暴发,二种格局也对应地被更新来使用Path2D对象而不是现阶段路线。在此间,带路径参数的stroke和fill可以把对象画在画布上。

                setTimeout(function(){

functiondraw(){varcanvas=document.getElementById(‘canvas’);if(canvas.getContext){varctx=canvas.getContext(‘2d’);varrectangle=newPath2D();rectangle.rect(10,10,50,50);varcircle=newPath2D();circle.moveTo(125,35);circle.arc(100,35,25,0,2*Math.PI);ctx.stroke(rectangle);ctx.fill(circle);}}

                    start(‘show’);

ScreenshotLive sample

                } , 2000)

                return ;

            }else if(disY > 50 && type == ‘show’){

//              console.log(‘改收起动画了’);

                setTimeout(function(){

                    start(‘hide’);

                } , 2000)

                return ;

            }

            ctx.clearRect(0,0,cw,ch);

            drawPageCorShow(points , disX , disY);

            drawPageCor(points, disX , disY);

            window.requestAnimationFrame(function(){

                draw(points , type);

            })

        }

        

        function drawPageCorShow(points, disX , disY){

            ctx.save();

            ctx.beginPath();

            //闭合三角形

            ctx.moveTo(points.x1 , points.y1);

            ctx.lineTo(points.x2 , points.y2);

            ctx.lineTo(points.x2 , points.y1);

            ctx.lineTo(points.x1 , points.y1);

            ctx.closePath();

            ctx.strokeStyle = “#080”;

            ctx.stroke();

            

            ctx.fillStyle = ‘#ff6600’;

            ctx.fill();

            //重叠方式

            ctx.globalCompositeOperation = ‘source-atop’;

            

            ctx.beginPath();

            ctx.font = ’14px Arial’;

            ctx.textAlign = ‘center’;

            ctx.translate(78 , 22);

            ctx.rotate(45 * deg);

            ctx.fillStyle = ‘#fff’;

            ctx.fillText(‘NEW’ , 0 , 0);

            ctx.closePath();

            ctx.restore();

            

        }

        

        function drawPageCor(points, disX , disY){

            ctx.save();

            ctx.beginPath();

            //移動到地点 左上

            ctx.moveTo(points.x1,points.y1);

            //画第三个曲线

            ctx.quadraticCurveTo(points.x1 + (disX/10),points.y1 +
disY/10 ,(points.x1 + disX/10),points.y1 + disY/2);

            //直线向下

            ctx.lineTo(points.x1 + disX / 10 , points.y2 – (disY/5));

            //半圆向右

            ctx.arc(points.x1+disX/5,points.y2 –
(disY/5),disY/10,deg*180 , deg*90,true);

            // 直线向右

            ctx.lineTo(points.x2 – disX/2 , points.y2 – (disY / 10))

            //曲线向右

            ctx.quadraticCurveTo(points.x2 -disX/10,points.y2 –
(disY/10) ,points.x2,points.y2 );

            //闭合图形

            ctx.lineTo(points.x1,points.y1);

            

            ctx.closePath();

            

            var gradient = ctx.createLinearGradient(points.x1 ,
points.y2 , points.x1 + (disX/2) , points.y1 + disY/2);

            gradient.addColorStop(0 , ‘#ccc’);

            gradient.addColorStop(0.7 , ‘#111’);

            gradient.addColorStop(1 , ‘#000’);

            

            ctx.fillStyle = gradient;

            ctx.fill();

            ctx.restore();

            //更新速度地点

            points.x1 -= speed;

            points.y2 += speed;

            speed += aSpeed;

        }

        start(‘show’);

</script>

</body>

</html>

 

右上角须要从无的状态撕开一个符号,且有动画进度,上图是兑现的效用图,不是gif。

对这几个翻角效果的难题在于没有翻动的时候披露的是dom上边的情节,达成角度来说纯dom

  • css动画的设计方案并不曾相出一个好的机关:
    于是捡起了久久事先学的入门级其余canvas:

上面说一下贯彻思路。

动画片拆分

  • 将此动画分解成两局地,一部分是翻页出现的藏蓝色三角区域,另一个是发自的橘色浮现内容

  • 对于橘色的来得内容区域相对好一些,因为是一个规则图形,而黄色区域相对较难

先从基础canvas使用方法说起

  1. <div class="container">

  2. <canvas class="myCanvas" width="100" height="100"></canvas>

  3. </div>

 

布局如上,那里要说一点踩过的坑是,canvas必需要设置上width 与
height,此处并非为css中的width与height,而是写在dom上的属性。
因为dom上的width与height标识了canvas的分辨率(个人精晓)
所以此canvas画布分辨率为100*亚洲必赢官网 ,100,而显得尺寸是足以经过css控制。

js中率先要做的是得到canvas对象

  1. var canvas = document.querySelector('.myCanvas'); //获取canvas对应dom

  2. var ctx = canvas.getContext('2d'); //此方法较为基础 , 意为获取canvas绘画2d内容的工具(上下文)

  3. var cw = 100; //分辨率 , 其实直接从dom上获取可能更好些

  4. var ch = 100; //分辨率 , 其实直接从dom上获取可能更好些

ctx那些绘画上下文在那些科目中起到的职能主要,它提供了老大强劲的api,比如用来画线、填充、写文字等,那样看来掌握为画笔会尤其显明一些。

此处效果要求使用的api如下(不做详细分解,可w3c自行查询):

  1. ctx.save() //保存上下文状态 (比如画笔尺寸 颜色 旋转角度)

  2. ctx.restore() //返回上次保存的上下文状态

  3. ctx.moveTo(x,y) //上下文移动到具体位置

  4. ctx.lineTo(x,y) //上下文以划线的形式移动到某位置

  5. ctx.stroke() // 画线动作

  6. ctx.quadraticCurveTo() //上下文(画笔)按贝塞尔曲线移动(简单理解为可控的曲线即可)

  7. ctx.arc() //画圆

  8. ctx.beginPath() //开启新的画笔路径

  9. ctx.closePath() //关闭当前画笔路径

  10. ctx.createLinearGradient() //创建canvas渐变对象

  11. ctx.fill() //对闭合区域进行填充

  12. ctx.globalCompositeOperation //画笔的重叠模式

莫不方法列举的不够详尽,见谅。

首先是绘制红色翻出的有些,图形分解为如下几有的(请依照上图脑补):

  1. 左上角向右下的半弧 ╮

  2. 下一场是竖直向下的竖线 |

  3. 然后是向右的半圆 ╰

  4. 再接下来是向右的横线

  5. 随后依旧向右下的半弧 ╮

  6. 最终是将线连接会起源

于是乎第一步 大家要先将画笔移动到起始地点:

  1. ctx.moveTo(50,0);

然后

  1. ctx.quadraticCurveTo(55 , 5 , 55 , 25); // 可以理解为从(50,0)这个点划线到(55,25)这个点,中间会受到(55,5)这个点将直线想磁铁一样"吸"成曲线

于是乎第二个向右下的半弧已毕,此时canvas上尚未其余绘制内容,因为还并未履行过绘制方法例如stroke或fill。

接下去直线向下就是简约的移动:

  1. ctx.lineTo(55 , 40);

其一时候大家接下去应该画向右的圆弧,那个时候再用贝塞尔曲线绘制实在有点不太对劲,因为从图上来看,那里完全是1/4的圆,所以要选拔canvas提供的画圆的api。

  1. ctx.arc(60 , 40 , 5 , Math.PI , Math.PI / 2 , true);

上述画圆的代码意为:以(60,40)点为圆心,5为半径,逆时针从180度绘制到90度,180度就是圆心的档次向左
到达点(55,40),与上一步连接上,然后又因为显示器向下为正,90度在圆心正下方,所以绘制出此半圆。

于是乎按照同样的步子,水平向右:

  1. ctx.lineTo(75 , 45);

接下来再一次行使贝塞尔曲线用第一步的笔触画出向右下的弧:

  1. ctx.quadraticCurveTo( 95 , 45 , 100 , 50 );

同理,上述贝塞尔曲线可以清楚为一条从( 75 , 45 ) 到 ( 100 , 50 )的线被 (
95 , 45 )”吸”成曲线。

最终链接源点,闭合绘画区域:

  1. ctx.lineTo(50 , 0);

其一时候青色区域的翻页就画完了,然后此时启幕填写颜色:

  1. var gradient = ctx.createLinearGradient(50 , 50 , 75 , 75);

  2. gradient.addColorStop(0 , '#ccc');

  3. gradient.addColorStop(0.7 , '#111');

  4. gradient.addColorStop(1 , '#000');

我们经过上述代码创设一个从( 50 , 50 )点到(75 , 75)点的线性渐变,颜色从
#ccc 到 #111 到 #000,创立高光效果。

接下来填充:

  1. ctx.fillStyle = gradient;

  2. ctx.fill();

于是翻页效果的一半固然完事了。

至今,我要说一点自己精晓的canvas的作画”套路”。

对此上述教程中,有一步我们使用了一个词叫做闭合,闭合的概念在canvas中是当成存在的,对于fill方法来说,填充的间隔是有一个空间尺寸才足以的,比如我们描绘的这些粉红色的三角形,参与大家最后没有将终点与源点相连接,同样canvas会自行帮我们链接最终一笔绘画的职分到源点,强制行程闭合空间,而这么我们想再多画多少个新的密闭空间就劳动了,所以canvas提供了如下api
新建闭合路径:

  1. ctx.beginPath(); //新建路径

  2. ctx.closePath(); //闭合路径

 

因此对于我们接下去要绘制右上角橘色区域来说,大家在绘制紫色区域此前率先要做的是:

 

  1. ctx.beginPath();

  2. ...

接下来在fill此前我们理应 :

  1. ctx.closePath();

也就是说beginPath到closePath之间标识着大家团结一心的一个整机的绘画阶段。

那么接下去绘制右上角的橘色区域就大约很多了:

  1. ctx.beginPath();

  2. ctx.moveTo(50,0);

  3. ctx.lineTo(100,50);

  4. ctx.lineTo(100,0);

  5. ctx.lineTo(50,0);

  6. ctx.closePath();

  7. ctx.fillStyle = '#ff6600';

  8. ctx.fill();

于是乎右上角的橘色区域大家就绘制已毕了。

文字绘制

接下去绘制”new”,实际上是运用canvas不难的公文绘制,代码如下:

  1. var deg = Math.PI / 180;

  2. ctx.globalCompositeOperation = 'source-atop'; //canvas层叠模式

  3. ctx.beginPath();

  4. ctx.font = '14px Arial'; //设置字体大小 字体

  5. ctx.textAlign = 'center'; // 字体对齐方式

  6. ctx.translate(78 , 22);  // 移动canvas画布圆点

  7. ctx.rotate(45 * deg);    // 旋转画布

  8. ctx.fillStyle = '#fff';  // 设置文字颜色

  9. ctx.fillText('NEW' , 0 , 0); //文字绘制动作

  10. ctx.closePath();

对于上述代码中,文字的相干api是属于尚未难度的,只是设置而已,要求精晓的一部分在于translate和rotate。

那八个章程中,translate的趣味为活动canvas画布的( 0 , 0 )点到
(78,22),然后旋转45度,再将文字渲染在原点,实际就是(78,22)那么些点上,此时大家对canvas的画笔做出了极度大的改动。

譬如说我们修改了旋转角度以及画布圆点,那种操作可能只在我们须要绘制倾斜的new的时候要求,中期可能就不必要运用了。

还好canvas的画笔是存在”状态”的,通过
ctx.save();可以保留当前画笔的情况,通过ctx.restore();可以恢复生机到上次画笔保存的情状。

于是乎自己个人明白到,在开发canvas动画时,一个较好的习惯就是,在beginPath以前先ctx.save();保存画笔状态,在closePath后
ctx.restore();还原以前的画笔状态,那样大家的每一个绘制阶段对于画笔的改动都将是不会有影响的(个人经历)。

  1. ctx.globalCompositeOperation = 'source-atop'; //canvas层叠模式

 

代码中那有些是指
大家绘制的文字new与橘色三角形区域的重合关系,此格局取值较多,此处不做过多介绍,source-atop值可以使重叠区域保留,新绘制的情节在重叠区域以外的一部分没有,以此达到new在里头的功能。

到此地大家就开发好了翻角效果的一心呈现的景况,那么怎样让那么些区域动起来吧?

这边须求选择h5提供的用于刷帧的函数 requestAnimationFrame

此格局可概括明了为16飞秒的定时器,不过厉害的是能够再相继环境中机动匹配到可完结的周旋顺遂的帧率,实际并不是定时器哈。

大家必要在这几个轮回执行的函数中,将上述的绘图内容重复绘制,例如 :

  1. function draw(){

  2. drawMethod(); //绘制三角等内容

  3. window.requestAnimationFrame(function(){

  4. draw();

  5. })

  6. }

  7. function drawMethod(){

  8. //...

  9. }

这么我们就可以落成刷帧的法力了,于是接着大家要做的就是控制绘制时种种数值的参数。

譬如大家是以(50,0)为起源,(100,50)为巅峰那样的多个运动点为绘制标记的,如若大家将七个点展开仓储,并且每一趟执行drawMethod的时候更新点的职位,然后清空canvas,再绘制新的点
那么就足以达标canvas动起来的目的了。

网站地图xml地图