JavaScript」タグアーカイブ

flex-box vender prefix

本日やっと HTML5 Test Page の書き換えが終わりました。
やっと古いページの一掃が終わったぞい。
どう書き換えするか散々迷ったけど ES6 で全部動的作成することに。

CSS3 TestPage – L’Isola di Niente

思い付きでヘッダは上部にマウスカーソルを動かすとヒョッコリ出すように。
もちろん comipoli Web 版で使うため、linux 版はフルスクリーンで出しているもん。
やはり同じにしたいじゃないの。

こうやって色々作ってみると本当に今の Web はスタンドアロンなアプリと変わらない。
普通のアプリみたいに作れるのは楽しい、去年までこんなこと考えられなかったのに。
ES6 様々です。

ところで実際に書き換えてみて解ったんだけど。

.flex {
    /*display: -webkit-flex;
    display: -moz-flex;
    display: -ms-flex;*/
    display: flex;
    flex-wrap: wrap;
    /*-webkit-flex-wrap: wrap;*/
    text-align: left;
    margin: 5px 0px;
}

2018.08 の現在 flex-box は vender prefix はもういらないのね。
根暗用 OS は持っていないので -ms-* は知らないけど、どうでもいいよね!

JavaScript MessageBox

ガンガンONLINE 等で漫画を読み進めると最後に HTML なダイアログが出る。
これと同じようなダイアログを作りたい。

サイズは alert や GtkMessageDialog のように文字列の流さに合わせたい。
閉じるボタンも当然付いている状態で出したい。

CSS で縦横センタリング! 要素を画面中央に『ドン!!』と表示する方法 | phiary

検索で一番上にでてくる有名な手段だけど width, height 指定必須。

console.log(div.style.width);

は空文字だ。

不定な流さの文字列タグの横幅を得る手段が見つからない、困った。
別の手段に頭を切り換える必要がありそうだ。

position:absolute で中央に配置するやり方 | YouKnow.jp
CSSで要素を上下や左右から中央寄せする7つの方法 | 株式会社グランフェアズ

transform:translate というのがいいみたいだ。
両方 vender prefix が付いているけど 2018.08 な現在はどうなのかな。
早速試してみよう。

messageBox(id) {
    let div = document.createElement("div");
    div.style.backgroundColor = "#EEE";
    div.style.position = "absolute";
    div.style.display = "block";
    div.style.zIndex = "101";
    // Centering
    div.style.left = "50%";
    div.style.top = "50%";
    div.style.transform = "translate(-50%,-50%)";
    // Border
    div.style.border = "1px solid #7c93b2";
    div.style.borderRadius = "3pt";
    div.style.boxShadow = "5px 5px";
    //
    let paragraph = document.createElement("p");
    paragraph.textContent = document.getElementById(id).value;
    paragraph.style.textAlign = "center";
    //
    let close = document.createElement("p");
    close.textContent = "Close";
    close.style.textAlign = "center";
    close.style.backgroundColor = "#CCC";
    close.style.border = "1px solid #7c93b2";
    close.style.borderRadius = "5pt";
    close.addEventListener("click", ()=> {
        div.removeChild(paragraph);
        div.removeChild(close);
        document.body.removeChild(div);
    });
    div.appendChild(paragraph);
    div.appendChild(close);
    document.body.appendChild(div);
}

vender prefix 無しで safari, firefox, google-chrome イケる!
何も問題ない、お試しは以下に。
ES6 Web TestPage – L’Isola di Niente

ところで google-chrome のデベロッパーツールをよく見ると。。。。。

box-shadow なんて style があるのをポップアップのおかげで知った。
いやいやツールは使ってみるものだ、早速利用しました。

comico

comico アプリを iPhone に入れた。
たしか「ももくり」アニメが始まった直後だったから約2年ぶり。
当事は iPhone 5s だったので「画面ちいさすぎでアカン!」だった。

iPhone 7 の今はド近視+老眼ぎみな筆者でも悪くないと思えるように。
画面はデカくなる一方なのでスマホで漫画はもう全然問題無いのかも。
てか、縦スクロールで読む漫画ってスマホでは本当に最適かも。

いや実は「マンガUP!」等は随分前から入れていたりするんだけーが。
横フリックでページめくりは縦長画面の恩恵が無いって感じ。

そんなこんなで。
Comipoli Web 版はスマホでは自動で comico 型になるようにしたいなと。
特許は無いよな?

とりあえず、スマホやタブレットを見分ける方法を捜さないと。
[JavaScript] ユーザーエージェントを判定し、にクラスを付与する
こんなにアッサリ、Web JavaScript 楽すぎる。

ES6 なら includes が使えるし PC ならプラットホームも得てみたいし。
ということで。

getUserAgent(id) {
    let ua = navigator.userAgent;
    let res = "";
    if (ua.includes("iPhone"))
        res = "iPhone";
    else if (ua.includes("iPad"))
        res = "iPad";
    else if (ua.includes("Android"))
        if (ua.includes("Mobile"))
            res = "Android Smartphone";
        else
            res = "Android Tablet";
    else
        res = navigator.platform; // pc
    document.getElementById(id).innerHTML = `This is a ${res}`;
}

こんな感じに。

ちなみに iPhone, iPad 用 Google Chrome でも iPhone になる。
PC の場合ブラウザ毎に違うので「Linux x86_64」等を表示するオマケ。
window.navigator.platform – Web API インターフェイス | MDN

どうでもいいけどついでに。
navigator のプロパティ一覧なんかは以下で得ることができる。

let ss = "";
for (let s in navigator) ss += `${s}: ${navigator[s]}\n`;
document.getElementById(id).innerHTML = ss;

常識かも。

コレ書いていて JavaScript でも内包表記できればなぁと思ったけど。
配列内包表記 – JavaScript | MDN
SpiderMonkey 限定で以前はできていたのか、知らなかった。
ちなみに Gjs では今でも使えるようです。

ただし for in はできないようだ、結局意味ネェ!

JavaScript Image.onload Part2

前回の続き。
2つの Image.onload コールバックを検知してから描写しないといけない。
それなら最初のコールバックの中で次の onload を呼び出しすればいいじゃない。
それに気が付くまで二週間も掛かった、いや連休前で仕事も忙しかったし。

これでインラインのように処理、、、、、できなかった。
コールバックの中でしか画像の大きさを得ることができないのが痛い。

画像が横長なのか調べる必要があるけど2つ目のコールバックまで何もできない。
これを得ないと現在表示しているページ番号が不定になってしまう。
Linux, macOS 版 Comipoli のコードはやっぱり流用できそうにない。
しかたがないので prev 処理は左右ページを入れ替えるという最終手段に。

var LocaleComicViewer = {
    readComic(files) {
        //
        // etc...
        //
        // image
        this.firstPage = new Image();
        this.secondPage = new Image();
        this.firstPage.onload = ()=> {
            if (this.num == -1) {
                this.spread = false;
                this.num = 0;
                this.drawPage();
            } else {
                if (this.prev) {
                    if (this.firstPage.width > this.firstPage.height) {
                        this.spread = false;
                        this.drawPage();
                    } else {
                        if (this.num > 0) {
                            this.spread = true;
                            this.secondPage.src = this.comics[this.num - 1];
                            this.num -= 1;
                        } else {
                            this.spread = false;
                            this.drawPage();
                        }
                    }
                } else {
                    if (this.firstPage.width > this.firstPage.height) {
                        this.spread = false;
                        this.drawPage();
                    } else {
                        if (this.comics.length > this.num + 1) {
                            this.spread = true;
                            this.secondPage.src = this.comics[this.num + 1];
                        } else {
                            this.spread = false;
                            this.drawPage();
                        }
                    }
                }
            }
        }
        this.secondPage.onload = ()=> {
            if (this.secondPage.width > this.secondPage.height) {
                this.spread = false;
                this.drawPage();
            } else {
                this.drawPage();
            }
        }
        this.firstPage.src = this.comics[0];
    },
    drawPage() {
        this.context.fillRect(0, 0, this.canvas.width, this.canvas.height);
        let aw = this.canvas.width;
        let ah = this.canvas.height;
        let w = this.firstPage.width;
        let h = this.firstPage.height;
        if (w - h > 0 || !this.spread) {
            //
            // etc...
            //
        } else {
            if (this.LtoR || this.prev) {
                //
                // etc...
                //

full src
cv,js

なんとかなったけどまだ動作があやしい。
Linux 版 Comipoli も安定させるのに一年くらい使ったし、まあこんなもんや。

ところで Firefox は location.reload だけでは読み直ししないのね。
javascript – window.location.reload not working for Firefox and Chrome – Stack Overflow

setTimeout(()=> {location.reload(true);});

で解決したけど何故に。。。。。

それと今回から class をヤメて ES6 簡略構文を使うことにした。
gjs の Lang.Class とほぼ同様だしアロー関数で this は保持できるし。
new でインスタンスを作る必要が無いのであればこっちのほうが簡単なのでお勧め。

JavaScript Image.onload

Comipoli Web 版を作るとココに随分前から書いているがそろそろ本気で。
使う人がいるかどうかなんてどうだっていいんだよ。
一度だけでもサーバーサイドをやりたい、経験になれば充分!

実は今までの TestPage で着々と準備はしている。
Canvas の動的作成やらスクロールのロックやら矢印キーの取得やらetc…
次は肝心な画像の見開き表示の実装だ。

で、コミックの見開き表示なら Canvas に Image を2つ表示すればいい。
困った、Image の読み込みは非同期だ。
2つの Image.onload コールバックを検知してから描写しないといけない。
つまり Linux, macOS 版みたいな画像切り替え処理は流用できない、なんてことだ。

歳くってジジイな頭でなんとか考えた。
ひたすらインクリメントして偶数だった場合に更新処理すればよくね?

HTML5 Canvas TestPage – L’Isola di Niente

一応抜き出しすると以下のように。

var Html5CanvaTest = class {
    readComic(files) {
        // var
        this.num = -1;
        this.en = 0; //Even number
        //
        // etc...
        //
        // image
        this.firstPage = new Image();
        this.firstPage.onload = ()=> {
            this.newPage();
        }
        this.secondPage = new Image();
        this.secondPage.onload = ()=> {
            this.newPage();
        }
        this.firstPage.src = this.comics[0];
    }
    newPage() {
        if (this.num == -1) {
            this.num = 0;
            this.drawPage();
            return;
        }
        this.en += 1;
        if ((this.en % 2) == 0) {
            this.drawPage();
        }
    }
    nextPage(num) {
        if (this.comics.length > 0 && this.comics.length > this.num + 1) {
            this.firstPage.src = this.comics[this.num + 1];
            if (this.comics.length > this.num + 2) {
                this.secondPage.src = this.comics[this.num + 2];
                this.num += 2;
            } else {
                this.en += 1;
                this.num += 1;
            }
        }
    }
    drawPage() {
        this.context.fillRect(0, 0, this.canvas.width, this.canvas.height);
        // etc...

解り辛ぇ…

onload コールバック毎に this.en をインクリメント。
その this.en が偶数だった場合に canvas に描写、というのが現在の処理。
とりあえず目的は果たしたけど、なんだかなぁ。

うーん、もっとイイ方法は無いのだろうか?

関係ないけど JavaScript で検索するとマジでみんな mac だなぁ。
エロゲ専用 OS はともかく Linux 使いは何をやっているのやら。