wrapBox:最外层盒子,背景色为进度条的颜色
leftBox/rightBox:半宽等长 左/右浮动的盒子,背景色为灰色
roundMask:居中的盒子 用来遮盖leftBox和rightBox
基本原理:
当进度小于180度,rightBox以左中点为原点进行旋转
当进度大于180度,rightBox位置不变 背景变成灰色,leftBox以右中点为原点进行旋转,旋转度数=进度-180
问题:rpx在转换成px时有误差 导致小圆不在中心位置 border-radius计算不准确
解决办法:宽高、位置用百分比,border-radius根据windowWidth自己算
代码:
<template> <view class="wrapBox" style="background:{{color}};width:{{circleWidth}}rpx;height:{{circleWidth}}rpx;"> <view class="leftBox" style="width:50%;height:100%;border-radius:{{radius}}rpx 0 0 {{radius}}rpx;transform:rotateZ({{deg>180?deg-180:0}}deg)"></view> <view class="rightBox" style="width:50%;height:100%;border-radius:0 {{radius}}rpx {{radius}}rpx 0;background:{{deg>180?color:'#F0F0F0'}};transform: rotateZ({{deg>180?0:deg}}deg)"></view> <view class="roundMask" style="width:{{maskWidth}}%;height:{{maskWidth}}%;background:{{backgroundColor}}"></view> </view> </template> <script> import wepy from 'wepy' export default class Progress extends wepy.component { props = { color: { type: String, default: "#FFD600" }, deg: { type: Number, default: 0 }, circleWidth: { type: Number, default: 34 }, progressWidth: { type: Number, default: 10 }, backgroundColor: { type: String, default: '#fff' } } computed = { maskWidth() { return (1 - this.progressWidth / this.circleWidth) * 100 }, maskRadius() { return (1 - this.progressWidth / this.circleWidth) * 50 }, radius() {
//windowWidth在app.wpy的onShow中获取 return this.$root.$parent.globalData.windowWidth * this.circleWidth / 375 } } } </script> <style lang="less"> .wrapBox { position: absolute; border-radius: 50%; .leftBox, .rightBox { overflow: hidden; float: left; background: #F0F0F0; } .leftBox { transform-origin: right center; } .rightBox { transform-origin: left center; } .roundMask { position: absolute; top: 50%; left: 50%; border-radius:50%; transform: translate(-50%, -50%); } } </style>