本篇接着上一篇:第157天:canvas基础知识详解 继续来写。
五、Konva的使用快速上手
5.1 Konva的整体理念
Stage
|
+------+------+
| |
Layer Layer
| |
+-----+-----+ Shape
| |
Group Group
| |
+ +---+---+
| | |
Shape Group Shape
|
+
|
Shape
5.2 Konva矩形案例
5.2.1 创建一个矩形: Konva.Rect(option);
1 //Konva使用的基本案例 2 //第一步:创建舞台 3 var stage = new Konva.Stage({ 4 container: 'container', //需要存放舞台的Dom容器 5 width: window.innerWidth, //设置全屏 6 height: window.innerHeight 7 }); 8 9 //第二步:创建层 10 var layer = new Konva.Layer(); //创建一个层 11 stage.add(layer); //把层添加到舞台 12 13 //第三步: 创建矩形 14 var rect = new Konva.Rect({ //创建一个矩形 15 x: 100, //矩形的x坐标,相对其父容器的坐标 16 y: 100, 17 width: 100, //矩形的宽度 18 height: 100, //矩形高度 19 fill: 'gold', //矩形填充的颜色 20 stroke: 'navy', //矩形描边的颜色 21 strokeWidth: 4, //填充宽度 22 opactity: .2, //矩形的透明度 23 scale: 1.2, //矩形的缩放 1:原来大小 24 rotation: 30, //旋转的角度,是deg不是弧度。 25 cornerRadius: 10, //圆角的大小(像素) 26 id: 'rect1', //id属性,类似dom的id属性 27 name: 'rect', 28 draggable: true //是否可以进行拖拽 29 }); 30 31 //创建一个组 32 var group = new Konva.Group({ 33 x: 40, 34 y: 40, 35 }); 36 group.add( rect ); //把矩形添加到组中 37 38 //第四步: 把形状放到层中 39 layer.add( group ); //把组添加到层中 40 layer.draw(); //绘制层到舞台上
5.3 Konva的动画系统
5.3.1 tween对象(重点)
- tween,英文意思:两者之间, 英 [twiːn] 美 [twin]
- tween是控制Konva对象进行动画的核心对象。
- tween可以控制所有数字类型的属性进行动画处理,比如:x, y, rotation, width, height, radius, strokeWidth, opacity, scaleX等
1 //案例: 2 var tween = new Konva.Tween({ 3 node: rect, //要进行动画的Konva对象 4 x: 300, //要进行动画的属性 5 opacity: .8, 6 duration: 1, //持续时间 7 easing: Konva.Easings.EaseIn, //动画的动画效果 8 yoyo: true, //是否进行循环播放的设置 9 onFinish: function() { 10 //动画执行结束后,执行此方法 11 } 12 }); 13 14 tween.play(); //启动动画 15 tween的控制方法 16 otween.play(), //播放动画 17 otween.pause(), //暂停动画 18 otween.reverse(), //动画逆播放 19 otween.reset(), //重置动画 20 otween.finish(), //立即结束动画 21 oseek:英文:寻找 英 [siːk] 美 [sik] 22 tween的缓动控制选项 23 oKonva.Easings.Linear //线性 24 oKonva.Easings.EaseIn //缓动,先慢后快 25 oKonva.Easings.EaseOut //先快后慢 26 oKonva.Easings.EaseInOut //两头慢,中间快 27 oKonva.Easings.BackEaseIn //往回来一点,然后往前冲,汽车启动类似... 28 oKonva.Easings.BackEaseOut 29 oKonva.Easings.BackEaseInOut 30 oKonva.Easings.ElasticEaseIn //橡皮筋 英 [ɪ'læstɪk] 美 [ɪ'læstɪk] 31 oKonva.Easings.ElasticEaseOut 32 oKonva.Easings.ElasticEaseInOut 33 oKonva.Easings.BounceEaseIn //弹跳;弹起,反跳;弹回 英 [baʊns] 美 [baʊns] 34 oKonva.Easings.BounceEaseOut 35 oKonva.Easings.BounceEaseInOut 36 oKonva.Easings.StrongEaseIn //强力 37 oKonva.Easings.StrongEaseOut 38 oKonva.Easings.StrongEaseInOut
5.3.2 动画to的使用
- to就是对tween的封装,比较简单好用。
1 //案例: 2 var rect = new Konva.Rect({ 3 x: 10, 4 y: 10, 5 width: 100, 6 height: 100, 7 fill: 'red' 8 }); 9 layer.add(rect); 10 layer.draw(); 11 12 //动画系统 13 rect.to({ 14 x: 100, 15 y: 100, 16 opactity: .1, 17 duration: 3, 18 onFinish: function() { 19 20 } 21 }); 22 23 //to: 就是对tween的简单应用。
5.3.3 Animate的应用
- Animation动画,实际上就是浏览器通知开发者进行绘制,并提供当前的时间
1 var anim = new Konva.Animation(function(frame) { 2 //动画系统提供的frame有三个属性可以使用: 3 var time = frame.time, // 动画执行的总时间 4 timeDiff = frame.timeDiff, // 距离上一帧的时间 5 frameRate = frame.frameRate; // 帧率(既1000/间隔时间) 6 7 //动画的动作 8 9 }, layer); 10 11 anim.start();//启动动画 12 13 //anim.stop();//结束动画
5.3.4 循环播放动画的实现
1 //总体思路,使用tween 配合onFinish事件中重新播放动画,达到循环播放的效果 2 var loopTween = new Konva.Tween({ 3 node: star, //设置要表现动画的 Konva对象 4 rotation: 360, //旋转360度 5 duration: 2, //动画持续时间 6 easing: Konva.Easings.Linear, 7 onFinish: function() { 8 // this === loopTween //true 9 this.reset();//重置动画 10 this.play(); //重新播放动画 11 } 12 }); 13 loopTween.play();
5.3.5 回放且循环播放动画
- yoyo属性可以进行对动画进行播放完后,回放当前动画,并持续循环来回切换播放。
1 rect.to({ 2 duration: 2, 3 scale: 1.5, 4 yoyo: true// 此设置也可以用于 tween 5 });
5.3.6 进度条案例
5.3.7 传智官网案例
- 三角函数的补充
- Math.sin(弧度); //夹角对面的边 和 斜边的比值
- Math.cos(弧度); //夹角侧边 与斜边的比值
- 圆形上面的点的坐标的计算公式
- x =x0 + Math.cos(rad) * R;//x0和y0是圆心点坐标
- y =y0 + Math.sin(rad) * R;//注意都是弧度
- group的灵活运用
- konva的group很灵活,每个group都有自己的坐标系
- group可以包含其他的group,可以对group做整个组的动画
group可以通过getChidren();//可以拿到直接子级元素。
1 var group = new Konva.Group({ 2 x: 0, 3 y: 0 4 }); 5 group.add(rect);
5.4 Konva的事件(重要)
1 var rect = new Konva.Rect({ 2 x: 100, 3 y: 100, 4 fill: 'red', 5 width: 200, 6 height: 200 7 }); 8 9 //绑定事件 Konva支持事件:mouseover, mouseout, mouseenter, mouseleave, mousemove, mousedown, mouseup, mousewheel, click, dblclick, dragstart, dragmove, and dragend 10 11 rect.on('click', function(){ //jQuery一模一样!! 12 console.log('^_^ ^_^'); 13 }); 14 15 //绑定多个事件 16 rect.on('click mousemove',function(e){ 17 18 }); 19 20 //解除绑定事件 21 rect.off('click'); //这不是jQuery吗? 22 23 //触发事件 24 rect.fire('click'); 25 26 //取消事件冒泡 27 rect.on('click', function(evt) { 28 alert('You clicked the circle!'); 29 evt.cancelBubble = true; //取消事件冒泡 30 });
5.5 Konva的选择器
- 选择方法。
- ID选择法:stage.find('#id'); //此方法返回的是一个数组
- name选择法:group.findOne('.name');//返回一个Konva对象
- type选择法: group.find('Circle');//查找所有的圆形Konva对象
1 //组中查找圆形的Konva对象 2 groupCircle.find('Circle').each(function( circle, index ){ 3 circle.setZIndex( 3 - index ); 4 });
5.6 饼状图案例
- wedge: 楔形
5.7 柱状图案例
- histogram n. [统计] 直方图;柱状图 英 ['hɪstəgræm] 美 ['hɪstəɡræm]
六、Canvas项目实战
七、Canvas优化
1 <!-- requestAnim shim layer by Paul Irish --> 2 window.requestAnimFrame = (function(){ 3 return window.requestAnimationFrame || 4 window.webkitRequestAnimationFrame || 5 window.mozRequestAnimationFrame || 6 window.oRequestAnimationFrame || 7 window.msRequestAnimationFrame || 8 function(/* function */ callback, /* DOMElement */ element){ 9 window.setTimeout(callback, 1000 / 60); 10 }; 11 })(); 12 13 14 // example code from mr doob : http://mrdoob.com/lab/javascript/requestanimationframe/ 15 16 var canvas, context, toggle; 17 18 init(); 19 animate(); 20 21 function init() { 22 23 canvas = document.createElement( 'canvas' ); 24 canvas.width = 512; 25 canvas.height = 512; 26 27 context = canvas.getContext( '2d' ); 28 29 document.body.appendChild( canvas ); 30 31 } 32 33 function animate() { 34 requestAnimFrame( animate ); 35 draw(); 36 37 } 38 39 function draw() { 40 41 var time = new Date().getTime() * 0.002; 42 var x = Math.sin( time ) * 192 + 256; 43 var y = Math.cos( time * 0.9 ) * 192 + 256; 44 toggle = !toggle; 45 46 context.fillStyle = toggle ? 'rgb(200,200,20)' : 'rgb(20,20,200)'; 47 context.beginPath(); 48 context.arc( x, y, 10, 0, Math.PI * 2, true ); 49 context.closePath(); 50 context.fill(); 51 52 }