基於CANVAS的簡單畫圖組件讓你用類似於dom的方式,在canvas上畫圖,感覺會不會很爽。
主頁:http://graph.jm47.com/
示例:http://graph.jm47.com/example/index.html
安裝
直接從github下載
https://github.com/jiamao/jmgraph
入門
下載jmGraph.min.js代碼,並引用到你的html中。
<script type="text/javascript" src="../dist/jmGraph.min.js"></script>
在dom中添加一個div或canvas,然后初始化jmGraph。
<div id="mycanvas_container"></div>
<script type="text/javascript">
//也可以是一個dom對象或一個jquery對象
//例如:$('#mycanvas_container') || document.getElementById('mycanvas_container')
var container = 'mycanvas_container';
// 用Promise方式
/*jmGraph(container, {
width: 800,
height: 600
}).then((g)=>{
//g就是一個jmGraph實例
init(g);
}); */
var g = new jmGraph(container, {
width: 800,
height: 600,
//樣式,規則請參照樣式說明
style: {
fill: '#000' //指定背景色
}
});
</script>
在畫布上畫一個方塊
function init(g){ var style = { stroke:'#46BF86', lineWidth: 2 }; style.shadow = '0,0,10,#fff';//陰影 //style.opacity = 0.2; //style.lineCap = 'round'; //創建一個方塊 var rect = g.createShape('rect',{ style:style, position: {x:100,y:100}, //左上角坐標 width:100, height:100 }); g.children.add(rect); //繪制,可以用requestAnimationFrame動態刷新 function update() { g.redraw(); //requestAnimationFrame(update); } update(); }
樣式
樣式可以直接用canvas支持的名稱,也可以用本組件簡化后的。
樣式一覽
| 簡化名稱 | 原生名稱 | 說明 |
|---|---|---|
| fill | fillStyle | 用於填充繪畫的顏色、漸變或模式 |
| stroke | strokeStyle | 用於筆觸的顏色、漸變或模式 |
| shadow | 沒有對應的 | 最終會解析成以下幾個屬性,格式:'0,0,10,#fff'或g.createShadow(0,0,20,'#000'); |
| shadow.blur | shadowBlur | 用於陰影的模糊級別 |
| shadow.x | shadowOffsetX | 陰影距形狀的水平距離 |
| shadow.y | shadowOffsetY | 陰影距形狀的垂直距離 |
| shadow.color | shadowColor | 陰影顏色,格式:'#000'、'#46BF86'、'rgb(255,255,255)'或'rgba(39,72,188,0.5)' |
| lineWidth | lineWidth | 當前的線條寬度 |
| miterLimit | miterLimit | 最大斜接長度 |
| font | font | 文本內容的當前字體屬性 |
| opacity | globalAlpha | 繪圖的當前 alpha 或透明值 |
| textAlign | textAlign | 文本內容的當前對齊方式 |
| textBaseline | textBaseline | 在繪制文本時使用的當前文本基線 |
| lineJoin | lineJoin | 兩條線相交時,所創建的拐角類型:miter(默認,尖角),bevel(斜角),round(圓角) |
| lineCap | lineCap | 線條的結束端點樣式:butt(默認,平),round(圓),square(方) |
| zIndex | - | 控件層級,同級節點值越大層級越高 |
事件
事件的綁定函數:bind/unbind
示例:
//創建一條線 var line = graph.createLine({x:10,y:200},{x:80,y:120},style); //鼠標移到上面顯示不同的樣式 line.bind('mouseover',function(evt) { this.style.stroke = 'rgba(39,72,188,0.5)'; this.cursor('pointer'); this.neadUpdate = true; //需要刷新 });
事件一覽
| 名稱 | 說明 | 回調參數 |
|---|---|---|
| mousedown | 鼠標按下時觸發 | - |
| mousemove | 鼠標在對象上移動時觸發 | {target:當前元素,position: 當前位置} |
| mouseover | 鼠標從某元素移開 | {target:當前元素} |
| mouseleave | 某個鼠標按鍵被松開 | - |
| mouseup | 某個鼠標按鍵被松開 | - |
| dblclick | 鼠標雙擊某個對象 | - |
| click | 鼠標點擊某個對象 | - |
| touchstart | 觸控開始 | position: 當前位置 |
| touchmove | 觸控移動手指 | position: 當前位置 |
| touchend | 觸控結束 | position: 當前位置 |
控件
Path
path是多數圖形的基類,可以指定一個points數組來繪制一個路徑。
在線示例
var path = graph.createPath(null,style); path.points.push({x:10,y:10}); path.points.push({x:10,y:60}); path.points.push({x:80,y:20}); path.points.push({x:90,y:80}); path.points.push({x:80,y:80});
圓
arc可以創建橢圓、圓弧和圓,circle調用的是原生的arc函數繪制,harc可以繪制一個圓環。 具體請參考示例。 在線示例
//創建一個橢圓,指定不同的寬高就為橢圓。如果相同或指定半徑則為圓。 var arc1 = g.createShape('arc', { style: style, center: {x:100, y:150}, width: 120, height: 80 });
箭頭
arraw為創建一個箭頭, arrawline是一條帶箭頭的直線。
具體請參考示例。 在線示例
//帶箭頭的直線 var shape = g.createShape('arrawline',{ style:style, start: {x:100,y:100}, end: {x: 200, y: 350} }); //一起結束點和一個角度angle可以決定一個箭頭,如果不填angle,則會用start和end來計算角度 var arraw = g.createShape('arraw',{ style:style, start: {x:150, y:120}, end: {x: 160, y: 150} //angle: Math.PI/2, //箭頭角度 可以不填 //offsetX: 5, //箭頭X偏移量 //offsetY: 8 //箭頭Y偏移量 });
貝塞爾曲線
bezier可以指定無隱個控制點,繪制復雜的曲線。 具體請參考示例。 在線示例
//一個固定的bezier曲線 var bezier = g.createShape('bezier', { style: style, points: [p0, p1, p2, p3, p4] });
圖片
img是用來承載一張圖片的控件,可以用style.src來指定圖片url。 具體請參考示例。 在線示例
var style = { src: 'http://mat1.gtimg.com/www/qq2018/imgs/qq_logo_2018x2.png' }; style.shadow = '0,0,10,#fff'; //style.opacity = 0.2; //創建一個image var img = g.createShape('image',{ style:style, position: {x:100,y:100} }); //設置圖片可以用鼠標移動 img.canMove(true);
文字
label可以用來繪制文字,通過style指定樣式。 具體請參考示例。 在線示例
var style = { stroke: '#effaaa', fill: '#fff', textAlign: 'center', //水平居中 textBaseline: 'middle', //垂直居中 font: '20px Arial', border: {left:1,top:1,right:1,bottom:1}, //邊框 shadow: '0,0,10,#fff' }; //style.opacity = 0.2; //創建一個label var label = g.createShape('label',{ style:style, position:{x:200,y:150}, text:'test label', width:120, height:80 });
棱形
prismatic
具體請參考示例。 在線示例
var prismatic = g.createShape('prismatic',{ style:style, center:{x:200,y:150}, width:120, height:80 });
可縮放控件
resize 可以自由放大縮小的控件。 具體請參考示例。 在線示例
var style = { stroke: 'red', fill: 'yellow', lineWidth: 2, //邊線寬 //小方塊樣式 rectStyle: { stroke: 'green', //小方塊邊顏色 fill: 'transparent',//小方塊填充色 lineWidth: 1, //小方塊線寬 close: true } }; //style.opacity = 0.2; //創建一個resize var resize = g.createShape('resize', { style: style, position: {x:200, y:150}, width: 120, height: 80 }); //大小改變事件 resize.on('resize', function() { console.log(arguments); });
自定義控件
大多數控件直接繼承jmPath即可,然后通過實現initPoints來繪制當前控件。當需要從某點重新開始畫時,給點指定m屬性為true,表示移到當前點。
示例
來畫一個X
在線示例:http://graph.jm47.com/example/controls/test.html
function jmTest(graph,params) { if(!params) params = {}; this.points = params.points || []; var style = params.style || {}; this.type = 'jmTest'; this.graph = graph; this.center = params.center || {x:0,y:0}; this.radius = params.radius || 0; this.initializing(graph.context, style); } jmUtils.extend(jmTest, jmPath);//jmPath //定義屬性 /** * 中心點 * point格式:{x:0,y:0,m:true} * @property center * @type {point} */ jmUtils.createProperty(jmTest.prototype, 'center'); /** * 半徑 * @property radius * @type {number} */ jmUtils.createProperty(jmTest.prototype, 'radius', 0); /** * 初始化圖形點 * 控件都是由點形成 * * @method initPoint * @private * @for jmArc */ jmTest.prototype.initPoints = function() { //可以獲取當前控件的左上坐標,可以用來畫相對位置 var location = this.getLocation();//獲取位置參數 var cx = location.center.x ; var cy = location.center.y ; this.points = []; //簡單的畫一個X //根據半徑計算x,y偏移量 //由於是圓,偏移量相同 var offw = Math.sqrt(location.radius * location.radius / 2); //左上角到右下角對角線 this.points.push({x:cx - offw, y:cy-offw}, {x:cx + offw, y:cy+offw}); //左下角到右上角對角線 //畫完上面的線后,需要重新移到這條線的起點,指定m:true即可 this.points.push({x:cx - offw, y:cy+offw, m:true}, {x:cx + offw, y:cy-offw}); return this.points; }
微信小程序支持
微信小程序稍有差別,因為無需壓縮,請直接把dist中的jmgraph.js合並后的文件引用到你的小程序中。
示例
wxml
<canvas style="width: 400px; height: 600px;background:#000;" canvas-id="mycanvas" bindtouchstart="canvastouchstart" bindtouchmove="canvastouchmove" bindtouchend="canvastouchend" bindtouchcancel="canvastouchcancel"> </canvas>
javascript
/** * 生命周期函數--監聽頁面初次渲染完成 */ onReady: function () { //這里引用jmgraph let jmGraph = require('../../utils/jmgraph'); var self = this; jmGraph('mycanvas', { width: 400, height: 600 }).then((g) => { init(g) }); function init(g) { //g.style.fill = '#000'; //畫布背景 var style = { stroke: '#46BF86', fill: '#556662', lineWidth: 2 }; style.shadow = '0,0,10,#fff'; //style.opacity = 0.2; //style.lineCap = 'round'; //創建一個方塊 var rect = g.createShape('rect', { style: style, position: { x: 100, y: 100 }, width: 100, height: 100 }); rect.canMove(true); g.children.add(rect); function update() { if (g.needUpdate) g.redraw(); setTimeout(update, 20); } update(); //初始化jmGraph事件 //把小程序中的canvas事件交給jmGraph處理 self.canvastouchstart = function() { return g.eventHandler.touchStart.apply(this, arguments); } self.canvastouchmove = function() { return g.eventHandler.touchMove.apply(this, arguments); } self.canvastouchend = function() { return g.eventHandler.touchEnd.apply(this, arguments); } self.canvastouchcancel = function() { return g.eventHandler.touchCancel.apply(this, arguments); } } }
