分类
svg

数据大屏边框(1)续

第一次对数据大屏边框的尝试是对svg的基础运用。其中会造成各种问题导致无法在项目中实用。这次会在前一次的基础上做的一些优化。

数据大屏边框(1)

效果图

此次的优化项

1.动画

开头的动画采用smil(同步多媒体集成语言)动画的形式,每一个svg属性下都可以采用一个或多个smil动画。且由于同步的特性,一个动画的开始可以由另一个动画的结束为触发。第一个动画的开始采用了这一段代码。

<animate id="a1" attributeName="fill" restart="never" begin="indefinite" to="rgba(19,101,233,.4)" fill="freeze" dur="3s"></animate>
<script>
    document.addEventListener('click', function() {
        document.getElementById('a1').beginElement();
    })
</script>

而动画的效果是基于stroke,stroke-dasharray,stroke-dashoffset这三个属性。

 <path d="M 673 300 L 678 300 L 678 320 L 673 320 z" fill="transparent" stroke="rgb(14,80,191)" stroke-width="2"  stroke-dasharray="100,100" stroke-dashoffset="100" stroke-linejoin="round">
            <animate attributeName="stroke-dashoffset" dur="1s" to="0" begin="a2.end + 2.6" fill="freeze"></animate>
        </path>

以这段代码为例,首先这是一个小方块,它的初始状态里有stroke-dasharray=“100,100”,stroke-dasharray是将描边以虚线的形式展现,作用是100长度实线,100长度虚线,100长度实线,100长度虚线。。。显然,这个path组成的小方块并没有100那么长,但是没关系,只要比它实际的长度长就可以,这个实际的长度测算方式是在html页面中我们所能看到的长度,如果它被放大,那么实际的长度也会变大。而stroke-dashoffset的作用是偏移量,数值为正向左偏移。因此就变成了初始状态下,我们看不到东西的情况。

其次动画的状态也需要说明。attributeName=”stroke-dashoffset” – 动画改变的属性,fill=“freeze”-动画结束后以冻结的方式,不会回到初始状态。

2.适配各种大小

ui姐姐给出的设计稿是一张图片,因此每个元素的尺寸都是固定的,但是实际上我们的展示内容不可能与设计图的大小完全一致。所以需要加一些属性。

viewBox=“0 0 697 462”以x=0,y=0为基点,697为宽度,462为高度。

preserveAspectRatio=”none”,大小改变后的等比例收缩方式,none说明不按照等比例收缩

3.大小按等比例缩放后描边大小会跟着改变,但是不想让它改变

设置style属性

 path{
            vector-effect: non-scaling-stroke;
 }

(完)

分类
svg

数据大屏边框(1)

起因

通常,我们做一些数据大屏项目时会使用一些插件来完成特效的制作,比如DataV组件库提供了许多大屏的特效。但是这样ui就不能自由自在的创作了,为了解决此问题,参照着DataV的写法,试试能否实现ui的设计稿。

ui设计稿

ui sj 1024x654 - 数据大屏边框(1)
ui画的设计稿。

思路

  • 左上角有个小三角。
  • 外框是有path组成。
  • 右侧的小方块一个一个画吧。
  • 该边框形成一个特定的比例。
  • 看左侧和下侧还有光晕,是动画吧。

开搞

定义一个特定的比例
<svg
            class="ec-svg-container"
            width="697"
            height="462"
            viewBox="0 0 697 462"
            xmlns="http://www.w3.org/2000/svg"
    >...</svg>
左上角小三角
<path d="M 5 5 L 20 5 L 5 20 z"
              fill="transparent" stroke-linejoin="round" stroke="rgba(19,101,233)" stroke-width="2" />
外框
 <path d="M 30 5 L 323 5 L 351 17 L 548 17 L 554 5 L 641 5 L 662 28
             L 682 28 L 682 88 L 665 100 L 665 394 L 682 404 L 682 435
             L 670 455 L 5 455 L 5 30 z"
              fill="rgba(19,101,233,.4)" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round" />
右侧小方块和小线段
 <path d="M 673 102 L 678 102 L 678 122 L 673 122 z" fill="transparent" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 673 135 L 678 135 L 678 155 L 673 155 z" fill="transparent" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 673 168 L 678 168 L 678 188 L 673 188 z" fill="transparent" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 673 201 L 678 201 L 678 221 L 673 221 z" fill="transparent" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 673 234 L 678 234 L 678 254 L 673 254 z" fill="transparent" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 673 267 L 678 267 L 678 287 L 673 287 z" fill="transparent" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 673 300 L 678 300 L 678 320 L 673 320 z" fill="transparent" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 673 333 L 678 333 L 678 353 L 673 353 z" fill="transparent" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 673 366 L 678 366 L 678 386 L 673 386 z" fill="transparent" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <!--    右侧小线段-->
        <path d="M 680 92 L 680 101" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 680 123 L 680 134" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 680 156 L 680 167" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 680 189 L 680 200" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 680 222 L 680 233" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 680 255 L 680 266" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 680 288 L 680 299" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 680 321 L 680 332" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 680 354 L 680 365" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 680 387 L 680 400" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>

真是考验耐心,和初中的计算功底呢。

光晕动画
这个是比较难的点,需要好好说说。
  • 假设先画一个比较粗的,围绕着外框的光带。
  • 一个圆在光带中运动,而我们只能看到圆中的部分。
  • 我们看到的部分只有渐变的,咋办呢,那就在mask中加入径向渐变中间实心,外侧透明,这样就有光晕的效果啦。
  <defs>
<!--            第一个光晕的路径-->
            <path id="ec-border-box-path-1" d="M 30 5 L 323 5 L 351 17 L 548 17 L 554 5 L 641 5 L 662 28 L 682 28 L 682 88 L 665 100 L 665 394 L 682 404 L 682 435 L 670 455 L 5 455 L 5 30 L 30 5" fill="transparent"></path>
<!--            第二个光晕的路径-->
            <path id="ec-border-box-path-1-c1" d="M 665 394 L 682 404 L 682 435 L 670 455 L 5 455 L 5 30 L 30 5 L 323 5 L 351 17 L 548 17 L 554 5 L 641 5 L 662 28 L 682 28 L 682 88 L 665 100 Z" fill="transparent"></path>
<!--            定义径向渐变-->
            <radialGradient id="ec-border-box-r-1" cx="50%" cy="50%" r="50%">
                <stop offset="0%" stop-color="#fff" stop-opacity="1"/>
                <stop offset="100%" stop-color="#fff" stop-opacity="0"/>
            </radialGradient>
<!--            定义遮罩-->
            <mask id="ec-border-box-mask-1">
<!--                定义圆,fill使用了径向渐变-->
                <circle cx="0" cy="0" r="50" fill="url(#ec-border-box-r-1)">
<!--                    定义运动路径-->
                    <animateMotion dur="5s" rotate="auto" repeatCount="indefinite">
                        <mpath xlink:href="#ec-border-box-path-1"></mpath>
                    </animateMotion>
                </circle>
                <circle cx="0" cy="0" r="50" fill="url(#ec-border-box-r-1)">
                    <animateMotion dur="5s" rotate="auto" repeatCount="indefinite">
                        <mpath xlink:href="#ec-border-box-path-1-c1"></mpath>
                    </animateMotion>
                </circle>
            </mask>
        </defs>
<use stroke-width="5" xlink:href="#ec-border-box-path-1" mask="url(#ec-border-box-mask-1)" stroke="rgb(19,101,233)"></use>

总的代码

 <style>
        body{
            background-color:rgb(18,19,37)
        }
        .ec-box{
            position:relative;
            width: 500px;
            height: 400px;
        }
        .border-box-content{
            height: 100%;
        }
        .ec-svg-container{
            position:absolute;
            width: 100%;
            height: 100%;
            left: 0;
            top: 0;
        }
    </style>
<div class="ec-box">
    <svg
            class="ec-svg-container"
            width="697"
            height="462"
            viewBox="0 0 697 462"
            xmlns="http://www.w3.org/2000/svg"
    >
        <defs>
            <path id="ec-border-box-path-1" d="M 30 5 L 323 5 L 351 17 L 548 17 L 554 5 L 641 5 L 662 28 L 682 28 L 682 88 L 665 100 L 665 394 L 682 404 L 682 435 L 670 455 L 5 455 L 5 30 L 30 5" fill="transparent"></path>
            <path id="ec-border-box-path-1-c1" d="M 665 394 L 682 404 L 682 435 L 670 455 L 5 455 L 5 30 L 30 5 L 323 5 L 351 17 L 548 17 L 554 5 L 641 5 L 662 28 L 682 28 L 682 88 L 665 100 Z" fill="transparent"></path>
            <radialGradient id="ec-border-box-r-1" cx="50%" cy="50%" r="50%">
                <stop offset="0%" stop-color="#fff" stop-opacity="1"/>
                <stop offset="100%" stop-color="#fff" stop-opacity="0"/>
            </radialGradient>
            <mask id="ec-border-box-mask-1">
                <circle cx="0" cy="0" r="50" fill="url(#ec-border-box-r-1)">
                    <animateMotion dur="5s" rotate="auto" repeatCount="indefinite">
                        <mpath xlink:href="#ec-border-box-path-1"></mpath>
                    </animateMotion>
                </circle>
                <circle cx="0" cy="0" r="50" fill="url(#ec-border-box-r-1)">
                    <animateMotion dur="5s" rotate="auto" repeatCount="indefinite">
                        <mpath xlink:href="#ec-border-box-path-1-c1"></mpath>
                    </animateMotion>
                </circle>
            </mask>
        </defs>
        <use stroke-width="5" xlink:href="#ec-border-box-path-1" mask="url(#ec-border-box-mask-1)" stroke="rgb(19,101,233)"></use>
        <!--    三角-->
        <path d="M 5 5 L 20 5 L 5 20 z"
              fill="transparent" stroke-linejoin="round" stroke="rgba(19,101,233)" stroke-width="2" />
        <!--            外框-->
        <path d="M 30 5 L 323 5 L 351 17 L 548 17 L 554 5 L 641 5 L 662 28
             L 682 28 L 682 88 L 665 100 L 665 394 L 682 404 L 682 435
             L 670 455 L 5 455 L 5 30 z"
              fill="rgba(19,101,233,.4)" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round" />
        <!--            上方的线-->
        <path d="M 352 6 L 540 6" stroke="rgb(14,80,191)" stroke-width="3" stroke-linejoin="round"/>
        <!--    右侧小方块-->
        <path d="M 673 102 L 678 102 L 678 122 L 673 122 z" fill="transparent" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 673 135 L 678 135 L 678 155 L 673 155 z" fill="transparent" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 673 168 L 678 168 L 678 188 L 673 188 z" fill="transparent" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 673 201 L 678 201 L 678 221 L 673 221 z" fill="transparent" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 673 234 L 678 234 L 678 254 L 673 254 z" fill="transparent" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 673 267 L 678 267 L 678 287 L 673 287 z" fill="transparent" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 673 300 L 678 300 L 678 320 L 673 320 z" fill="transparent" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 673 333 L 678 333 L 678 353 L 673 353 z" fill="transparent" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 673 366 L 678 366 L 678 386 L 673 386 z" fill="transparent" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <!--    右侧小线段-->
        <path d="M 680 92 L 680 101" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 680 123 L 680 134" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 680 156 L 680 167" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 680 189 L 680 200" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 680 222 L 680 233" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 680 255 L 680 266" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 680 288 L 680 299" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 680 321 L 680 332" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 680 354 L 680 365" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
        <path d="M 680 387 L 680 400" stroke="rgb(14,80,191)" stroke-width="2" stroke-linejoin="round"/>
    </svg>
</div>

最终效果

Rec 0004 - 数据大屏边框(1)
由于是截的gif,比较不流畅。