如何反转此SCSS动画?

时间:2019-06-06 19:26:47

标签: html css sass

这是一个实际上创建录制按钮的代码。当您单击按钮时,内部的圆圈变为正方形。如果您再次单击正方形,则这次将再次旋转而没有任何动画。

我对SCSS几乎一无所知,我需要一些帮助来修改此代码。

我如何动画将正方形恢复为圆形?

首先是codepen

这是代码:

HTML

.container
  input(type="checkbox" id="btn")
  label(for="btn")
  .time
    .h_m
    .s_ms

SCSS

@import url(https://fonts.googleapis.com/css?family=Fjalla+One);

$bg: #000;
$red: rgb(232, 4, 21);
$white: #fff;
$grey: rgb(162, 162, 162);
$cont-size: 170px;
$outer-size: $cont-size - 40;
$inner-size: $outer-size - 30;
$border-size: 6px;
$sec: 1s;
$bezier: cubic-bezier(.4, -.9, .9, 1);

@mixin animation($name) {
    @-webkit-keyframes #{$name} {@content;}
    @-moz-keyframes #{$name} {@content;}
    @-o-keyframes #{$name} {@content;}
    @keyframes #{$name} {@content;}
}

@mixin animation-use($name, $time, $easing) {
    -webkit-animation: $name $time infinite $easing;
    -moz-animation: $name $time infinite $easing;
    -o-animation: $name $time infinite $easing;
    animation: $name $time infinite $easing;
}

@mixin animate($val, $colon) {
    @include animation(to_ + $val) {
        @for $i from 1 to $val {
            #{100/$val*$i}% {
                @if ($i < 10) {
                    content: $colon + '0' + $i;
                } @else {
                    content: $colon + '' + $i;
                }
            }
        } 
    }
}

@mixin pseudo($content) {
    position: relative;
    content: $content;
}

@mixin center($val) {
    position: absolute;
    left: 50%;
    top: 50%;
    width: $val;
    height: $val;
    margin: -$val/2 0 -$val/2;
}

@mixin delay($time) {
    -webkit-animation-delay: $time;
    animation-delay: $time;
}

@mixin once() {
    -webkit-animation-iteration-count: 1;
    animation-iteration-count: 1;
    -webkit-animation-fill-mode: forwards;
    animation-fill-mode: forwards;
}

@include animate(24, '');
@include animate(60, ':');
@include animate(100, ':');

@include animation(time) {
    to {
        top: 100%;
        opacity: 1;
    }
}

@include animation(stop) {
    70% {
        border-radius: 6px;
        @include center($inner-size - 40);
    } 100% {
        border-radius: 6px;
        @include center($inner-size - 36);
    }
}

body {
    overflow: hidden;
    background: $bg;

    .container {
        @include center($cont-size);

        #btn {
            display: none;

            & + label:before {
                @include center($outer-size);
                content: '';
                -webkit-transform: translate(-$border-size, -$border-size);
                -ms-transform: translate(-$border-size, -$border-size);
                transform: translate(-$border-size, -$border-size);
                border-radius: 50%;
                border: $border-size solid $white;
                cursor: pointer;
            }

            & + label:after {
                @include center($inner-size);
                content: '';
                border-radius: $inner-size/2;
                background: $red;
                cursor: pointer;
            }

            &:checked {
                & + label:after {
                    @include animation-use(stop, 0.5*$sec, $bezier);
                    @include once();
                }

                & ~ .time {
                    @include animation-use(time, 0.3*$sec, linear);
                    @include once();
                    animation-delay: 0.3*$sec;
                }

                & ~ .time .h_m:after {
                    @include animation-use(to_24, 86400*$sec, linear);
                    @include delay(1800*$sec);
                }

                & ~ .time .h_m:before {
                    @include animation-use(to_60, 3600*$sec, linear);
                    @include delay(30*$sec);
                }

                & ~ .time .s_ms:before {
                    @include animation-use(to_60, 60*$sec, linear);
                    @include delay(.5*$sec);
                }

                & ~ .time .s_ms:after {
                    @include animation-use(to_100, $sec, linear);
                }
            }
        }

        .time {
            position: absolute;
            width: 100%;
            top: 110%;
            opacity: 0;

            & > * {
                display: inline-block;
                width: 50%;
                margin: -2px;
                color: $grey;
                font-family: 'Fjalla One', sans-serif; 
                font-size: 1.3em;
            }

            .h_m:after {
                float: right;
                @include pseudo('00');
            }

            .h_m:before {
                float: right;
                @include pseudo(':00');
            }

            .s_ms:before {
                float: left;
                @include pseudo(':00');
            }

            .s_ms:after {
                float: left;
                @include pseudo(':00');
            }
        }
    }
}

1 个答案:

答案 0 :(得分:4)

SCSS只是编写CSS的一种更快的方法。通过单击CSS窗格中的向下箭头并选择查看已编译的CSS,可以在Codepen中获得“已处理”的CSS。但是,在这种情况下,SCSS主要用于时间码显示,而不是按钮动画。


以下是该示例中所做操作的简化版本(使用纯CSS)。

基本上,有一个复选框,如果选中,则圆圈变为正方形。如果不是,它将返回为圆形的第一个状态。

这是使用:checked来确定输入是否被“选择”,并在这种情况下将adjacent sibling设置为跨度以具有不同的border-radiusCSS Transition用于在两种状态之间建立动画。

label {
  display:block;
  margin: 50px;
  cursor:pointer;
  padding: 10px;
  width: 50px;
  height: 50px;
  border: 1px solid #dadada;
  border-radius: 50%;
}

span {
  display:block;
  height: 100%;
  background-color:red;
  transition: all 0.5s cubic-bezier(.4, -.9, .9, 1);
}

input {
  display:none;
}

input + span {
  /* normal is a circle */
  border-radius: 50%;
}

input:checked + span {
  /* when the input is selected change to square */
  border-radius: 20%;
}
<label>
   <input type="checkbox" />
   <span></span>
</label>


编辑(带有关键帧动画)。

我分叉并修改了codepen,以查看是否可以使此复选框轻松使用。但正如预期的那样,state并未与复选框保持在一起,而是会跳转。


这是codepen的另一个分支,它使用了我上面提到的过渡技术,确实可以正常工作。