最近有人要我帮做一个字段拖拽编辑功能的页面,由于页面上可编辑的字段有些多,那么如何突出显示当前正在被编辑的字段而不影响其编辑样式呢?于是我就脑洞大开地想到了边框环绕。
1、用原始虚线边框来实现边框环绕
css原始边框不支持环绕,于是我就想到了利用虚线边框加动画的方式来实现边框环绕。主要思路是被环绕的元素里面放四个额外的子元素,利用他们来做边框。
代码:
<!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>Document</title>
<style>
div {
position: relative;
margin: 100px auto;
width: 200px;
height: 200px;
overflow: hidden;
}
div>span {
position: absolute;
}
span:nth-of-type(1) {
width: 200%;
height: 1px;
top: 0;
right: 0;
box-sizing: border-box;
border-top: 1px dashed #333;
animation: flash1 8s infinite linear;
}
span:nth-of-type(2) {
width: 200%;
left: 0;
height: 1px;
bottom: 0;
box-sizing: border-box;
border-top: 1px dashed #333;
animation: flash2 8s infinite linear;
}
span:nth-of-type(3) {
height: 200%;
width: 1px;
left: 0;
top: 0;
box-sizing: border-box;
border-right: 1px dashed #333;
animation: flash3 8s infinite linear;
}
span:nth-of-type(4) {
height: 200%;
bottom: 0;
width: 1px;
right: 0;
box-sizing: border-box;
border-right: 1px dashed #000;
animation: flash4 8s infinite linear;
}
@keyframes flash1 {
0% {
right: 0;
}
100% {
right: -100%;
}
}
@keyframes flash2 {
0% {
left: 0;
}
100% {
left: -100%;
}
}
@keyframes flash3 {
0% {
top: 0;
}
100% {
top: -100%;
}
}
@keyframes flash4 {
0% {
bottom: 0;
}
100% {
bottom: -100%;
}
}
</style>
</head>
<body>
<div>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
</body>
</html>
然而这种方式的效果并不好,于是我想到了用canvas来画虚线作为边框。
2、用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>Document</title>
<style>
div {
position: relative;
margin: 100px auto;
width: 200px;
height: 200px;
overflow: hidden;
}
div>canvas {
position: absolute;
}
canvas:nth-of-type(1) {
top: 0;
right: 0;
animation: flash1 12s infinite linear;
}
canvas:nth-of-type(2) {
right: 0;
bottom: 0;
animation: flash2 12s infinite linear;
}
canvas:nth-of-type(3) {
left: 0;
bottom: 0;
animation: flash3 12s infinite linear;
}
canvas:nth-of-type(4) {
top: 0;
left: 0;
animation: flash4 12s infinite linear;
}
@keyframes flash1 {
0% {
right: 0;
}
100% {
right: -100%;
}
}
@keyframes flash2 {
0% {
bottom: 0;
}
100% {
bottom: -100%;
}
}
@keyframes flash3 {
0% {
left: 0;
}
100% {
left: -100%;
}
}
@keyframes flash4 {
0% {
top: 0;
}
100% {
top: -100%;
}
}
</style>
</head>
<body>
<div id="fa">666
<canvas id="canvas1" height="1" ></canvas>
<canvas id="canvas2" width="1" ></canvas>
<canvas id="canvas3" height="1" ></canvas>
<canvas id="canvas4" width="1"></canvas>
</div>
<script>
Array.from(document.querySelectorAll('canvas')).forEach((_, i) => {
i % 2 === 0 ? _.width = 400 : _.height = 400;
let ctx = _.getContext('2d');
ctx.strokeStyle = '#000';
ctx.setLineDash([5, 5]);
ctx.beginPath();
ctx.moveTo(0, 0);
i % 2 === 0 ? ctx.lineTo(_.width, 0) : ctx.lineTo(0, _.height);
ctx.stroke();
});
</script>
</body>
</html>
注意为了确保四条边移动的速度一致,四条边的动画移动距离和执行动画的时间的比例要相等,不懂的话全部写成一样就行了。