注册
web

不用 js实现渐变、虚线、跑马灯、可伸缩边框

最近遇到个需求,要求实现一个渐变色的边框,并且是虚线的,同时还要有动画。


有的朋友可能看到这里就要开骂了,估计要提刀找设计和产品怼回去了。


但其实我是可以理解的,因为这种花哨的边框想要用在一个类似于魔法框的地方,框住一个地方,然后交给 ai 处理。这样的交互设计可以很好的体现科技感,并且我也想尝试一下,就接了这个需求。


单看几个条件都好处理,css 已经支持了 border-image。


再不济用伪元素遮盖一下,clip-path镂空也可以


甚至我看到很多网站是直接放个视频就完了


但是我这次的需求最重要的是虚线,这就不好处理了。因为设置了边框为虚线后会忽略掉 border-image。


其实这个问题看起来很难,做起来也确实难。我搜到了张鑫旭大佬多年前的文章,就是专门讲这件事的


http://www.zhangxinxu.com/wordpress/2…


看完之后我受益匪浅,虽然我不能用他的方案(因为他的方案中,虚线是假的,样式会和浏览器有差异)


我尝试了很多方案,mask、clip-path、背景图等等,效果都不好。


绝望之际我想到了一个救星svg


div 做不到的事情,我 svg 来做。svg 可以设置 stroke,可以设置 fill,可以设置渐变色,渐变色还可以做动画。简直就是完美的符合需求


先写个空标签上去


<style>
.rect{
width: 100px;
height: 100px;
}
</style>
<div class='rect'>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
</svg>
</div>

因为我需要 svg 尺寸跟随父容器变化,所以就不写 viewBox 了,直接设置宽高 100%。同时在里面画一个矩形,也是宽高 100%。


<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width='100%' height='100%'>
<rect width="100%" height="100%"></rect>
</svg>

现在长这样
image.png


接下来给 rect 设置填充和描边,边框宽度为 4px


<rect 
fill="transparent"
stroke="red"
stroke-width="4"
width="100%"
height="100%"
>
</rect>

image.png


接下来我们给border 设置为渐变色,需要在 svg 中定义一个渐变,svg 定义渐变色还是很方便的,都是现成标签和属性直接就可以通过 id 取到。


<svg>
...
<defs>
<linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="lightcoral" />
<stop offset="50%" stop-color="lightblue" />
<stop offset="100%" stop-color="lightgreen" />
</linearGradient>
</defs>
</svg>

接下来给红色的 stroke 换成渐变色


<rect 
fill="transparent"
stroke="url(#gradient)"
stroke-width="4"
width="100%"
height="100%"
>
</rect>

image.png


接下通过 stroke-dasharray 来设置虚线边框


mdn 上关于 dasharry的介绍在这里 developer.mozilla.org/zh-CN/docs/…


image.png


我给 rect 设置 dasharray 为 5,5


<rect 
fill="transparent"
stroke="url(#gradient)"
stroke-dasharray="5,5"
stroke-width="4"
width="100%"
height="100%"
>
</rect>

image.png


这样渐变虚线边框就成了


接下来处理动画效果


动画分两种



  1. 线动,背景色不动
  2. 线不动,背景色动

这两种效果我都实现了


首先展示线动,背景色不动的情况


这种情况只要能想办法让虚线产生偏移就可以,于是我搜了一下,这不巧了吗,正好有个属性叫 stroke-dashoffset


image.png


于是就可以通过 css 动画来修改偏移量


<style>
.dashmove {
animation: dashmove 1s linear infinite;
}

@keyframes dashmove {
0% {
stroke-dashoffset: 0;
}
100% {
stroke-dashoffset: 10;
}
}
</style>
<rect class="dashmove" .... ></rect>

ezgif-1bb6c3542c4ad7.gif


大功告成


接下来处理第二种情况,线不动,背景动


这种情况就更简单了,因为 svg 本身就支持动画


我们只需要在渐变色中增加一个animateTransform标签


<linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="0%">
...
<animateTransform
attributeName="gradientTransform"
type="rotat
from="
0 0.5 0.5"
to="360 0.5 0.5"
dur="1s"
repeatCount="indefinite"
/>

</linearGradient>

ezgif-6b83b81feb0420.gif


接下来看一下拖拽的效果,这个很重要,因为我们不希望随着容器比例变化,会让边框宽度也变化。


给容器元素加上这三个属性,这个 div 就变成了可拖拽缩放的


.rect{
// ...
resize: both;
position: relative;
overflow: auto;
}

看下效果


ezgif-58de40b814d0bb.gif


完美 🎉🎉🎉


在这里查看完整在线 demo stackblitz.com/edit/stackb…


作者:阿古达木
来源:juejin.cn/post/7502127751572406323

0 个评论

要回复文章请先登录注册