使用angularJS 编写一个自定义组件
用来表示使用进度百分比的canvas图形
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>AngularJS Directive LiquidFill Demo</title>
<script src="https://cdn.bootcss.com/angular.js/1.4.6/angular.min.js"></script>
</head>
<body ng-app="myApp">
<div ng-controller="demo">
<liquid-fill :value="{{value}}" title="{{title}}" :id="{{id}}"></liquid-fill>
</div>
<script>
const app = angular.module("myApp", []);
app.controller('demo', function($scope){
$scope.title = 'Bloke Cache命中率';
$scope.value = 50;
$scope.id = 'liquidFill';
});
app.directive('liquidFill', () => {
return {
scope: {
title: '@',
value: '@',
id: '@',
config: '@'
},
restrict : "AE",
template: '<canvas id="{{id}}"></canvas>',
controller: function($scope){
const defaultSize = 350;
const lineWidth = 1;
var config = {
width: defaultSize,
height: defaultSize,
lineWidth,
cc: defaultSize / 2, // 圆心(圆心的x和y轴坐标)
cr: ( defaultSize / 2 -32) * lineWidth, // 半径
sX: 0,
axisLength: defaultSize, // 轴长
waveWidth: 0.008, // 波浪宽度,数越小越宽
waveHeight: 6, // 波浪高度,数越大越高
speed: 0.09, // 波浪速度,数越大速度越快
xOffset: 0, // 波浪x偏移量
strokeStyle: '#1080d0',
};
var ctx;
var isDrawCircle = false;
let defaultValue = 10;
config = Object.assign(config, $scope.config || config);
let currentValue = $scope.value;
const drawCircle = () => {
ctx.beginPath();
ctx.strokeStyle = config.strokeStyle;
ctx.arc(config.cc, config.cc, config.cr + 1, 0, 2 * Math.PI);
ctx.stroke();
ctx.beginPath();
ctx.arc(config.cc, config.cc, config.cr, 0, 2 * Math.PI);
ctx.clip();
isDrawCircle = true;
};
// y=Asin(ωx+φ)+k
const drawSin = (xOffset, color, waveHeight) => {
ctx.save();
const points = []; //用于存放绘制Sin曲线的点
ctx.beginPath();
for (let x = config.sX; x < config.sX + config.axisLength; x += 20 / config.axisLength) {
let y = Math.sin((-config.sX - x) * config.waveWidth + xOffset) * 0.8 + 0.1;
let dy = config.height * (1 - defaultValue / 100);
points.push([x, dy + y * waveHeight]);
ctx.lineTo(x, dy + y * waveHeight);
};
ctx.lineTo(config.axisLength, config.height);
ctx.lineTo(config.sX, config.height);
ctx.lineTo(points[0][0], points[0][1]);
ctx.fillStyle = color;
ctx.fill();
ctx.restore();
};
const render = () => {
ctx.clearRect(0, 0, config.width, config.height);
if (!isDrawCircle) drawCircle();
if (defaultValue <= ($scope.value < 10 ? 10 : $scope.value)) defaultValue += 1;
if (defaultValue > ($scope.value < 10 ? 10 : $scope.value)) defaultValue -= 1;
drawSin(config.xOffset + Math.PI * 0.7, 'rgba(28, 134, 209, 0.5)', 18);
drawSin(config.xOffset, '#1c86d1', 18);
drawText();
config.xOffset += config.speed;
requestAnimationFrame(render);
};
const drawText = () => {
ctx.save();
let size = 0.4 * config.cr;
ctx.font = size + 'px Microsoft Yahei';
ctx.textAlign = 'center';
ctx.fillStyle = "rgba(06, 85, 128, 0.5)";
ctx.fillText(~~$scope.value + '%', config.cc, config.cc + size);
ctx.font = 20 + 'px Microsoft Yahei';
ctx.fillStyle = "rgba(0, 0, 0, .5)";
ctx.fillText($scope.title, config.cc, config.cc - 80);
ctx.restore();
};
$scope.render = () => {
const canvas = document.getElementById($scope.id);
ctx = canvas.getContext('2d');
canvas.width = config.width;
canvas.height = config.height;
render();
};
},
link: function($scope,element,attr,controller){
setTimeout(() => {
$scope.render();
}, 0);
},
replace: false,
transclude: true // 指令可嵌套其他指令
};
});
</script>
</body>
</html>
网友评论