zookeeper python接口实例详解
195
2023-05-31
canvas实现环形进度条效果
昨下午睡着了,晚上打开手机才发现朋友给我发了一个QQ消息,问我这个怎么实现?
这里就选canvas来简单写一下 先上代码,然后在说一说需要注意的点:
body{
background-color:#000;
text-align: center;
}
.canvas1{
margin-top: 100px;
display: inline-block;
background-color: #FFF;
}
/*
需求:环形、一周分为10个片段,根据进度去走的一个状态
技术选型:canvas (挑战加熟悉)
思路:
01 首先中间的文字部分不用说,使用canvas的画文字。
02 圆形是个规则图形,那么为了避免画不规则图形,我们可以用圆和矩形来重叠出效果。
a. 大的灰色背景圆
b. 小一圈的白色背景圆
c. 以同心圆的圆心为圆心,小圆为半径为半径复制画10个小的矩形
*/
//初始化动画变量
var requestAnimationFrame = window.requestAnimationFrame || window.msRequestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame;
var cancelAnimationFrame = window.cancelAnimationFrame || window.msCancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelRequestAnimationFrame;
//初始化当前进度数
var curPercentCount = 0;
//获取canvas对象,设置画布大小
var oC = document.querySelector('#circle_process');
oC.width = 300;
oC.height = 300;
//获取canvas执行上下文
var ctx = oC.getContext('2d');
//定义小矩形的个数
var miniRectCount = 10;
//定义圆心位置
var cirCenter = {
x:oC.width/2,
y:oC.height/2
};
//定义小矩形的大小rectSize
var rectSize = {
width:0,
height:0
};
//圆对象构造函数
function Circle(center,radius){
this.center = center;
this.radius = radius;
}
//小矩形对象构造函数
function MiniRect(length,width){
this.length = length;
this.width = width;
}
//角度转换成弧度的函数
function d2a(angleInt){
return angleInt*Math.PI / 180;
}
//百分比转换角度函数(这里减90因为arc0度是从右侧开始的)
function percentTurn(percentFloat){
return percentFloat * 360 / 100 - 90;
}
//画当前百分比扇形的方法
function drawFanForPercent(percentFloat){
ctx.beginPath();
ctx.moveTo(cirCenter.x,cirCenter.y);
ctx.lineTo(oC.width/2,(oC.height-baseCircle.radius*2)/2);
ctx.arc(cirCenter.x,cirCenter.y,baseCircle.radius,d2a(-90),d2a(percentTurn(percentFloat)));
ctx.fillStyle = 'aqua';
ctx.fill();
ctx.closePath();
}
//画圆的函数
function drawArc(center,radius,start,end,type,color){
start = start || 0;
end = end || 360;
ctx.beginPath();
ctx.arc(center.x,center.y,radius,d2a(start),d2a(end));
ctx.fillStyle = color;
ctx.strokeStyle = color;
if(!!type){
(type === 'fill') && ctx.fill();
(type === 'stroke') && ctx.stroke();
}
ctx.closePath();
}
//画文字的函数
function drawPercentText(text,percentInt){
ctx.beginPath();
ctx.fillStyle = 'aqua';
ctx.font="italic small-caps bold 40px Calibri";
ctx.textAlign = 'center';
ctx.fillText(text,cirCenter.x,cirCenter.y-18,100);
ctx.closePath();
ctx.beginPath();
ctx.fillStyle = 'aqua';
ctx.font="italic small-caps bold 60px Calibri";
ctx.textAlign = 'center';
ctx.fillText(percentInt+'%',cirCenter.x,cirCenter.y+40,100);
ctx.closePath();
}
//画小方块的方法
function drawMiniRect(startPoint,width,height,axisPoint,rotateAngle){
/*
ctx.beginPath();
//平移,画出第一个
ctx.save();
ctx.translate(startPoint.x,startPoint.y);
ctx.fillStyle = '#FFF';
ctx.fillRect(0,0,rectSize.width,rectSize.height);
ctx.restore();
ctx.closePath();
//这种先平移画出在旋转的思路是错的,画之后就不能转了
ctx.save();
ctx.translate(axisPoint.x,axisPoint.y);
ctx.rotate(rotateAngle);
ctx.restore();
*/
ctx.save();
ctx.translate(axisPoint.x,axisPoint.y); /*画布平移到圆的中心*/
ctx.rotate(d2a(rotateAngle)); /*旋转*/
/*画*/
ctx.beginPath();
ctx.fillStyle = '#FFF';
ctx.fillRect(startPoint.x,startPoint.y,rectSize.width,rectSize.height);
ctx.closePath();
ctx.restore();
}
//画整体
function draw(curPercent){
//底部灰色圆
drawArc(baseCircle.center,baseCircle.radius,null,null,'fill','#CCC');
//进度扇形
drawFanForPercent(curPercent);
//内部白色遮挡圆
drawArc(innerCircle.center,innerCircle.radius,null,null,'fill','#FFF');
//画文字
drawPercentText('当前进度',curPercent);
//十个小的矩形
for(var i=0; i drawMiniRect(startPoint,rectSize.width,rectSize.height,cirCenter,i*360/miniRectCount); } } //实例化底圆和内圆 var baseCircle = new Circle(cirCenter,130); var innerCircle = new Circle(cirCenter,100); //设置rectSize数值 rectSize.width = 15; rectSize.height = baseCircle.radius - innerCircle.radius + 5; //设置第一个小矩形的起始点 (这里有误差) // var startPoint = { // x: oC.width /2 - 7.5, http://// y: (oC.height - baseCircle.radius*2) / 2 // }; //由于平移到中心点之后画的位置是在画布外的,所以重新定义 var startPoint = { x:-7.5, y:-baseCircle.radius - 2 }; //这里开定时去显示当前是百分之几的进度 var raf = null; var percent = 0; function actProcess(percentFloat){ percentFloat = percentFloat || 100; percent = Math.round(percentFloat); console.log(percent); curPercentCount++; raf = requestAnimationFrame(function(){ actProcess(percentFloat); }); draw(curPercentCount); if(curPercentCount >= percent){ cancelAnimationFrame(raf); return; } } actProcess(50); // cancelAnimationFrame(raf); //这里没搞懂为什么percent会加 ? //解: requestAnimationFrame中方法还是需要有参数,这里就用匿名函数回调的执行体去指定。 /* //setInterval的方式 function actProcess(percentFloat){ if(curPercentCount >= percentFloat){ clearInterval(timer); return; } curPercentCount++; draw(curPercentCount); } clearInterval(timer); var timer = setInterval(function(){ actProcess(50); },16.7); */ //直接画弧形的测试: //drawArc(innerCircle.center,innerCircle.radius,0,260,'fill','red'); /* 用到的技术点: 01 canvas平移 02 canvas画布状态保存于恢复 03 canvas旋转 04 canvas clearRect配合动画requestAnimationFrame 05 canvas写文字 */ 接下来说一些注意点和我写的过程中碰到的疑问: 疑问: 01 整体代码没有封装成一个组件,感兴趣的同学可以封装一下。 我这有时间也会封装。 02 画文字的时候只能单独画一行文字么? 怎样进行换行? 03 canvas怎样处理响应式? 注意点: 01 画布平移之后,画布上的点也会被平移,所以我在定义第一个小矩形的起始点的时候才会重新定义一个负值。 02 直接画弧形来控制进度不准确,因为arc会自动closePath(),最终形成这样的一个效果。 03 默认圆的0度起始位置是从3点钟方向开始的(见上图),那么想从12点钟位置开始走进度,需要减去90度的角度。 04 requestAnimationFrame的回调函数在有参数的情况下还是需要传参数的,需要借助匿名函数回调,在执行体里面去执行想要loop的函数内容(可传参数)。否者会出现注释中写道的pecent不规则增加的问题。 先就这样,之后可能会结合一个上传图片的小功能尝试把它封装成一个组件。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~