Canvas入門到高級詳解(下)

4、 Canvas 開發庫封裝

4.1 封裝經常使用的繪製函數

4.1.1 封裝一個矩形

//思考:咱們用到的矩形須要哪些繪製的東西呢?javascript

  1. 矩形的 x、y座標
  2. 矩形的寬高
  3. 矩形的邊框的線條樣式、線條寬度
  4. 矩形填充的樣式
  5. 矩形的旋轉角度
  6. 矩形的縮小放大
//下面是把上面全部的功能進行封裝的代碼: function ItcastRect( option ) {//矩形構造函數 this._init(option); } ItcastRect.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: ItcastRect }; 
  • 4.1.2 做業:嘗試着封裝一個圓形?
//封裝圓形的代碼的答案:不要偷看 function ItcastCircle(option) { this._init(option); } ItcastCircle.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: ItcastCircle }; 

4.2 第三方庫使用

  • Rgraph vs 百度的 echart
https://roopons.com.au/wp-content/plugins/viral-optins/js/rgraph/ 
  • 國產的 egret 引擎
http://www.egret-labs.org/ 
  • 比較火的 3d 引擎:treejs
http://threejs.org/ 
  • Konva
官網:http://konvajs.github.io/ 特色: * 小巧、使用方便、適合移動端和pc端 * 支持豐富的事件處理操做 * 支持相似JQuery的操做方式(順帶能複習jQueyr) * 開源,能夠隨意更改 * 社區更新比較活躍,github託管源碼 * 性能也不錯 
  • 其餘的還有不少,但願之後能用到大家的庫。

5、Konva 的使用快速上手

5.1 Konva 的總體理念

  • 舞臺的概念的引入。整個視圖看作是一個舞臺 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 的控制方法php

    • tween.play(), //播放動畫
    • tween.pause(), //暫停動畫
    • tween.reverse(), //動畫逆播放
    • tween.reset(), //重置動畫
    • tween.finish(), //當即結束動畫
    • seek:英文:尋找 英 [siːk] 美 [sik]
  • tween 的緩動控制選項css

    • 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
  • 動畫效果參考: 29Konva 動畫緩動效果案例.htmlhtml

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 (謙太祥和)官網案例

  • 三角函數的補充
    • Math.sin(弧度); //夾角對面的邊 和 斜邊的比值
    • Math.cos(弧度); //夾角側邊 與斜邊的比值
  • 圓形上面的點的座標的計算公式
    x =x0 + Math.cos(rad) * R;//x0 和 y0 是圓心點座標 _
    y =y0 + Math.sin(rad) * R; //注意都是弧度
 
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> <title>33Canvas案例-canvas案例</title> <style type="text/css" media="screen"> body { padding: 0; margin: 0; background-color: #f0f0f0; overflow: hidden; } </style> <script src="bower_components/konva/konva.min.js"></script> </head> <body> <div id="container"> </div> <script> (function(){ //建立舞臺 var stage = new Konva.Stage({ container: 'container', width: window.innerWidth, height: window.innerHeight }); //舞臺中心,也是旋轉的中心 var groupX = stage.width() / 2, groupY = stage.height() / 2, L3_Radius = 217, L2_Radius = 125, L1_Radius = 90, L0_Radius = 66; //背景層 var bgLayer = new Konva.Layer({ hitGraphEnabled : false//don’t need event on layer set }); //繪製背景圓形 3環 var circle_L3 = new Konva.Circle({ x: groupX, y: groupY, radius: L3_Radius, stroke: '#a0a0a0', stokeWidth: 2, opacity: .3, dash: [10,4] }); bgLayer.add(circle_L3); //繪製背景圓形 2環 var circle_L2 = new Konva.Circle({ x: groupX, y: groupY, radius: L2_Radius, stroke: '#2A3466', stokeWidth: 2, opacity: .3, dash: [10,4] }); bgLayer.add(circle_L2); //繪製背景中心區域 var cneterCircleText = new CircleText({ text: "WEB全棧", innerRadius: L0_Radius, outerRadius: L1_Radius, fontSize: 17, fontFamily: '微軟雅黑', fontFill: "#fff", fontX: -41, fontY: -8, x: groupX, y: groupY, innerFill: "#2A3466", outerFill: "#ddd", opacity: .8 }); var centerGroup = cneterCircleText.createCircleText(); bgLayer.add(centerGroup); stage.add(bgLayer); //動畫層 var layer = new Konva.Layer({ // hitGraphEnabled : false }); stage.add(layer); //建立總體的動畫組 var group = new Konva.Group({ x: groupX, y: groupY, rotation: 0 }); //要建立的5個3環的對象數據設置 var L3CircleData = [{ text: "WebApp",//建立webapp的圓心組合 1 innerRadius: 40, outerRadius: 50, fontSize: 14, fontFamily: '微軟雅黑', fontFill: "#fff", fontX: -30, fontY: -7, x: L3_Radius, y: 0, x: (Math.cos(20 * Math.PI / 180) * L3_Radius), y: (Math.sin(20 * Math.PI / 180) * L3_Radius), innerFill: "#CF2782", outerFill: "#ddd", opacity: .7 },{ text: "canvas",//動態建立第2個group innerRadius: 40, outerRadius: 50, fontSize: 16 , fontFamily: '微軟雅黑', fontFill: "purple", fontX: -28, fontY: -7, x: 0, y: L3_Radius, innerFill: "#7CB9CE", outerFill: "#ddd", opacity: .7 },{ text: "ReactJS", innerRadius: 40, outerRadius: 50, fontSize: 16 , fontFamily: '微軟雅黑', fontFill: "purple", fontX: -30 , fontY: -7, x: -L3_Radius, y: 0, innerFill: "#68AAFC", outerFill: "#ddd", opacity: .7 },{ text: "NodeJS", innerRadius: 40, outerRadius: 50, fontSize: 16 , fontFamily: '微軟雅黑', fontFill: "purple", fontX: -30 , fontY: -7, x: (Math.cos(-115 * Math.PI / 180) * L3_Radius), y: (Math.sin(-115 * Math.PI / 180) * L3_Radius), innerFill: "yellow", outerFill: "#ddd", opacity: .7 },{ text: "HTML5", innerRadius: 40, outerRadius: 50, fontSize: 16 , fontFamily: '微軟雅黑', fontFill: "purple", fontX: -30 , fontY: -7, x: (Math.cos(-45 * Math.PI / 180) * L3_Radius), y: (Math.sin(-45 * Math.PI / 180) * L3_Radius), innerFill: "green", outerFill: "#ddd", opacity: .7 }]; for( var i = 0; i < L3CircleData.length; i++ ) { var tempCircleText = new CircleText(L3CircleData[i]); var circleTextGroup = tempCircleText.createCircleText(); group.add(circleTextGroup); } layer.add(group); //繪製第二層動畫層 var groupL2 = new Konva.Group({ x: groupX, y: groupY, rotation: 0 }); // 繪製第二層的一個圓形 var zeptoJSCircleText = new CircleText({ text: "zeptoJS", innerRadius: 30, outerRadius: 40, fontSize: 14 , fontFamily: '微軟雅黑', fontFill: "blue", fontX: -26 , fontY: -7, x: (Math.cos(-75 * Math.PI / 180) * L2_Radius), y: (Math.sin(-75 * Math.PI / 180) * L2_Radius), innerFill: "orange", outerFill: "#ddd", opacity: .7 }); var groupZepto = zeptoJSCircleText.createCircleText(); groupL2.add(groupZepto); var CSS3CircleText = new CircleText({ text: "CSS3", innerRadius: 30, outerRadius: 40, fontSize: 14 , fontFamily: '微軟雅黑', fontFill: "blue", fontX: -20 , fontY: -7, x: (Math.cos(105 * Math.PI / 180) * L2_Radius), y: (Math.sin(105 * Math.PI / 180) * L2_Radius), innerFill: "pink", outerFill: "#ddd", opacity: .7 }); var groupC3 = CSS3CircleText.createCircleText(); groupL2.add(groupC3); layer.add(groupL2); layer.batchDraw(); //動畫處理層 var angularSpeed = 60;//每秒旋轉的角度 var anim = new Konva.Animation(function(frame) { console.log(frame.timeDiff); //計算每一幀旋轉的角度 var angleDiff = frame.timeDiff * angularSpeed / 1000; //三環進行旋轉 group.rotate(angleDiff); // group.getChildren().each(function(value, index){ value.rotate(-angleDiff) }); //2環 旋轉 groupL2.rotate(-angleDiff); //2環內的 組合進行反向旋轉 groupL2.getChildren().each(function(value, index){ value.rotate(angleDiff) }); }, layer); anim.start(); // 動畫事件處理 group.on('mouseover touchstart',function(e){ angularSpeed = 10; }); group.on('mouseleave touchend',function(e){ angularSpeed = 60; }); })(); //旋轉圖像的組合對象 function CircleText(option) { // 文字內容 // 圓的半徑 // 默認座標位置 // 顏色圓 // 顏色光環 // 透明度 option = option || {}; option.text = option.text || "canvas"; option.innerRadius = option.innerRadius || 40; option.outerRadius = option.outerRadius || 60; option.fontSize = option.fontSize || 14; option.fontWeight = option.fontWeight || "bold"; option.fontFamily = option.fontFamily || '微軟雅黑'; option.fontFill = option.fontFill || "#FFF"; option.fontX = option.fontX ||-20; option.fontY = option.fontY ||-7; option.x = option.x === 0 ? 0 : option.x || 217; option.y = option.y === 0 ? 0 : option.y || 217; option.innerFill = option.innerFill || "teal"; option.outerFill = option.outerFill || "#ddd"; option.opacity = option.opacity || .5; //建立旋轉組合對象的 組 this.createCircleText = function() { var group = new Konva.Group({ x: option.x, y: option.y, rotation: 0 }); //內圓 var innerCircle = new Konva.Circle({ x: 0, y: 0, radius: option.innerRadius, fill: option.innerFill, opacity: option.opacity, perfectDrawEnabled : false }); group.add(innerCircle); //環形 var outerRing = new Konva.Ring({ x: 0, y: 0, innerRadius: option.innerRadius, outerRadius: option.outerRadius, fill: option.outerFill, opacity: option.opacity, perfectDrawEnabled: false }); group.add(outerRing); //文字 var text = new Konva.Text({ text: option.text, fontSize: option.fontSize, fontFamily: option.fontFamily, fontStyle: 'bold', fill: option.fontFill, x: option.fontX, y: option.fontY, align: 'left' }); group.add(text); return group; } } </script> </body> </html> 

group 的靈活運用
* konva 的 group 很靈活,每一個 group 都有本身的座標系
* group 能夠包含其餘的 group,能夠對 group 作整個組的動畫
* group 能夠經過 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 的選擇器

  • 選擇方法。
    • ID 選擇法:stage.find('#id'); //此方法返回的是一個數組
    • name 選擇法:group.findOne('.name');//返回一個 Konva 對象
    • type 選擇法: group.find('Circle');//查找全部的圓形 Konva 對象
//組中查找圓形的Konva對象 groupCircle.find('Circle').each(function(circle, index) { circle.setZIndex(3 - index); }); 

5.6 餅狀圖案例

  • wedge: 楔形
//建立舞臺 var stage = new Konva.Stage({ container: 'container', width: window.innerWidth,//全屏 height: window.innerHeight }); //中心點座標 var cenX = stage.width() / 2; var cenY = stage.height() / 2; //建立層 var layer = new Konva.Layer(); stage.add(layer); //餅狀圖數據 var data = [{ name: "前端", value: .25, color: '#e0e' },{ name: "php", value: .2, color: 'orange' },{ name: "UI", value: .3, color: 'blue' },{ name: "C++", value: .05, color: 'green' },{ name: "遊戲", value: .1, color: 'purple' },{ name: "Java", value: .1, color: 'red' }]; //建立餅狀圖 var pieChart = new PieChart({ data: data,//扇形區域的數據 animateDuration: 2,//扇形動畫的時間 easing: Konva.Easings.EaseIn,//扇形動畫的速度規格 x: cenX, y: cenY, radius: .14 * stage.width(),//半徑 txtAwayFromWedge: .2 * .14 * stage.width()//扇形上的文字的距離圓形的距離 }); pieChart.addToLayer(layer); pieChart.playAnimate(); layer.draw(); layer.on('click tap', function(){ pieChart.playAnimate(); }); //餅狀圖 function PieChart(option) { var _this = this; if( !option ) { throw new Error('請初始化餅狀圖的參數'); } this.animageIndex = 0; this.init = function(otpion) { //餅狀圖數據:[{name:'',value:.2,color:'red'},...] option.data = option.data || []; //動畫執行的時間 option.animateDuration = option.animateDuration || .8; //動畫執行的效果 option.easing = option.easing || Konva.Easings.Linear; //x,y座標 option.x = option.x || 0; option.y = option.y || 0; //餅狀圖半徑 option.radius = option.radius === 0 ? 0 : option.radius || 100; option.txtAwayFromWedge = option.txtAwayFromWedge || 20; //扇區的組 this.group = new Konva.Group({ x: option.x, y: option.y }); //文字的組 this.TxtGroup = new Konva.Group({ x: option.x, y: option.y }); //默認的旋轉角度 var tempAngel = -90; //遍歷生成全部扇形的對象 for(var i = 0; i < option.data.length; i++ ) { var wedgeAngel = option.data[i].value * 360; var wedge = new Konva.Wedge({ x: 0, y: 0, radius: option.radius, fill: option.data[i].color, angle: 0,//後面有計算出角度放到數組中 opacity: .8, id: option.data[i].name, name: wedgeAngel + '', rotation: tempAngel, visible: true }); this.group.add(wedge); //當前 扇形的對象 和扇形的須要旋轉的角度 // arr.push({value: wedge, angle: option.data[i].value * 360}); //繪製 文字 //扇形區域的中間 var totalAngle = tempAngel + 1/2 * wedgeAngel; //設置文字的x座標 var txtX = Math.cos( totalAngle * Math.PI / 180) * (option.radius + option.txtAwayFromWedge); // 設置文字的y座標 var txtY = Math.sin( totalAngle * Math.PI / 180) * (option.radius + option.txtAwayFromWedge); var txtTitle = option.data[i].name +' ' + option.data[i].value * 100 + '%'; var txt = new Konva.Text({ x: txtX, y: txtY, fill: option.data[i].color, fontSize: '14px', fontFamily: '微軟雅黑', fontStyle: 'bold', align: 'left', id: 'txt_' + option.data[i].name, text: txtTitle, visible: false //默認隱藏 }); this.TxtGroup.add(txt); console.log(txt.x() + " " + txt.y()); //設置下一個元素旋轉到具體的位置 tempAngel += option.data[i].value * 360; } }; this.init(option);//初始化 //把當前 餅狀圖添加到 層 this.addToLayer = function(layer) { layer.add(this.group); layer.add(this.TxtGroup); layer.draw(); }; //展現動畫 this.playAnimate = function() { _this = this; if(this.animageIndex >= data.length) { _this.animageIndex = 0; return; } if(this.animageIndex == 0) { _this.group.getChildren().each(function(value, index){ value.angle(0); }); _this.TxtGroup.getChildren().each(function(value,index){ value.hide(); }); } this.calleeFn = arguments.callee;//當前函數 //繪製一個 扇區的動畫 var wedge = this.group.getChildren()[this.animageIndex]; var angel = Number(wedge.name());//扇區的度數 wedge.to({ angle: angel, duration: angel * option.animateDuration / 360, onFinish: function() { _this.TxtGroup.getChildren()[_this.animageIndex].show(); _this.TxtGroup.getParent().draw(); _this.animageIndex++; _this.calleeFn();//調用當前函數自身,造成動畫隊列。 } }); }; } 

5.7 柱狀圖案例

  • histogram n. [統計] 直方圖;柱狀圖 英 ['hɪstəgræm] 美 ['hɪstəɡræm]
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> <title>36柱狀圖案例</title> <style> body { padding: 0; margin: 0; background-color: #f0f0f0; overflow: hidden; } </style> <script src="bower_components/konva/konva.min.js"></script> <script src="js/KonvaExtend.js" charset="utf-8"></script> </head> <body> <div id="container"> </div> <script> var stage = new Konva.Stage({ container: 'container', width: window.innerWidth, height: window.innerHeight }); var layer = new Konva.Layer(); stage.add(layer); var cenX = stage.width() / 2; var cenY = stage.height() / 2; var data = [ { name: '百度', value: .2, color: 'blue' }, { name: '阿里', value: .4, color: 'red' }, { name: '新浪', value: .1, color: 'purple' }, { name: '搜狐', value: .1, color: 'navy' }, { name: '360', value: .2, color: 'orange' } ]; var his = new Histogram({ data: data, x: 1/8 * stage.width(), y: 3/4 * stage.height(), blWidth: 2, blColor: 'lightblue', width: 3/4 * stage.width(), height: 1/3 * stage.height(), fontSize: 14 }); his.addToGroupOrLayer(layer); layer.draw(); his.playAnimate(); layer.on('click',function(){ his.playAnimate(); }); </script> </body> </html> 

6、Canvas 項目實戰

7、Canvas 優化

<!-- requestAnim shim layer by Paul Irish -->
    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(); } 

視頻

配套視頻請戳:https://www.bilibili.com/video/av26151775/java

關注AICODER官網: https://www.aicoder.comnode

相關文章
相關標籤/搜索