螺旋正方形旋转渐显

212 阅读1分钟

需求

实现正方形盒子嵌套,首次加载时候,先显示小盒子(渐变、从小到大) -> 然后依次显示外层盒子

  • vue + scss

思考

  • 我用dom实现的,没有用canvas,( canvas的一些动效不熟练
  • dom -> 添加需要的dom盒子个数
<div class="wrapper">
    <div v-for="i in 28" :key="i" class="rotate" :class="'rotate-'+i">
    </div>
</div>
  • scss -> 让盒子中心点整齐划一,最外层盒子最大,给一个固定的缩小比率
$boxNum: 29;
$sizeTemp: $maxW;

.rotate {
    position: absolute;
    @for $i from 1 to $boxNum{
        $sizeTemp: $sizeTemp * 0.94; // 盒子大小

        &-#{$i}{
            width: $sizeTemp;
            height: $sizeTemp;
            border: 1px solid black;
            animation-fill-mode: backwards !important;
            transform: rotate(#{($i - 1)*2}deg); // 角度
        }
    }
}
    
  • DOM渲染完成的时候,再动画显示盒子元素
mounted() {
    this.$nextTick(() => {
        let wrapperDom = document.getElementsByClassName('wrapper');
        wrapperDom[0].classList.add('show-wrapper');
    })
},

<!--scss-->
&.show-wrapper {
    visibility: visible;
    .rotate {
        @for $i from 1 to $boxNum{
            $delay: $delay - 0.1; // 延迟时间
            &-#{$i}{
                @if $i==28{
                    animation: scaleAnimation28 0.8s ease;
                    animation-delay: 0;
                    -webkit-animation-delay: 0;
                }@else{
                    animation: scaleAnimation#{$i} .1s ease;
                    animation-delay: #{$delay}s;
                    -webkit-animation-delay: #{$delay}s;
                }
            }
        }
    }
}
  • 注意点:因为每个正方形盒子dom的延迟时间和动画旋转角度都不同,则需要定义和正方形盒子同等个数的动画进行匹配
@for $i from 1 to $boxNum{
    @if $i==28{
        <!--最内层动画单独定制-->
        @keyframes scaleAnimation28 {
            0% {
                transform: scale(0) rotate(0);
                opacity: 0;
            }
            100% {
                transform: scale(1) rotate(#{($i - 1)*2}deg);
                opacity: 1;
            }
        }
    }@else {
        @keyframes scaleAnimation#{$i} {
            0% {
                opacity: 0;
                transform: scale(0.9) rotate(#{($i - 1) * 2 + 4}deg);
            }
            100% {
                opacity: 1;
                transform: scale(1) rotate(#{($i - 1)*2}deg);
            }
        }
    }
}

效果图

参考