読者です 読者をやめる 読者になる 読者になる

みかづきブログ その3

3ヶ月つづけてみました。

CSSアニメーションでランダムっぽい動きを実装する

DEMO


SCSS

@import "compass/reset";

body {
    background: #311B92;
}

.circles {
    position: absolute;
    top: 0; bottom: 0;
    left: 0; right: 0;
    margin: auto;
    width: 300px; height: 300px;
    -x-animation: rotate 10s linear infinite;

    .circle {
        float: left;
        margin: 20px;
        border-radius: 50%;
        width: 10px; height: 10px;
        background: rgba(255, 255, 255, .2);
        box-shadow: rgba(255, 255, 255, .8) 0 0 10px;
        -webkit-filter: blur(1px);
    }
}


@for $i from 1 through 9 {
    .move#{$i} {
        animation: move#{$i} 10s linear infinite alternate;
    }
}

@keyframes rotate {
    0% {
        transform: rotateZ(0deg);
    }
    
    50% {
        transform: rotateZ(180deg);
    }
    
    100% {
         transform: rotateZ(360deg);   
    }
}

$moveRange: 20px;

@keyframes move1 {
  0% {
    transform: translate3d(0.2 * $moveRange, 0.4 * $moveRange, 0);
  }
  10% {
    transform: translate3d(-0.5 * $moveRange, 0.6 * $moveRange, 0);
  }
  20% {
    transform: translate3d(-0.6 * $moveRange, 0.2 * $moveRange, 0);
  }
  30% {
    transform: translate3d(0.3 * $moveRange, 0.3 * $moveRange, 0);
  }
  40% {
    transform: translate3d(-0.6 * $moveRange, 0.8 * $moveRange, 0);
  }
  50% {
    transform: translate3d(0 * $moveRange, 0.8 * $moveRange, 0);
  }
  60% {
    transform: translate3d(0.6 * $moveRange, -0.4 * $moveRange, 0);
  }
  70% {
    transform: translate3d(-0.1 * $moveRange, -0.3 * $moveRange, 0);
  }
  80% {
    transform: translate3d(0.3 * $moveRange, 0.7 * $moveRange, 0);
  }
  90% {
    transform: translate3d(-0.5 * $moveRange, -0.4 * $moveRange, 0);
  }
  100% {
    transform: translate3d(0.5 * $moveRange, -0.2 * $moveRange, 0);
  }
}
@keyframes move2 {
  0% {
    transform: translate3d(0.2 * $moveRange, -0.1 * $moveRange, 0);
  }
  10% {
    transform: translate3d(0.9 * $moveRange, -0.1 * $moveRange, 0);
  }
  20% {
    transform: translate3d(-0.6 * $moveRange, 0.4 * $moveRange, 0);
  }
  30% {
    transform: translate3d(0.8 * $moveRange, 0 * $moveRange, 0);
  }
  40% {
    transform: translate3d(-0.6 * $moveRange, -0.2 * $moveRange, 0);
  }
  50% {
    transform: translate3d(-0.4 * $moveRange, 0.3 * $moveRange, 0);
  }
  60% {
    transform: translate3d(0 * $moveRange, 0.2 * $moveRange, 0);
  }
  70% {
    transform: translate3d(0.6 * $moveRange, 0.7 * $moveRange, 0);
  }
  80% {
    transform: translate3d(0 * $moveRange, -0.7 * $moveRange, 0);
  }
  90% {
    transform: translate3d(0 * $moveRange, -0.1 * $moveRange, 0);
  }
  100% {
    transform: translate3d(0.8 * $moveRange, 0.3 * $moveRange, 0);
  }
}
@keyframes move3 {
  0% {
    transform: translate3d(0.8 * $moveRange, 0.6 * $moveRange, 0);
  }
  10% {
    transform: translate3d(-0.1 * $moveRange, 0.8 * $moveRange, 0);
  }
  20% {
    transform: translate3d(-0.7 * $moveRange, 0.4 * $moveRange, 0);
  }
  30% {
    transform: translate3d(0.9 * $moveRange, -0.2 * $moveRange, 0);
  }
  40% {
    transform: translate3d(0.2 * $moveRange, -0.6 * $moveRange, 0);
  }
  50% {
    transform: translate3d(0.7 * $moveRange, -0.5 * $moveRange, 0);
  }
  60% {
    transform: translate3d(-0.6 * $moveRange, 0.5 * $moveRange, 0);
  }
  70% {
    transform: translate3d(-0.7 * $moveRange, 0.9 * $moveRange, 0);
  }
  80% {
    transform: translate3d(0.6 * $moveRange, 0.1 * $moveRange, 0);
  }
  90% {
    transform: translate3d(-0.4 * $moveRange, -0.1 * $moveRange, 0);
  }
  100% {
    transform: translate3d(-0.8 * $moveRange, -0.9 * $moveRange, 0);
  }
}
@keyframes move4 {
  0% {
    transform: translate3d(0.9 * $moveRange, -0.3 * $moveRange, 0);
  }
  10% {
    transform: translate3d(0.3 * $moveRange, 0.9 * $moveRange, 0);
  }
  20% {
    transform: translate3d(0.7 * $moveRange, 0.6 * $moveRange, 0);
  }
  30% {
    transform: translate3d(0.1 * $moveRange, -0.7 * $moveRange, 0);
  }
  40% {
    transform: translate3d(0.4 * $moveRange, 0.9 * $moveRange, 0);
  }
  50% {
    transform: translate3d(-0.3 * $moveRange, 0 * $moveRange, 0);
  }
  60% {
    transform: translate3d(0.7 * $moveRange, -0.9 * $moveRange, 0);
  }
  70% {
    transform: translate3d(-0.8 * $moveRange, 0 * $moveRange, 0);
  }
  80% {
    transform: translate3d(0.1 * $moveRange, 0.9 * $moveRange, 0);
  }
  90% {
    transform: translate3d(-0.6 * $moveRange, 0.2 * $moveRange, 0);
  }
  100% {
    transform: translate3d(0.1 * $moveRange, -0.8 * $moveRange, 0);
  }
}
@keyframes move5 {
  0% {
    transform: translate3d(0.6 * $moveRange, 0.9 * $moveRange, 0);
  }
  10% {
    transform: translate3d(0 * $moveRange, 0.8 * $moveRange, 0);
  }
  20% {
    transform: translate3d(0.3 * $moveRange, 0.6 * $moveRange, 0);
  }
  30% {
    transform: translate3d(-0.9 * $moveRange, 0.9 * $moveRange, 0);
  }
  40% {
    transform: translate3d(-0.6 * $moveRange, 0.9 * $moveRange, 0);
  }
  50% {
    transform: translate3d(-0.4 * $moveRange, 0.8 * $moveRange, 0);
  }
  60% {
    transform: translate3d(-0.2 * $moveRange, 0.2 * $moveRange, 0);
  }
  70% {
    transform: translate3d(0.4 * $moveRange, 0.2 * $moveRange, 0);
  }
  80% {
    transform: translate3d(0.3 * $moveRange, 0.6 * $moveRange, 0);
  }
  90% {
    transform: translate3d(0.2 * $moveRange, 0.3 * $moveRange, 0);
  }
  100% {
    transform: translate3d(-0.3 * $moveRange, -0.8 * $moveRange, 0);
  }
}
@keyframes move6 {
  0% {
    transform: translate3d(-0.6 * $moveRange, -0.6 * $moveRange, 0);
  }
  10% {
    transform: translate3d(-0.7 * $moveRange, -0.7 * $moveRange, 0);
  }
  20% {
    transform: translate3d(0.5 * $moveRange, -0.2 * $moveRange, 0);
  }
  30% {
    transform: translate3d(-0.2 * $moveRange, 0.5 * $moveRange, 0);
  }
  40% {
    transform: translate3d(-0.9 * $moveRange, -0.1 * $moveRange, 0);
  }
  50% {
    transform: translate3d(0.1 * $moveRange, 0.6 * $moveRange, 0);
  }
  60% {
    transform: translate3d(0.3 * $moveRange, 0.5 * $moveRange, 0);
  }
  70% {
    transform: translate3d(0.2 * $moveRange, -0.8 * $moveRange, 0);
  }
  80% {
    transform: translate3d(0 * $moveRange, -0.2 * $moveRange, 0);
  }
  90% {
    transform: translate3d(0 * $moveRange, -0.5 * $moveRange, 0);
  }
  100% {
    transform: translate3d(-0.5 * $moveRange, -0.7 * $moveRange, 0);
  }
}
@keyframes move7 {
  0% {
    transform: translate3d(0.2 * $moveRange, 0 * $moveRange, 0);
  }
  10% {
    transform: translate3d(0.7 * $moveRange, -0.1 * $moveRange, 0);
  }
  20% {
    transform: translate3d(-0.1 * $moveRange, 0.9 * $moveRange, 0);
  }
  30% {
    transform: translate3d(0.4 * $moveRange, -0.9 * $moveRange, 0);
  }
  40% {
    transform: translate3d(-0.6 * $moveRange, -0.2 * $moveRange, 0);
  }
  50% {
    transform: translate3d(-0.7 * $moveRange, 0.5 * $moveRange, 0);
  }
  60% {
    transform: translate3d(-0.7 * $moveRange, 0.5 * $moveRange, 0);
  }
  70% {
    transform: translate3d(-0.2 * $moveRange, -0.4 * $moveRange, 0);
  }
  80% {
    transform: translate3d(0.2 * $moveRange, -0.9 * $moveRange, 0);
  }
  90% {
    transform: translate3d(0.4 * $moveRange, 0.8 * $moveRange, 0);
  }
  100% {
    transform: translate3d(0.3 * $moveRange, 0.9 * $moveRange, 0);
  }
}
@keyframes move8 {
  0% {
    transform: translate3d(-0.1 * $moveRange, -0.7 * $moveRange, 0);
  }
  10% {
    transform: translate3d(-0.5 * $moveRange, -0.4 * $moveRange, 0);
  }
  20% {
    transform: translate3d(-0.2 * $moveRange, 0.7 * $moveRange, 0);
  }
  30% {
    transform: translate3d(-0.5 * $moveRange, -0.2 * $moveRange, 0);
  }
  40% {
    transform: translate3d(0.2 * $moveRange, 0.7 * $moveRange, 0);
  }
  50% {
    transform: translate3d(-0.3 * $moveRange, 0.5 * $moveRange, 0);
  }
  60% {
    transform: translate3d(0.5 * $moveRange, -0.6 * $moveRange, 0);
  }
  70% {
    transform: translate3d(-0.7 * $moveRange, -0.9 * $moveRange, 0);
  }
  80% {
    transform: translate3d(0.4 * $moveRange, 0.9 * $moveRange, 0);
  }
  90% {
    transform: translate3d(0.9 * $moveRange, 0.6 * $moveRange, 0);
  }
  100% {
    transform: translate3d(0 * $moveRange, -0.7 * $moveRange, 0);
  }
}
@keyframes move9 {
  0% {
    transform: translate3d(0.5 * $moveRange, -0.5 * $moveRange, 0);
  }
  10% {
    transform: translate3d(0.5 * $moveRange, -0.3 * $moveRange, 0);
  }
  20% {
    transform: translate3d(0.9 * $moveRange, 0.3 * $moveRange, 0);
  }
  30% {
    transform: translate3d(-0.4 * $moveRange, 0.7 * $moveRange, 0);
  }
  40% {
    transform: translate3d(-0.8 * $moveRange, -0.1 * $moveRange, 0);
  }
  50% {
    transform: translate3d(-0.8 * $moveRange, 0.4 * $moveRange, 0);
  }
  60% {
    transform: translate3d(-0.3 * $moveRange, -0.9 * $moveRange, 0);
  }
  70% {
    transform: translate3d(0.1 * $moveRange, -0.6 * $moveRange, 0);
  }
  80% {
    transform: translate3d(-0.8 * $moveRange, 0.4 * $moveRange, 0);
  }
  90% {
    transform: translate3d(-0.8 * $moveRange, 0.2 * $moveRange, 0);
  }
  100% {
    transform: translate3d(-0.8 * $moveRange, -0.9 * $moveRange, 0);
  }
}

SCSSのランダムをつかっても良かったんですが、毎回差分が出てしまうのが嫌だったのでランダムっぽいkeyframeを書き出すJavaScriptもつくってみました。


JavaScript

(function(win, doc) {
    
    "use strict";
    
    var arr;
    
    doc.write("$moveRange: 20px;");
    br();
    br();
    for (var j = 1; j < 10; ++j) {
        document.write("@keyframes move" + j + " {");
        br();
        
        for (var i = 0; i <= 10; ++i) {
            arr = [((Math.random() - 0.5) * 20 | 0) / 10, ((Math.random() - 0.5) * 20 | 0) / 10];
            tab(); doc.write(i * 10 + "% {");
            br();
            tab(); tab(); doc.write("transform: translate3d(" + arr[0] + " * $moveRange, " + arr[1] + " * $moveRange, 0);");
            br();
            tab(); doc.write("}");
            br();
        }
        
        doc.write("}");
        br();
    }
    
    function br() {
        doc.write("<br />");
    }
    
    function tab() {
        doc.write("&nbsp;&nbsp;");
    }
    
})(this, document);

DEMO