概要
- コンソールに寿司を流す。
- 画面にも流したい! → 流しました。
元のコード
const STR_LEN = 80
const SUSHI_INTERVAL =10
let cnt = 0;
function sushiDraw(){
const sa = new Array(STR_LEN).fill(' ')
for(let i = 0; i < STR_LEN; i += SUSHI_INTERVAL){
const sushiIndex = sa.length - 1 - (cnt + i) % sa.length
sa.splice(sushiIndex, 1, '🍣')
}
console.clear()
console.log(sa.join(''))
cnt++
}
setInterval(sushiDraw, 1000)
Class構文を使ってみた
ロジックも見直した。結果、コードは長くなった。
- 引数で寿司の数、間隔、流れる速度を変更できるようにした。
- 処理のたびに毎回配列を1から作って結合していたので、それをやめる。
- 最初に一度だけ寿司文字列を生成する。
- その後は処理が行われるたびに最初の1文字を削って後ろに継ぎ足していく方式。
- 寿司の絵文字がサロゲートペアという問題にぶち当たり、単純に1文字削るだけでは上手く行かなかったので、例外処理を追加。
- 表示処理は単純に文字列の入ったインスタンス変数を参照するだけにした。
class RevolvingSushi {
constructor(len = 80, interval = 10, delay = 1000) {
this.STR_LEN = len;
this.SUSHI_INTERVAL = interval;
this.DELAY = delay;
this.sushi = this.make(this.STR_LEN, this.SUSHI_INTERVAL);
this.display();
this.flow();
}
make(len, interval){
const sushi = ' '.repeat(interval - 1) + '🍣',
count = Math.floor(len / interval),
space = ' '.repeat(len % interval);
return sushi.repeat(count) + space;
}
slide(){
let str = this.sushi.charAt(0);
if (str !== ' '){
this.sushi = this.sushi.slice(2);
str = '🍣'
} else {
this.sushi = this.sushi.slice(1);
}
this.sushi += str;
}
clear(){
console.clear();
}
display(){
console.log(this.sushi);
}
flow(){
setTimeout(() => {
this.slide();
this.clear();
this.display();
this.flow();
}, this.DELAY);
}
}
// 実行
new RevolvingSushi();
HTML上に寿司を流す
- JavaScript上での処理はテキスト生成と指定した要素への挿入のみ。
- 動きはCSSでつける。
JS
class RevolvingSushiText {
constructor(selector = '.sushi', len = 80, interval = 10, delay = 1000) {
this.STR_LEN = len;
this.SUSHI_INTERVAL = interval;
this.DELAY = delay;
this.space = ' ';
this.afterSpace = this.space.repeat(len % interval);
this.sushi = this.make(this.STR_LEN, this.SUSHI_INTERVAL);
this.target = document.querySelector(selector);
this.set();
}
make(len, interval) {
const sushi = this.space.repeat(interval - 1) + '🍣',
count = Math.floor(len / interval);
return sushi.repeat(count);
}
set() {
this.target.innerHTML = `<div class="sushi-outer"><div class="sushi-inner">${this.sushi}</div><div class="sushi-inner">${this.sushi + this.afterSpace}</div></div>`
const width = document.querySelector('.sushi-inner').offsetWidth;
document.querySelector('.sushi-outer').style.width = width * 2 + 'px';
}
}
new RevolvingSushiText('.sushi', 100, 5);
HTML
<p class="sushi"></p>
CSS
.sushi {
overflow: hidden;
}
.sushi-outer {
display: block;
white-space: nowrap;
}
.sushi-inner {
float: left;
animation: slide 15s infinite linear;
}
@keyframes slide {
0% {
transform: translateX(0%);
}
100% {
transform: translateX(-100%);
}
}