JavascriptとCSSで簡単な文字アニメーション

#作るもの

文字列をバラバラにしてランダムに動かす。
画面をタップするごとに　整列⇔シャッフル　が切り替わる。
<p data-height="265" data-theme-id="0" data-slug-hash="OopVmP" data-default-tab="js,result" data-user="snst-lab" data-pen-title="Shuffle Strings" class="codepen">See the Pen <a href="https://codepen.io/snst-lab/pen/OopVmP/">Shuffle Strings</a> by snst.lab (<a href="https://codepen.io/snst-lab">@snst-lab</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


#テストページ

Github Pages( https://snst-lab.github.io/shuffling/public/?text=九蓮宝燈 )に設置。URLのtextクエリで指定された任意の文字「xxx」からアニメーションを生成する。

```console
https://snst-lab.github.io/shuffling/public/?text=xxx
```


#Javascipt
```javascript
const rand = (min, max) => Math.floor(Math.random() * (max - min + 1) + min);

const shuffle = {
  QUERY:[],
  DEFAULT_STRINGS:'十三不塔',

  main : function(){
    shuffle.parseQuery('text');
    shuffle.init(shuffle.QUERY);
    shuffle.changeAction(shuffle.QUERY);

    var align = true;
    var interval = setInterval(function(){
        shuffle.changeAction(shuffle.QUERY);
    },2000);
    align = false;

    $('body').on('click',function(){
      if(align){
        shuffle.changeAction(shuffle.QUERY);
        interval = setInterval(function(){
            shuffle.changeAction(shuffle.QUERY);
        },2000);
        align = false;
      }
      else{
        shuffle.endAction(shuffle.QUERY);
        clearInterval(interval);
        align = true;
      }
    });
  },

  parseQuery:function(variable){
    var query = window.location.search.substring(1);
    var vars = query.split("&");
    var queryExist = false;
    for (var i=0;i<vars.length;i++) {
    var pair = vars[i].split("=");
    if (pair[0] == variable) {
        queryExist = true;
        shuffle.QUERY = decodeURIComponent( pair[1]).split(''); 
    }
    }
    if(!queryExist){
        shuffle.QUERY = this.DEFAULT_STRINGS.split('');
    }
  },

  init:function(query){
    var fontsize = 0.8 *screen.width / query.length;
    for (var i = 0; i < query.length; i++) {
        $('body').append($('<div>').text(query[i]).addClass('char').css({'font-size':fontsize}));
    }
  },
  
  changeAction : function(query){
    $('.char').each(function(){
        var fontsize =  0.8 *screen.width / 5 * rand(0.2,3);
        shuffle.rotate(this, rand(500,3000),rand(-1,1));
        $(this).animate({'top':rand(-50,50) +'vh','left':rand(-50,50) +'vw','font-size':fontsize},1800);
    });
  },

  endAction : function(query){
    var fontsize = 0.8 *screen.width / query.length;
    $('.char').each(function(i){
        shuffle.rotateEnd(this, rand(500,3000),rand(-1,2));
        $(this).animate({'top':'0','left':'0','font-size':fontsize},1000);
    });      
  },

  rotate : function(dom,msec,direction){
    if(direction>0){
        $(dom).css({'animation': 'rotate-clock '+msec+'ms linear infinite both'});
    }
    else if(direction<0){
        $(dom).css({'animation': 'rotate-counterclock '+msec+'ms linear infinite both'});
    }
    else{
        $(dom).css({'animation': 'none'});
    }
  },

  rotateEnd : function(dom,msec,direction){
    if(direction>0){
        $(dom).css({'animation': 'rotate-clock '+msec+'ms linear both'});
    }
    else if(direction<0){
        $(dom).css({'animation': 'rotate-counterclock '+msec+'ms linear both'});
    }
    else{
        $(dom).css({'animation': 'none'});
    }
  },
};

window.onload = function(){
    shuffle.main();
}
```

#CSS
```css
html,body {
    background: white;
    width:100vw;
    padding:0;
    position:relative;
    overflow: hidden; 
}
.char{
    float:left;
    position:relative;
    text-shadow: 0 10px 10px rgba(0, 0, 0, 0.5);
}
@keyframes rotate-clock {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
@keyframes rotate-counterclock {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(-360deg);
  }
}
```