《4.1封裝常用的繪制函數》
4.1.1封裝一個矩形
//思考:我們用到的矩形需要哪些繪制的東西呢?
1、矩形的x、y坐標
2、矩形的寬高
3、矩形的邊框的線條樣式、線條寬度
4、矩形填充的樣式
5、矩形的旋轉角度
6、矩形的縮小放大
//下面是把上面所有的功能進行封裝的代碼:
function XMGRect( option ) {//矩形構造函數
this._init(option);
}
XMGRect.prototype = { ?//矩形的原型對象
_init: function( option ) { ?//初始化方法
option = option || {};
this.x = option.x === 0 ? 0 : option.x || 100;
this.y = option.y === 0 ? 0 : option.y || 100;
this.w = option.w || 100;
this.h = option.h || 100;
this.angle = option.angle === 0 ? 0 : option.angle || 0;
this.fillStyle = option.fillStyle || 'silver';
this.strokeStyle = option.strokeStyle || 'red';
this.strokeWidth = option.strokeWidth || 4;
this.scaleX = option.scaleX || 1;
this.scaleY = option.Y || 1;
},
render: function( ctx ) {//把矩形渲染到canvas中
ctx.save();
ctx.translate( this.x, this.y );//位移畫布
ctx.rotate( this.angle * Math.PI / 180 );//旋轉角度
ctx.scale( this.scaleX, this.scaleY );//縮放
ctx.fillStyle = this.fillStyle;
ctx.fillRect( 0, 0, this.w, this.h ); //填充矩形
ctx.lineWidth = this.strokeWidth; ? ? //線寬
ctx.strokeStyle = this.strokeStyle; ? //填充樣式
ctx.strokeRect( 0,0,this.w,this.h ); ?//描邊樣式
ctx.restore();
},
constructor: XMGRect
};
4.1.2作業:嘗試著封裝一個圓形?
function XMGCircle( option ) {
this._init( option );
}
XMGCircle.prototype = {
_init: function( option ) {
option = option || {};
this.x = option.x === 0 ? 0 : option.x || 100;
this.y = option.y === 0 ? 0 : option.y || 100;
this.w = option.w || 100;
this.h = option.h || 100;
this.angle = option.angle === 0 ? 0 : option.angle || 0;
this.fillStyle = option.fillStyle || 'silver';
this.strokeStyle = option.strokeStyle || 'red';
this.strokeWidth = option.strokeWidth || 4;
this.scaleX = option.scaleX || 1;
this.scaleY = option.Y || 1;
this.opactity = option.opactity || 1;
this.counterclockwise =
option.counterclockwise === true ? true : option.counterclockwise || false;
this.startAngle = option.startAngle == 0 ? 0 : option.startAngle || 0;
this.endAngle = option.endAngle == 0 ? 0 : option.endAngle || 0;
this.startAngle = this.startAngle * Math.PI/180;
this.endAngle = this.endAngle * Math.PI / 180;
this.r = option.r || 100;
},
render: function( ctx ) {
ctx.save();
ctx.translate( this.x, this.y);
ctx.scale( this.scaleX, this.scaleY );
ctx.rotate( this.agnle * Math.PI / 180 );
ctx.globalAlpha = this.opacity;
ctx.fillStyle = this.fillStyle;
ctx.strokeStyle = this.strokeStyle;
ctx.moveTo(0, 0);
ctx.arc( 0, 0, this.r, this.startAngle, this.endAngle, this.counterclockwise);
ctx.fill();
ctx.stroke();
ctx.restore();
},
constructor: XMGCircle
};
《4.2 第三方庫》
百度的echart
http://echarts.baidu.com/echarts2/doc/example.html
國產的egret引擎
http://www.egret-labs.org/
比較火的3d引擎:treejs
FABRIC.JS ? oCanvas ? ?RGraph
【Konva】
官網:
特點:
*小巧、使用方便、適合移動端和pc端
*支持豐富的事件處理操作
*支持類似JQuery的操作方式
*開源,可以隨意更改
*社區更新比較活躍,github托管源碼
*性能也不錯
【五、Konva的使用快速上手】
《5.1Konva的整體理念》
舞臺:
整個視圖看做是一個舞臺stage
舞臺中可以繪制很多個層layer
layer下面可以有很多的group
group下面可以有 矩形、圖片、其他形狀等
Stage
|
+------+------+
| ? ? ? ? ? ? |
Layer ? ? ? ? Layer
| ? ? ? ? ? ? |
+-----+-----+ ? ? Shape
| ? ? ? ? ? |
Group ? ? ? Group
| ? ? ? ? ? |
+ ? ? ? +---+---+
| ? ? ? | ? ? ? |
Shape ? Group ? ?Shape
|
+
|
Shape
《5.2 Konva矩形案例》
5.2.1 創建一個矩形: Konva.Rect(option);
//Konva使用的基本案例
//第一步:創建舞臺
var stage = new Konva.Stage({
container: 'container', ? ? //需要存放舞臺的Dom容器
width: window.innerWidth, ? //設置全屏
height: window.innerHeight
});
//第二步:創建層
var layer = new Konva.Layer(); ?//創建一個層
stage.add(layer);//把層添加到舞臺
//第三步: 創建矩形
var rect = new Konva.Rect({ ? ? //創建一個矩形
x: 100, ? ? ? ? ? ? ? ? ? ? //矩形的x坐標,相對其父容器的坐標
y: 100,
width: 100, ? ? ? ? ? ? ? ? //矩形的寬度
height: 100, ? ? ? ? ? ? ? ?//矩形高度
fill: 'gold', ? ? ? ? ? ? ? //矩形填充的顏色
stroke: 'navy', ? ? ? ? ? ? //矩形描邊的顏色
strokeWidth: 4, ? ? ? ? ? ? //填充寬度
opactity: .2, ? ? ? ? ? ? ? //矩形的透明度
scale: 1.2, ? ? ? ? ? ? ? ? //矩形的縮放1:原來大小
rotation: 30, ? ? ? ? ? ? ? //旋轉的角度,是deg不是弧度。
cornerRadius: 10, ? ? ? ? ? //圓角的大小(像素)
id: 'rect1', ? ? ? ? ? ? ? ?//id屬性,類似dom的id屬性
name: 'rect',
draggable: true ? ? ? ? ? ? //是否可以進行拖拽
});
//創建一個組
var group = new Konva.Group({
x: 40,
y: 40,
});
group.add( rect ); ?//把矩形添加到組中
//第四步: 把形狀放到層中
layer.add( group ); //把組添加到層中
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等
//案例:
var tween = new Konva.Tween({
node: rect, ? ? ? ? ? ? //要進行動畫的Konva對象
x: 300, ? ? ? ? ? ? ? ? //要進行動畫的屬性
opacity: .8,
duration: 1, ? ? ? ? ? ?//持續時間
easing: Konva.Easings.EaseIn, //動畫的動畫效果
yoyo: true, ? ? ? ? ? ? //是否進行循環播放的設置
onFinish: function() {
//動畫執行結束后,執行此方法
}
});
tween.play(); ? //啟動動畫
tween的控制方法
tween.play(), //播放動畫
tween.pause(), //暫停動畫
tween.reverse(), //動畫逆播放
tween.reset(), //重置動畫
tween.finish(), //立即結束動畫
seek:英文:尋找 英[si?k]美[sik]
tween的緩動控制選項
Konva.Easings.Linear //線性
Konva.Easings.EaseIn //緩動,先慢后快
Konva.Easings.EaseOut //先快后慢
Konva.Easings.EaseInOut //兩頭慢,中間快
Konva.Easings.BackEaseIn //往回來一點,然后往前沖,汽車啟動類似...
Konva.Easings.BackEaseOut
Konva.Easings.BackEaseInOut
Konva.Easings.ElasticEaseIn //橡皮筋 英[?'l?st?k]美[?'l?st?k]
Konva.Easings.ElasticEaseOut
Konva.Easings.ElasticEaseInOut
Konva.Easings.BounceEaseIn //彈跳;彈起,反跳;彈回 英[ba?ns]美[ba?ns]
Konva.Easings.BounceEaseOut
Konva.Easings.BounceEaseInOut
Konva.Easings.StrongEaseIn //強力
Konva.Easings.StrongEaseOut
Konva.Easings.StrongEaseInOut
5.3.2 動畫to的使用
to就是對tween的封裝,比較簡單好用。
//案例:
var rect = new Konva.Rect({
x: 10,
y: 10,
width: 100,
height: 100,
fill: 'red'
});
layer.add(rect);
layer.draw();
//動畫系統
rect.to({
x: 100,
y: 100,
opactity: .1,
duration: 3,
onFinish: function() {
}
});
//to:就是對tween的簡單應用。
5.3.3 Animate的應用
Animation動畫,實際上就是瀏覽器通知開發者進行繪制,并提供當前的時間
var anim = new Konva.Animation(function(frame) {//類似于定時器
//動畫系統提供的frame有三個屬性可以使用:
var time = frame.time, //動畫執行的總時間
timeDiff =frame.timeDiff,//距離上一幀的時間
frameRate = frame.frameRate; //幀率(既1000/間隔時間)
//動畫的動作
},layer);
anim.start();//啟動動畫
//anim.stop();//結束動畫
5.3.4 循環播放動畫的實現
//總體思路,使用tween配合onFinish事件中重新播放動畫,達到循環播放的效果
var loopTween = new Konva.Tween({
node: star, //設置要表現動畫的Konva對象
rotation: 360, ?//旋轉360度
duration: 2, ? ?//動畫持續時間
easing: Konva.Easings.Linear,
onFinish: function() {
// this === loopTween //true
this.reset();//重置動畫
this.play(); //重新播放動畫
}
});
loopTween.play();
5.3.5 回放且循環播放動畫
yoyo屬性可以進行對動畫進行播放完后,回放當前動畫,并持續循環來回切換播放。
rect.to({
duration: 2,
scale: 1.5,
yoyo: true//此設置也可以用于tween
});
5.3.6 進度條案例
5.3.7 體系環繞案例
三角函數的補充
lMath.sin(弧度); //夾角對面的邊 和 斜邊的比值
lMath.cos(弧度); //夾角側邊 與斜邊的比值
圓形上面的點的坐標的計算公式
x =x0 + Math.cos(rad) * R;//x0和y0是圓心點坐標
y =y0 + Math.sin(rad) * R;//注意都是弧度
group的靈活運用
lkonva的group很靈活,每個group都有自己的坐標系
lgroup可以包含其他的group,可以對group做整個組的動畫
lgroup可以通過getChidren();//可以拿到直接子級元素。
var group = new Konva.Group({
x: 0,
y: 0
});
group.add(rect);
《5.4 Konva的事件(重要)》
var rect = new Konva.Rect({
x: 100,
y: 100,
fill: 'red',
width: 200,
height: 200
});
//綁定事件Konva支持事件:mouseover, mouseout, mouseenter, mouseleave, mousemove, mousedown, mouseup, mousewheel, click, dblclick, dragstart, dragmove, and dragend
rect.on('click', function(){ ? //jQuery一模一樣!!
console.log('^_^ ?^_^');
});
//綁定多個事件
rect.on('click mousemove',function(e){
});
//解除綁定事件
rect.off('click'); ? ? ? ? ? ? //這不是jQuery嗎?
//觸發事件
rect.fire('click');
//取消事件冒泡
rect.on('click', function(evt) {
alert('You clicked the circle!');
evt.cancelBubble = true; ? ? ?//取消事件冒泡
});
《5.5 Konva的選擇器》
選擇方法:
lID選擇法:stage.find('#id'); //此方法返回的是一個數組
lname選擇法:group.findOne('.name');//返回一個Konva對象
ltype選擇法:group.find('Circle');//查找所有的圓形Konva對象
//組中查找圓形的Konva對象
groupCircle.find('Circle').each(function( circle, index ){
circle.setZIndex( 3 - index );
});
《5.6 餅狀圖案例》
wedge:楔形,扇形
《5.7 柱狀圖案例》
histogram n. [統計]直方圖;柱狀圖 英['h?st?gr?m]美['h?st?ɡr?m]
【六、Canvas項目實戰】
【七、Canvas優化】
window.requestAnimFrame = (function(){
return ?window.requestAnimationFrame ? ? ? ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ? ?||
window.oRequestAnimationFrame ? ? ?||
window.msRequestAnimationFrame ? ? ||
function(/* function */ callback, /* DOMElement */ element){
window.setTimeout(callback, 1000 / 60);
};
})();
// example code from mr doob : http://mrdoob.com/lab/javascript/requestanimationframe/
var canvas, context, toggle;
init();
animate();
function init() {
canvas = document.createElement( 'canvas' );
canvas.width = 512;
canvas.height = 512;
context = canvas.getContext( '2d' );
document.body.appendChild( canvas );
}
function animate() {
requestAnimFrame( animate );
draw();
}
function draw() {
var time = new Date().getTime() * 0.002;
var x = Math.sin( time ) * 192 + 256;
var y = Math.cos( time * 0.9 ) * 192 + 256;
toggle = !toggle;
context.fillStyle = toggle ? 'rgb(200,200,20)' : ?'rgb(20,20,200)';
context.beginPath();
context.arc( x, y, 10, 0, Math.PI * 2, true );
context.closePath();
context.fill();
}