前言
项目中要求实现一个证件扫描识别页,未提供UI资源,遂自力更生。
SVG实现
实现遮罩
绘制一个铺满全屏的矩形遮罩层起手:
<svg class="ocr-overlay" width="100%" height="100%">
<rect
width="100%"
height="100%"
fill="rgba(0,0,0,0.7)"
/>
</svg>
<style>
.ocr-overlay {
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 100%;
}
</style>
实现识别框
前面已经绘制了一个全屏覆盖的遮罩层,现需挖空中间区域来实现视觉引导(识别区域),可以用svg遮罩实现这一点,遮罩中:白色=保留内容,黑色=透明,因此,扫描框区域用黑色填充,实现透明穿透:
<svg class="ocr-overlay" width="100%" height="100%">
<!-- 定义遮罩 -->
<defs>
<mask id="scanMask">
<rect width="100%" height="100%" fill="white" />
<rect
x="5%"
rx="5"
ry="5"
y="30%"
width="90%"
height="30%"
fill="black"
/>
</mask>
</defs>
<!-- 应用遮罩 -->
<rect
width="100%"
height="100%"
fill="rgba(0,0,0,0.7)"
mask="url(#scanMask)"
/>
</svg>
效果如下:
添加边框及呼吸动画
为扫描区域添加边框和文字说明:
<svg class="ocr-overlay" width="100%" height="100%">
...
<!-- 边框 -->
<rect
x="5%"
y="30%"
width="90%"
height="30%"
fill="none"
stroke="#1989fa"
stroke-width="2"
rx="5"
ry="5"
>
<animate
attributeName="stroke-opacity"
values="0.3;1;0.3"
dur="2.5s"
repeatCount="indefinite"
/>
<!-- <animate attributeName="stroke-width" values="0.5;1.5;0.5" dur="2.5s" repeatCount="indefinite"/> -->
</rect>
<text fill="#fff" x="50%" y="65%" class="text-16" text-anchor="middle">
请将证件置于扫描框中,停留5s
</text>
</svg>
边框动画说明:为描边透明度stroke-opacity(也可选择描边宽度stroke-width)绘制一个不限次数的呼吸动画,类似CSS Animation,效果如下:
添加扫描线及扫描动画
简单实现一个上下移动的扫描动效:
<svg class="ocr-overlay" width="100%" height="100%">
...
<!-- 扫描线 -->
<line
x1="7%"
y1="32%"
x2="93%"
y2="32%"
stroke="#1989fa"
stroke-width="1"
>
<animate
attributeName="y1"
values="32%;58%;32%"
dur="2.5s"
repeatCount="indefinite"
/>
<animate
attributeName="y2"
values="32%;58%;32%"
dur="2.5s"
repeatCount="indefinite"
/>
</line>
</svg>
扫描线动画说明:由于是垂直方向移动的扫描线,因此分别对扫描线的y1和y2添加动画,效果如下:
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<svg class="ocr-overlay" width="100%" height="100%">
<!-- 定义遮罩 -->
<defs>
<mask id="scanMask">
<rect width="100%" height="100%" fill="white" />
<rect
x="5%"
rx="5"
ry="5"
y="30%"
width="90%"
height="30%"
fill="black"
/>
</mask>
</defs>
<!-- 应用遮罩 -->
<rect
width="100%"
height="100%"
fill="rgba(0,0,0,0.7)"
mask="url(#scanMask)"
/>
<!-- 边框 -->
<rect
x="5%"
y="30%"
width="90%"
height="30%"
fill="none"
stroke="#1989fa"
stroke-width="2"
rx="5"
ry="5"
>
<animate
attributeName="stroke-opacity"
values="0.3;1;0.3"
dur="2.5s"
repeatCount="indefinite"
/>
<!-- <animate attributeName="stroke-width" values="0.5;1.5;0.5" dur="2.5s" repeatCount="indefinite"/> -->
</rect>
<text fill="#fff" x="50%" y="65%" class="text-16" text-anchor="middle">
请将证件置于扫描框中,停留5s
</text>
<!-- 扫描线 -->
<line
x1="7%"
y1="32%"
x2="93%"
y2="32%"
stroke="#1989fa"
stroke-width="1"
>
<animate
attributeName="y1"
values="32%;58%;32%"
dur="2.5s"
repeatCount="indefinite"
/>
<animate
attributeName="y2"
values="32%;58%;32%"
dur="2.5s"
repeatCount="indefinite"
/>
</line>
</svg>
<style>
* {
margin: unset;
padding: unset;
box-sizing: border-box;
}
.ocr-overlay {
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 100%;
}
</style>
</body>
</html>
总结
效果比较简单,但记录一下,总的来说,svg总是会在你觉得某功能用css不好实现或兼容时,给你带来一点小小的矢量震撼!