PIXI.jsであそんでる

PIXI.jsであそんでる。

個人プロジェクトで使おうという意図もあるので、別に遊んでるわけではないけど、割と気に入って最近よく試している。何が気に入っているかと言われると、非常に簡単な点と、パフォーマンスがいいことかなー。

canvasでやっていき問題

僕としては2Dの表現をもっといろいろやりたいなーみたいなのがあって、canvasをやり始めた。端的に言うとパーティクルとか、画像をうねつかせるようなのとか、そういうのまずできるようになりたいな、みたいな。なので、ゲームを作りたいとかそういうのはあんまりない。今もそんなに興味はない。
ただ、キャラクターを動かすとかはちょっとやってみたい思いがあるけど、素材を用意するのが面倒だなというので尻込みしてる。

それで結局canvasgetContext('2d')して愚直にやってたんだけど、どうもパフォーマンスがあんまりだし、それ用のライブラリというものが世の中にはあって、触らないのもどうなんだとおもってCreate.jsとPIXI.jsを試してみた。

実際、書き方的には2Dを弄る分にはcanvasだろうとcreate.jsだろうとPIXI.jsだろうとあんまり変わらんなという印象。ただ、PIXIはデフォルトでWebGL使ってくれるのでパフォーマンスがいいし、カスタムフィルターみたいなのが用意されてて、できることも多い。

というか、canvasである程度アニメーションの書き方がわかってなかったら、どっちにせよで全然わかんなかっただろうなとも思う。

PIXI.js

そういうわけで今はPIXIにはまってちょっと触ってみてる。自分で作る時も次はPIXI入れるだろうなと思う。

パーティクル

See the Pen PARTICLE PIXI by bom_phage (@bom_phage) on CodePen.

パーティクルをマスクしたやつ

See the Pen PARTICLE PIXI LINES MASK by bom_phage (@bom_phage) on CodePen.

結局z軸問題がある

今の所z軸をいい感じに弄る方法がわかってないので、んーっていうところもある。three.jsももっと触ってみたいなと思うのと、シェーダーをちゃんとやりたいなと思う。

CSSであそぼう

CSSであそぼう

CSSであんまり使ってないというか、あんまり挙動理解してないのいろいろあったので遊んでみた。

transformとperspective

matrix3D とか正直触ってみたけど行列を理解する頭がまだないので、よくわからん。結局translateとかscaleとかrotateみたいな慣れ親しんだものたちを触るほうが直感的だし、理解がはやくていいなとなった。
perspectiveも何回かしか試したことなかったけど便利。

というか、DOMを弄るほうがcanvasの2dいじるよりパフォーマンスいい気がする。しかもcanvasだとz軸がないけれど、CSSにはあるのでそういう面でもすごく直感的。だけど、DOMを常に操作しているということと、場合によってはDOMを大量に挿入するなどすることを考えるとあんまり前向きになれない部分もある。

See the Pen CSS Play by bom_phage (@bom_phage) on CodePen.

See the Pen CSS Play2 by bom_phage (@bom_phage) on CodePen.

clip

clipとか使うこと全然なかった。未だにどういう時に使うのかわかってない。だけどtextもclipできるみたいなことがわかったので、それなら確かに使うような場面があるかもしらんな、と言う気持ちになったのでちょっとさわってみた。

See the Pen CSS play3 by bom_phage (@bom_phage) on CodePen.

んー、でもつかうかなー

歳をとった。

歳をとった。今まさに年齢が増えるという切り替えの時間には、家で仕事をしていた。非常につらい仕事だったけど、日が変わって少ししたのち、ほぼ終わった。
朝起きてズッキーニを食べた。ひどく苦くて吐き出した。稀にこういうものがあるらしい。二本あって二本ともそうだったので捨てた。今もずっと口が苦い。

今年も最早半年が過ぎた。何かできただろうか。成長しただろうか。筋トレ以外続いてないし、進捗は非常に悪い。
そこで具体的に何をするのか以下に書いておこう。

書くとシンプルな気がする。とにかく人間やっていくことが大事なんだよなという気持ち。

年末にはやった感のある自分が見たいな。

何をしたいのか考えている

ここ最近専らの悩みは何をやっていくかということだ。なんか自分の年齢を自覚する機会が増えるにつれて、流石にだらだらしていられない気持ちになってきたので、行動したいと思っている。

そうは言いながら、予定では今頃ポートフォリオサイトだったりある程度形にしているはずだったのにも、降って湧いたタスクに時間を取られて手が止まってしまっている。

興味があること

何がしたいかという話を一年半くらい前に会社でしたことがあった。その時は、かっこいいものを作りたいという単純なものだったけど、今はまた少し、気持ちが違う。 かっこいいものっていうのは、イカしたデザインってことで、ポートフォリオサイトに載ったり、賞レース目指したりみたいなことだったと思ってる。 もちろん今もその気持ちはあるけれど、少し違くて、そういう曖昧な言葉で言うなら、面白いことをやりたいというのがしっくりくる。

具体的にどんなことかというと、クライアントやユーザーの目的を効果的に達成できるようなもので、そのプロセスと成果物だ。 当たり前だけど、目的もなくユーザーはページに訪れないし、クライアントも発注したりはしない。そのゴールがどこにあるかを考えて、どう解決するのか、僕はフロントエンドなので、その知見をどう解決に活かすかということに興味がある。

僕はやっぱ見た目がイカしたサイトが好きなので、その結果がインタラクションや動きが凝っててちょっと読み込みに時間がかかるような、いわゆるリッチなサイトだと嬉しいけど!

あるいは、ビジョンに共感できるようなものをずっと育てていくというのもすごく面白そうだと思ってる。 年取ったからかもしれないけど、ビジネスやチームにすごく興味がある。ある大きなプロジェクトを時間をかけて開発、検証して、より良いものにしていく。そしてユーザーの体験を向上していくというのも、今すごく経験してみたいことの一つだ。 もちろん思っていることと現実は違うだろうけど。

受託なのか、事業会社なのか

それが全然決めきれない。 今は受託なので、事業会社で働いてみたいという気持ちはでも強い。 でも、持ってるスキルは完全にサイト制作用だ。 受託でサイトを制作するような仕事なら、すんなり馴染んで仕事していけるんじゃないかと思う。だけど、アプリ開発等だと、知識がまるで足りないので覚えながらやっていくことになる。 年齢的にも、新しいことを経験するなら今なのではないかとも思うし、さまざまな考えがぐるぐる巡って悩んでいる。

だけど結局

なるようにしかならないわけだし、行動できてもないのに永遠に悩むのも時間がもったいない。 なんというか、まぁ、動き出そうぜという話でした。

今、Webフロントエンドをはじめるとしたら。

以前知り合いに、Web制作をやってみたいという話を受けたことがあった。結局それ以降話が膨らんだりはしなかったのだけど、なんとなく自分がどうやって覚えたか振り返ってみたくなった。

自分自身、Webサイトの作り方を覚えたのは独学だった。 当時、自分は仕事がなくて潰れそうな印刷会社にいて、業務時間中恐ろしく暇だった。その時の同僚にWebサイトを作れる人がいたので、暇な時間に色々聞いて作り始めた。最初概念的なことを教えてもらって、それから調べて、わからなければまた聞いたりした。ずっと自分の描いた絵を公開できるような場所が欲しいとおもっていたので、自分のWebサイトを最初に作った。 今考えれば、tumblr でええやんって感じだが、僕はなんでも自作したいタイプなので、なんとなく既存のサービスでなくて、自分の手で作りたいという気持ちが強かった。 2010年末から2011年くらいのことだ。

結局会社はすぐに潰れて、転職することになった。若干Webの知識がついたことと、作ったもの(自分のサイト)があったので、EC店舗運用の会社に入れた。 もちろんWebの知識は活きたが、別にほとんど不要でもあった。

前職の同僚に、今はWordpress だと聞いたのでテーマを自作してみた。高橋ノリのWebデザインレシピを何回も読んでなんとか実装した。 それからスマホサイトもいるよね、レスポンシブ、みたいな時代がやってきて、自分のサイトをレスポンシブにしてみた。2014年くらいの話。仕事中にウェブ関連の記事を読んで、友達とか知り合いのサイト作ったりして、普通にレスポンシブサイト作るくらいはできるようになった。 ここが限界だった。

僕は基本的にコンピュータに対する知識がない。 中で何が動いているのか、或いはwebサーバーとは何か、通信とは?インストールとは?パスとは?環境変数とは? コンソールを叩いて様々やるタスクランナーみたいなのが登場してるけど、なんだか怖い。git?sass?

Javascriptもほとんどわからなかった。 もちろんjQueryを引っ張ってきて、ライブラリ読み込ませてスライダーを導入するとかはできた。もちろんコピペだ。 野良スクリプトを貼っつけて動くだの動かないだのやっていた。

JavaScriptを書けないのは致命的なのではないかと思って、本を読んだり、入門サイトを巡って書式を学んでたけど、一体このfor分やら配列やらオブジェクトやらがなんの役に立つのかさっぱり見当もつかなかった。

次の会社で人に恵まれたので、今はJavaScriptもある程度わかるしcanvasで遊んだり、制作環境作ったりできるようになった。 gitがないと辛いし、sassでないとやる気が起きない。

自分が始めた頃と環境が一変したなと思う。 その当時はhtmlがあって、cssがあって、jQuery読ませとけばそれでよかった。 だけど結局今始めるんだとしてもやることは変わらないわけで、html書いてcssやってjQuery読ませてレスポンシブ対応して、みたいなことを地道にやっていくことになるだろうと思う。

その先をやるかやらないかは、とりあえずそれができたら考えればいいし、Webサイトを制作する上では結局の成果物はそれでしかないんだよなと思う。

何にもない話でした。

canvasにHTMLの内容を描画したい

かっこいいサイト見てたら、canvasにHTMLの内容を描画して背景なんかに引いてぐにゃぐにゃさせているようなのがあった。僕はそういうぐにゃぐにゃするようなのすごく好きなので、一体これどうやってるんだろうな、みたいな気持ちになって見てた。

たまたま、そのことをふと思い出して調べてみたら普通にMdnに載ってたので、早速試してみた。 文献これです。

DOM オブジェクトを Canvas に描画する

記述されている通りにやると確かに動くけど、もっとがっつりやりたいよね、という気持ちになる。
早い話、document.getElementByIdかなんかで要素を取得して、svgにぶち込んで、丸ごと描画させるみたいなことをやりたい気持ちになってくる。

そこで上記の文献を読むと、

SVG は valid な XML でなければならないので、埋め込む HTML も well-formed なものでなければいけません。

なるほど。参考コードが載ってるのでそれに則って一気にやってみる。

  // canvasの取得とサイズ指定
  const c = document.getElementById('c');
  const ctx = c.getContext('2d');
  const h = window.innerHeight;
  const w = window.innerWidth;
  c.width = w;
  c.height = h;

  // canvasに表示したい要素の取得
  const html = document.getElementById('js-html');

  /**
  * well-formedなやつ
  */

  // html作成
  const doc = document.implementation.createHTMLDocument('');
  // そのbodyの中に取得してきたDOMを書き込む
  doc.write(html);
  // svg化するのに使うぞ
  doc.documentElement.setAttribute("xmlns", doc.documentElement.namespaceURI);
  const serializeHtml = (new XMLSerializer).serializeToString(doc);

あれ、ほんでこれどうすればいいんだ?みたいな気持ちになる。
serializeHtmlを見ると当たり前だけど、シリアライズされて文字列になったHTMLが入っている。
これはつまりこれをsvgにはめ込んでやればオッケーってことなのか?

  const data = `
    <svg xmlns='http://www.w3.org/2000/svg' viewBox='0, 0, ${w}, ${h}' width='${w}' height='${h}'>
      <foreignObject width='100%' height='100%'>
        ${serializeHtml}
      </foreignObject>
    </svg>
  `;

  // svgファイルに変換
  const svg = new Blob([data], {type: "image/svg+xml;charset=utf-8"});

  // svgを生成した後、それをimgで読みたいため、urlを生成する
  const DOMURL = self.URL || self.webkitURL || self;
  const url = DOMURL.createObjectURL(svg);

  const img = new Image();
  img.src = url;

  // GO!!
  img.onload = () => {
    ctx.drawImage(img, 0, 0);
    // urlを破棄する
    DOMURL.revokeObjectURL(url);
  }

やってみると多分でかいcanvasがあるだけで何も表示されないと思う。
そこでChromeのdeveloperツール開いて、ネットワークパネルを見ると破滅した画像のリソースが見つかった。それを開くと

This page contains the following errors:
error on line 4 at column 11: internal error: detected an error in element content

Below is a rendering of the page up to the first error.

はぁ。

確認すると4行目には<!DOCTYPE html>がいる。つまりこいつがダメってことか。
だけどdocument.implementation.createHTMLDocumentで生成すればそれは必ず入るので、この方法ではこの場合ダメなんじゃなかろうか。

そういうわけで。

普通に取得してきたDOMをシリアライズして<div xmlns="http://www.w3.org/1999/xhtml"></div>で囲ってぶち込みましょう。
問題は解決です。

  // canvasに表示したい要素の取得
  const html = document.getElementById('js-html');
  const serializeHtml = (new XMLSerializer).serializeToString(html);

  const data = `
    <svg xmlns='http://www.w3.org/2000/svg' viewBox='0, 0, ${w}, ${h}' width='${w}' height='${h}'>
      <foreignObject width='100%' height='100%'>
        ${serializeHtml}
      </foreignObject>
    </svg>
  `;

はい。

スタイルどうするねん問題

<div xmlns="http://www.w3.org/1999/xhtml"></div>のなかに<style></stye>で書いてやれば普通にあたる。 だけど愚直に記述するのも厳しいので、cssファイルを取得してきて、打ち込むことにしましょう。
僕はaxiosを使います。以下コード全文

  
  const c = document.getElementById('c');
  const ctx = c.getContext('2d');
  const h = window.innerHeight;
  const w = window.innerWidth;
  c.width = w;
  c.height = h;
  
  // html 取得 & SVG作成
  const html = document.getElementById('js-html');

  // Get well-formed markup
  const serializeHtml = (new XMLSerializer).serializeToString(html);

  axios.get('./style.css')
    .then(res => {
      const style = res.data;
      const data = `
        <svg xmlns='http://www.w3.org/2000/svg' viewBox='0, 0, ${w}, ${h}' width='${w}' height='${h}'>
          <foreignObject width='100%' height='100%'>
            <div xmlns="http://www.w3.org/1999/xhtml">
            <style>
              ${style}
            </style>
            ${serializeHtml}
            </div>
          </foreignObject>
        </svg>
      `;
      const svg = new Blob([data], {type: "image/svg+xml;charset=utf-8"});

      // svgを生成した後、それをimgで読みたいため、urlを生成する
      const DOMURL = self.URL || self.webkitURL || self;
      const url = DOMURL.createObjectURL(svg);

      const img = new Image();
      img.src = url;

      // GO!!
      img.onload = () => {
        ctx.drawImage(img, 0, 0);
        // urlを破棄する
        DOMURL.revokeObjectURL(url);
      }
    })
    .catch(err => {
      console.log(err);
    });

結局

画像なんかはまたあれだし、便利にやってくれるhtml2canvasと言うライブラリがあるので、それを使いましょう。

html2canvas

Hello World!!

そういうわけで、レンサバ上にワードプレス入れてどうこうしようと思って領域作ってやってたけど、色々だるくなったのではてなにした。

なにがだるかったのかというと、まずスマホでログインするのが面倒だったし、あとはSNSなどの埋め込みについて考えるととにかく億劫になって、まるで記事を書かないみたいなことになった。

f:id:bom_shibuya:20180515092454j:plain

これは茹で上がったシャコで、2、3週間前に食べたやつだ。なんの脈絡もないが、しょっぱなにこういうものを置くことによって、自分は適当に更新するんだという意思表示をしておく。

今僕は電車で、非常に眠たい。

連日、家に帰ると仕事があるので睡眠時間がゴリゴリ削られている。

金と時間のバランスについて、よく考えている。