canvas来绘制图形,canvas纯绘制雨伞

简单来讲的 canvas 翻角效果

2017/12/07 · HTML5 ·
Canvas

初稿出处: 敖爽   

canvas来绘制图形,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
, 比如用于画线 , 填充 , 写文字等 , 那样看来了解为画笔会愈来愈鲜爱他美(Aptamil)些;

此地效果须求采纳的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>

</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’);//
Bell赛曲线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地图