emsApplication/applications/WebConfigure/web/js/lib/circle.process.js

355 lines
13 KiB
JavaScript
Raw Permalink Normal View History

2024-05-24 12:19:45 +08:00
/**
* Created by JianJia.Zhou<jianjia.zhou@longmaster.com.cn> on 2017/12/18.
*/
var CircleProcess = (function (window) {
// 版本
var version = "0.0.1";
var CircleProcess = function (selector, options) {
return new CircleProcess.fn.init(selector, options);
};
CircleProcess.fn = CircleProcess.prototype = {
circleProcess: version,
context: null,
option: {},
interVal: 0,
constructor: CircleProcess,
init: function (selector, options) {
// 如果没有传递实体对象 抛出异常
if (typeof selector === "undefined") {
throw new Error("Unable to get canvas object");
}
// 获取canvas对象
this.context = selector.getContext("2d");
// 获取配置
this.option = this._option();
// 根据canvas获取初始配置
this._getCanvasOption(selector);
// 获取全局配置
this._getOption();
if (typeof options === 'object') {
this._setOption(options);
this._getOption();
}
this.interVal = setInterval(function () {
this.run();
}.bind(this), 20);
},
/**
* 执行
*/
run: function () {
var option = this.option;
var process = option.percent;//从0到刻度option.process; 立即到刻度option.percent;
if (option.percent > 100 || option.percent < 0) {
clearInterval(this.interVal);
alert("Percentage out of range,The correct range of 1 - 100");
throw new Error("Percentage out of range,The correct range of 1 - 100");
}
if (process >= option.percent) {
process = option.percent;
clearInterval(this.interVal);
}
this._clear();
// 设置背景圆是否显示
if (option.backgroundCircle.show) {
this._backgroundCircle();
}
// 设置梯度是否显示
if (option.percentCircle.show) {
this._percentCircle(process);
}
// 设置起始圆点是否显示
if (option.startSmallCircle.show) {
this._smallCircle(option.startSmallCircle.radius, option.startSmallCircle.color, 0);
}
// 设置截止圆点是否显示
if (option.endSmallCircle.show) {
this._smallCircle(option.endSmallCircle.borderRadius, option.endSmallCircle.borderColor, process);
this._smallCircle(option.endSmallCircle.radius, option.endSmallCircle.color, process);
}
// 设置文字是否显示
if (option.processText.show) {
this._showProcess(process);
}
this._speed(option.percentCircle.speed);
},
/**
* 清除上一次画板
* @private
*/
_clear: function () {
var option = this.option;
this.context.clearRect(0, 0, option.backgroundCircle.roundX * 2, option.backgroundCircle.roundY * 2);
},
/**
* 背景圆环
* @private
*/
_backgroundCircle: function () {
var option = this.option;
// 设置线宽
this.context.lineWidth = option.lineWidth;
this.context.beginPath();
// 绘制圆环
this.context.arc(option.backgroundCircle.roundX,
option.backgroundCircle.roundY,
option.radius,
option.backgroundCircle.startAngle,
option.backgroundCircle.endAngle
);
this.context.strokeStyle = option.backgroundCircle.color;
this.context.stroke();
this.context.closePath();
},
/**
* 前置圆环
*
* @param {int|float} process
* @private
*/
_percentCircle: function (process) {
var option = this.option;
this.context.beginPath();
this.context.lineWidth = option.lineWidth;
this.context.arc(option.backgroundCircle.roundX,
option.backgroundCircle.roundY,
option.radius,
option.backgroundCircle.startAngle,
option.backgroundCircle.startAngle + process / 100 * option.cMultiple, // Math.PI * 180 / 180 * 2
false
);
if (option.percentCircle.gradientColorShow) {
this.context.strokeStyle = this._linearGradient();
} else {
this.context.strokeStyle = option.percentCircle.color;
}
this.context.lineCap = 'round';
this.context.stroke();
this.context.closePath();
},
/**
* 梯度颜色
*
* @returns {CanvasGradient}
* @private
*/
_linearGradient: function () {
var option = this.option;
// createLinearGradient x起点, y起点, x终点, y终点
var xStart = option.backgroundCircle.roundX - option.radius - this.option.lineWidth;
var xEnd = option.backgroundCircle.roundX + option.radius + this.option.lineWidth;
var yStart = option.backgroundCircle.roundY;
var yEnd = option.backgroundCircle.roundY;
var linGrad = this.context.createLinearGradient(xStart, yStart, xEnd, yEnd);
linGrad.addColorStop(0.0, 'rgba(255,0,0,0.1)');
linGrad.addColorStop(0.2, 'rgba(255,0,0,0.3)');
linGrad.addColorStop(0.4, 'rgba(255,0,0,0.5)');
linGrad.addColorStop(0.6, 'rgba(255,0,0,0.7)');
linGrad.addColorStop(0.8, 'rgba(255,0,0,0.9)');
linGrad.addColorStop(1.0, 'rgba(255,0,0,1)');
return linGrad;
},
/**
* 开始|结束圆点
* @param {int|float} radius
* @param {int|float} process
* @param {string} color
* @private
*/
_smallCircle: function (radius, color, process) {
var option = this.option;
var cx = Math.cos(2 * Math.PI / 360 * (option.angle + process * option.sMultiple / 100)) * option.radius + option.backgroundCircle.roundX;
var cy = Math.sin(2 * Math.PI / 360 * (option.angle + process * option.sMultiple / 100)) * option.radius + option.backgroundCircle.roundY;
this.context.beginPath();
this.context.arc(cx, cy, radius, 0, Math.PI * 2);
this.context.lineWidth = 1;
this.context.fillStyle = color;
this.context.fill();
},
/**
* 显示文字进度
* @param {int} process
* @private
*/
_showProcess: function (process) {
var decimal = 0;
var option = this.option;
var num = option.percent.toString();
// 如果当前数字是小数,那么需要保留小数 最大两位
if (/\./.test(num) && num.split(".")[1].length > 0) {
decimal = num.split(".")[1].length < 2 ? 1 : 2;
}
this.context.font = option.processText.fontSize + 'px April';
this.context.textAlign = option.processText.textAlign;
this.context.textBaseline = option.processText.textBaseline;
this.context.fillStyle = option.processText.color;
this.context.fillText(parseFloat(process).toFixed(decimal) + '%', option.backgroundCircle.roundX, option.backgroundCircle.roundY);
},
_showProcessFollow: function () {
},
/**
* 梯度速度
*
* @param mode
* @private
*/
_speed: function (mode) {
var option = this.option;
if (mode === "gradient") {
if (option.process / option.percent > 0.90) {
option.process += 0.30;
} else if (option.process / option.percent > 0.80) {
this.option.process += 0.55;
} else if (option.process / option.percent > 0.70) {
option.process += 0.75;
} else {
option.process += 1.0;
}
} else if (mode === "normal") {
option.process += 1.0;
} else if (mode === "fast") {
option.process += 2.5;
}
},
/**
* 初始化时获取canvas对象参数
*
* @param {object} selector
* @private
*/
_getCanvasOption: function (selector) {
this._extend(this.option, {
"backgroundCircle": {
"roundX": selector.width / 2,
"roundY": selector.height / 2,
"startAngle": Math.PI / 180 * 180,
"endAngle": Math.PI / 180 * 180 * 2
}
});
},
/**
* 合并对象
*
* @param {object} o
* @param {object} n
* @private
*/
_extend: function (o, n) {
for (var p in n) {
if (typeof n[p] === "object") {
this._extend(o[p], n[p]);
} else if (n.hasOwnProperty(p) && (!o.hasOwnProperty(p))) {
o[p] = n[p];
} else if (n.hasOwnProperty(p) && o.hasOwnProperty(p)) {
o[p] = n[p];
}
}
},
/**
*
* @returns {*}
* @private
*/
_getOption: function () {
var option = this.option;
option.angle = 180;
option.cMultiple = option.backgroundCircle.startAngle;
option.sMultiple = 180;
if (option.size === "complete") {
option.angle = 120;
option.cMultiple = option.backgroundCircle.startAngle * 2;
option.sMultiple = 360;
this._extend(this.option, {
"backgroundCircle": {
"startAngle": Math.PI / 180 * 120,
"endAngle": Math.PI / 180 * 120 * 4
}
});
} else if (option.size === "incomplete") {
option.angle = 120;
option.cMultiple = Math.PI * 5 / 3;
option.sMultiple = 300;
this._extend(this.option, {
"backgroundCircle": {
"startAngle": Math.PI / 180 * 120,
"endAngle": Math.PI / 180 * 420
}
});
}
},
_setOption: function (option) {
this._extend(this.option, option);
},
/**
* 初始参数配置
*
* @returns {{size: string, lineWidth: number, radius: number, position: string, percent: number, process: number, backgroundCircle: {show: boolean, color: string, roundX: number, roundY: number, startAngle: number, endAngle: number}, percentCircle: {show: boolean, color: string, speed: string}, startSmallCircle: {show: boolean, color: string, radius: number}, endSmallCircle: {show: boolean, color: string, radius: number}, gradient: {color: string}, processText: {show: boolean, fontSize: number, color: string, follow: boolean, textAlign: string, textBaseline: string}}}
* @private
*/
_option: function () {
return {
"size": "half", //complete,half,incomplete or todo-percent
"lineWidth": 5,
"radius": 100,
"percent": 80,
"process": 0.00,
"backgroundCircle": {
"show": true,
"color": "#eee",
"roundX": 0,
"roundY": 0,
"startAngle": 0,
"endAngle": 0
},
"percentCircle": {
"show": true,
"color": "#f00",
"speed": "gradient",//gradient normal fast
"gradientColorShow": false,
"gradientColor": "rgba(255.0.0,0.1)"
},
"startSmallCircle": {
"show": false,
"color": "#06a8f3",
"radius": 5
},
"endSmallCircle": {
"show": false,
"color": "#00f8bb",
"radius": 5
},
"gradient": {
"color": "rgba(255,0,0,0.1)",// todo 梯度颜色
"size": 4
},
"processText": {
"show": true,
"fontSize": 20,
"color": "#ccc",
"follow": false,//todo 是否跟随渐变而改变颜色
"textAlign": "center",
"textBaseline": "alphabetic"
}
};
}
};
CircleProcess.fn.init.prototype = CircleProcess.fn;
return CircleProcess;
})();