canvas+JS如何實現可拖拽並且顯示百分比的環形進度條
思維導圖:
HTML部分:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
</head>
<body>
<canvas id="test" width="200" height="200"></canvas>
<script src="js/drafting.js"></script>
<script type="text/javascript">
var canvasId = document.getElementById("test");
var drag1 = new DraftingByZM({
//必傳參數,注意此處必須傳原生對象,不能是jQuery對象
canvasByZM: canvasId
});
</script>
</body>
</html>
js組件:
/**
*
* @authors ZM
* @date 2017-09-05 18:42:09
* @version 1.0
*/
DraftingByZM = (function(){
var Obj = function(options){
this._setPara(options);
this.init();
};
Obj.prototype = {
constructor: Obj,
author: "ZM",
version: 1.0,
//入口方法
init: function(){
this._check();
this._eventListen();
},
//畫圓
_check: function(){
//簡單校驗,查看是否支持HTML5<canvas></canvas>標籤
if(this.canvasByZM.getContext){
this._circlePara();
//var _this = this;
this._drawCircle(this.$Begin);//傳入參數爲起始位置(0到1)
}else{
alert('Your browser does not support this function temporarily. Please upgrade your browser version as soon as possible.');
}
},
//圓的參數
_circlePara: function(){
this.context = this.canvasByZM.getContext('2d');//調用getContext方法,返回一個畫布環境
this.ox = 100;//圓環在畫布上的x軸座標
this.oy = 100;//圓環在畫布上的y軸座標
this.or = 70;//圓環半徑
this.br = 15;//圓珠半徑
},
//根據弧度與距離計算偏移座標
_calOffset: function(r,d){
return {x: -Math.sin(r)*d, y: Math.cos(r)*d};
},
_drawCircle: function(n){
var ctx = this.context;
//console.log(this.canvasByZM.width);
ctx.clearRect(0,0,this.canvasByZM.width,this.canvasByZM.height);
//clearRect()==>HTML5中的方法,用於擦除指定區域
//底環
ctx.strokeStyle = this.$acrossColor;//底色
ctx.lineWidth = this.$circleThinkness;//底環粗細
ctx.beginPath();//起始一條路徑,或重置當前路徑
ctx.arc(this.ox,this.oy,this.or,0,2*Math.PI,true);
ctx.stroke();
//有色環
ctx.strokeStyle = this.$fillColor;//顏色
ctx.lineWidth = this.$circleThinkness;//寬度
ctx.beginPath();
ctx.arc(this.ox,this.oy,this.or,0.5*Math.PI,(n*2+0.5)*Math.PI,false);
//arc(x, y, radius, startAngle, endAngle, anticlockwise):
//畫一個以(x,y)爲圓心的以radius爲半徑的圓弧(圓),
//從startAngle開始到endAngle結束,按照anticlockwise給定的方向(默認爲順時針)來生成
ctx.stroke();
//中間文字
ctx.fillStyle = this.$fillColor;//顏色
ctx.font = this.$FontSize +"px Arial";//字號
ctx.textAlign = "center";
ctx.textBaseline = "middle";
//計算數值的取值區間
ctx.fillText(Math.round(n*100)+this.$FontUnit,this.ox,this.oy);
//圓珠
ctx.fillStyle = this.$fillColor;
ctx.beginPath();
var d = this._calOffset(n*2*Math.PI,this.or);
console.log(d);
ctx.arc(this.ox+d.x,this.oy+d.y,this.br,0,2*Math.PI,true);
ctx.fill();
},
//獲取鼠標當前座標
_getXY: function(e) {
var _this = this;
var et = e.touches? e.touches[0] : e;
var x = et.clientX;
var y = et.clientY;
console.log(x);
console.log(y);
return {
x : x - _this.canvasByZM.getBoundingClientRect().left + (document.body.scrollLeft || document.documentElement.scrollLeft),
y : y - _this.canvasByZM.getBoundingClientRect().top + (document.body.scrollTop || document.documentElement.scrollTop)
// x : x - _this.canvasByZM.offsetLeft + (document.body.scrollLeft || document.documentElement.scrollLeft),
// y : y - _this.canvasByZM.offsetTop + (document.body.scrollTop || document.documentElement.scrollTop)
//offsetLeft存在一定兼容性問題,其在有些瀏覽器中是根據父元素獲取其偏移值,
//有些卻是根據body元素獲取偏移值。
//這裏可以使用getBoundingClientRect獲取對應元素到視窗的距離
}
},
//監聽事件
_eventListen: function(){
//是否支持觸屏
var on = ("ontouchstart" in document)? {
start: "touchstart", move: "touchmove", end: "touchend"
} : {
start: "mousedown", move: "mousemove", end: "mouseup"
};
var _this = this;
this.canvasByZM.addEventListener(on.end, function(e) {
_this.moveFlag = false;
}, false);
this.canvasByZM.addEventListener(on.start, function(e) {
_this.moveFlag = true;
}, false);
this.canvasByZM.addEventListener(on.move, function(e) {
if (_this.moveFlag) {
//獲取座標
var k = _this._getXY(e);
//計算弧度
var r = Math.atan2(k.x-_this.ox,_this.oy-k.y);
//畫圓
_this._drawCircle((Math.PI+r)/(2*Math.PI));
}
}, false);
},
//設置參數
_setPara: function(option){
this.canvasByZM = option.canvasByZM;
this.$circleThinkness = option.$circleThinkness || 10;
this.$acrossColor = option.$acrossColor || "#ccc";
this.$fillColor = option.$fillColor || "#ff5151";
this.$FontUnit = option.$FontUnit || "%";
this.moveFlag = false;//開關
this.$Begin = parseFloat(option.$Begin) || 0.5;
this.$FontSize = option.$FontSize || 50;
},
remove: function(){ // 移除組件
//清除事件
this.canvasByZM.onmousedown = null;
this.canvasByZM.onmousemove = null;
this.canvasByZM.onmouseup = null;
// 釋放內存
for (var i in this){
this[i] = null;
}
}
};
return Obj;
})();
//調用示例
// var drag1 = new DraftingByZM({
// //必傳參數,注意此處必須傳原生對象,不能是jQuery對象
// canvasByZM: $("#canvas1")[0],
// //可選參數
// $circleThinkness:10, //元環粗細
// $acrossColor:"#ccc", //底環顏色
// $fillColor:"#ff5151", //頂環顏色
// $FontUnit:"°", //數字單位
// $Begin:0.7,//(0-1) //起始位置
// $FontSize:70 //文字大小
// });
使用方法,將js組件部分存爲後綴爲.js的文件,引入到HTML文檔中,按調用示例調用。