LoginSignup
1
0

More than 5 years have passed since last update.

進捗・どう・です・か

Last updated at Posted at 2019-04-27

元ネタ:「進捗・どう・です・か」をランダムに表示し「進捗どうですか」が完成したら煽ってくるプログラムをES6で書いてみる

メッセージがリアルタイムに伸びていくようにしてみた。

  • TypeScript で書いたが、関数の引数と返値に型情報を追加しただけなので、「JavaScript は分かるけど TypeScript は分からない」という方でも(: string とか : number とかを無視していただければ)理解できるはず。
  • コンソール出力だと改行なしにはできなさそうなので、HTML に出力するようにした。
  • async/await で遅延処理を入れることで徐々にメッセージが伸びるようにした。
  • CodePen を埋め込んでみたが、一定時間経つと処理が止まってしまう(最後まで行かないことがある)ようだ。
const WORDS = Object.freeze(["進捗", "どう", "です", ""]);
const SEQUENCE_FINISH = "???";
const SHOUT = `_人人人人人人人_
>進捗どうですか<
 ̄Y^Y^Y^Y^Y^Y^Y ̄`;

const SEQUENCE_INTERVAL = 10;
const SHOUT_DELAY = 1500;

const SEQUENCE_CONTAINER_ID = "sequence_container";
const SHOUT_CONTAINER_ID = "shout_container";


(async () => {
    await appendWordSequenceAsync(
        WORDS, SEQUENCE_CONTAINER_ID, SEQUENCE_INTERVAL);
    appendText(SEQUENCE_CONTAINER_ID, SEQUENCE_FINISH);
    await timeoutAsync(SHOUT_DELAY);
    appendMultilineText(SHOUT_CONTAINER_ID, SHOUT);
})();


async function appendWordSequenceAsync(
    words: ReadonlyArray<string>,
    parentElementId: string,
    interval: number
): Promise<void> {
    let progress = 0;
    while (true) {
        const index = getRandomInt(0, words.length);

        const word = words[index];
        appendText(parentElementId, word);

        if (progress !== index) {
            progress = 0;
        }

        if (progress === index) {
            ++progress;
            if (progress >= words.length) {
                break;
            }
        }

        await timeoutAsync(interval);
    }
}

function appendMultilineText(
    parentElementId: string,
    text: string
): void {
    text.split("\n").forEach(line => {
        appendText(parentElementId, line);
        appendBr(parentElementId);
    });
}

function appendText(
    parentElementId: string,
    text: string
): void {
    const parent = ensureElement(parentElementId);
    const textNode = document.createTextNode(text);
    parent.appendChild(textNode);
}

function appendBr(parentElementId: string): void {
    const br = document.createElement("br");
    ensureElement(parentElementId).append(br);
}

function ensureElement(elementId: string): HTMLElement {
    const existing = document.getElementById(elementId);
    if (existing) { return existing; }

    const newElement = document.createElement("div");
    newElement.id = elementId;
    document.body.appendChild(newElement);
    return newElement;
}

function getRandomInt(
    rangeBegin: number,
    rangeEnd: number
): number {
    return rangeBegin
        + Math.floor(Math.random() * (rangeEnd - rangeBegin));
}

function timeoutAsync(delay: number): Promise<void> {
    return new Promise(resolve => 
        setTimeout(() => resolve(), delay)
    );
}

Playground · TypeScript

See the Pen 進捗どうですか??? by sdkei (@sdkei) on CodePen.

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0