从‘相信前端能做一切’到‘连这个都做不了么’
4711705568245_.pic.jpg帮助阅读本文主要文章是为了实现仪表盘功能,前后过了4种方案,每篇方案从逻辑、代码、效果、问题四个方面出发。最后个人总结。同时非常非常希望有大佬能够提供「一个」方案,个人实际想不到实现方案了
需求h5页面中,做一个环形仪表盘(如下图),需要一个从0%到实际人口的增长跨越动效
前提使用矫正原生 Html、css、js 实现,不打算借助第三方语言插件。
初步方案将UI图片作为背景,上面放一个白色div作为遮罩,再利用css3将白色div旋转,从而达到解决效果。
代码如下:style
.light-strip {
width: 500px;
height:500px;
border: 1px solid #efefef;
background-image: url('Frame 29@3x.png');
float: right;
background-size: 100% 100%;
}
.light-strip-top {
margin-top: 0%;
width: 500px;
height: 250px;
background: #fff;
transform-origin: bottom center;
/* transform: rotate 5s ; */
rotate: 0deg;
transition: all 2s ease-in-out;
}
/style
body onload="load()"
div class="light-strip"
div class="light-strip-top"
/div
/div
/body
script
function load() {
setTimeout(() = {
document.querySelectorAll('.light-strip-top')[0].setAttribute('style', "rotate: 180deg")
}, 1000)
}
/script
效果如下:屏幕截图2024-01-29 13.50.58.gif出现问题:由于仪表盘整体大于180度,所以白色div,在最开始覆盖全部仪表盘,那么旋转一定角度后一定会覆盖UI图。
进化计划根据上面出现的问题,想到与UI沟通将仪表盘改成180度效果(解决不了问题,就把问题解决掉),该方案由于改变了原型之后会导致UI过于丑,就没有进行深度测试。
超进化计划根据上面两个方案的结合,考虑将方案1中的白色div换成一张指针图片,利用css3旋转追针,达到过渡效果,但这个方案也改变了UI效果。
代码如下: style
.light-strip {
width: 500px;
height:500px;
border: 1px solid #efefef;
background-image: url('Frame 29@3x.png');
/* background-color: #fff; */
float: right;
background-size: 100% 100%;
}
.light-strip-top {
margin-top: 50%;
width: 49%;
height: 4px;
background: red;
transform-origin: center right;
/* transform: rotate 5s ; */
rotate: -35deg;
transition: all 2s ease-in-out;
}
/style
body onload="load()"
div class="light-strip"
div class="light-strip-top"
/div
/div
/body
script
function load() {
setTimeout(() = {
document.querySelectorAll('.light-strip-top')[0].setAttribute('style', "rotate: 90deg")
}, 1000)
}
/script
效果如下:屏幕截图2024-01-29 15.44.31.gif现在:此时大脑停滞了,在我的前端知识基础上,想达不到能够完美实现UI效果的方案了。于是和同事探讨一下,了解element-plus中的进度条有类似的效果,于是打算看一下发现新大陆又开始尝试svg实现。
究极进化计划利用svg,做一个带白色的背景圆环A,再做一个携带突变背景色的进展圆环B,利用进展圆环的偏移值、显示长度、断口长度配合css3过渡实现封装效果。
代码如下: style
body {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
background-color: #f5f5f5;
}
.dashboard {
position: relative;
width: 200px;
height: 200px;
background-size: 100% 100%;
}
.circle-background {
fill: none; /* 不填充 */
stroke: #fff; /* 圆环的颜色 */
stroke-width: 10; /* 圆环的宽度 */
stroke-dasharray: 200, 52; /* 圆环断开部分的长度,总长度为周长 */
stroke-dashoffset: 163;
stroke-linecap: round;
border-radius: 10;
transition: all 1s; /* 过渡效果时间 */
}
.circle-progress {
fill: none; /* 不填充 */
stroke: url(#gradient); /* 圆环的颜色 */
stroke-width: 10; /* 圆环的宽度 */
stroke-dasharray: 252, 0; /* 圆环断开部分的长度,总长度为周长 */
stroke-dashoffset: 163;
stroke-linecap: round; /* 圆滑断点 */
transition: all 1s; /* 过渡效果时间 */
}
.percentage {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 24px;
color: #3498db;
}
/style
/head
body
svg class="dashboard" viewBox="0 0 100 100"
!-- 定义渐变色 --
defs
linearGradient id="gradient" gradientUnits="userSpaceOnUse" x1="50" y1="0" x2="50" y2="100%"
stop offset="0%" style="stop-color: rgba(111, 232, 191, 1)" /
stop offset="33%" style="stop-color: rgba(255, 175, 19, 1)" /
stop offset="70%" style="stop-color: rgba(222, 19, 80, 1)" /
stop offset="100%" style="stop-color: rgba(133, 14, 205, 1)" /
/linearGradient
/defs
!-- 背景圆环 --
circle class="circle-background" cx="50" cy="50" r="40"/circle
!-- 进度圆环 --
circle class="circle-progress" cx="50" cy="50" r="40"/circle
/svg
!-- 进度百分比显示 --
div class="percentage" id="percentage"/div
script
function setProgress(percentage) {
const circleProgress = document.querySelector('.circle-progress');
const circleBackground = document.querySelector('.circle-background');
const percentageText = document.getElementById('percentage');
const circumference = 2 * Math.PI * 40; // 圆的周长
const circumNewLength = (percentage / 100) * (circumference - 52);
const dashOffset = 163 - circumNewLength;
// 设置进度圆环的样式
circleBackground.style.strokeDashoffset = dashOffset;
circleBackground.style.strokeDasharray = `${200 - circumNewLength}, ${ 52 + circumNewLength }`
circleProgress.style.strokeDasharray = `${circumNewLength}, ${ circumference - circumNewLength }`
// 更新百分比文本
percentageText.textContent = `${percentage}%`;
}
// 设置初始进度为0%
setProgress(0);
// 模拟过渡效果,从0%到50%
setTimeout(() = {
setProgress(50);
}, 1000); // 过渡时间为1秒,你可以根据需要调整这个值
/script
效果如下:屏幕截图2024-01-29 15.46.35.gif问题:基本实现了,但是还有一个问题是,突变色是两点之间的线性突变,无法实现圆环的顺时针突变。
总结简单前置不是万能的????????个人认为这个需求还是能够实现的「希望有大佬能出个方案」加油,继续搞点击关注公众号,”技术干货”及时达!
阅读原文
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。 项目经理在线