魔法少女サイト

これは、魔法少女になれなかった男の記録である。

人の優しさに触れた誕生日。

22歳になりました。

f:id:yuki540com:20181109173641p:plain

みなさんお久しぶりです。

大変私事なのですが、11/09が誕生日ということで22歳になりました。

せっかくの誕生日ということで、何かネット上でアクションを起こしたいと思い、あるサイトを公開しました。

はい。バーチャルニートのメンバーに入れてもらい、技術書典5で出したWeb本です。

元々は有償で公開していたものでしたが、もっとたくさんの人に「CSSアニメーションを使った自己表現」について知ってもらいたいという思いから、バーチャルニートのメンバーから許可をもらい、無償で公開させてもらいました。

🎉yozora.magical-girl.site🎉

で、プリン食べながらサイトを公開した後、すぐ寝る( ˘ω˘)スヤァ予定だったんですが.......

人の優しさに触れた

なんとバーチャルニートのメンバーのみんながサプライズで僕の誕生日サイトを作ってくれていました!?!?!?!?

これは...正直泣いちゃいました......

今までこんな嬉しいサプライズされたことなかったので......

ドワンゴインターンシップで一緒だった、おりばー君と仲良くなり、それからおりばー君の学校の友達であるバーチャルニートのメンバーのみなさん達と一緒に技術書典に一緒に参加させていただいたりと、違う学校にも関わらず仲良くしていただいて、お世話になりっぱなしで感謝しても感謝しきれません....

これからも仲良くしていただける嬉しいです....🙇‍♂️🙇‍♂️🙇‍♂️

本当にありがとうございました!!!!

また、誕生日サイト上やTwitterでたくさんの方々のお祝いメッセージもいただき、本当に嬉しいです....

f:id:yuki540com:20181109185018p:plain

f:id:yuki540com:20181109185043p:plain

f:id:yuki540com:20181109185101p:plain

f:id:yuki540com:20181109185114p:plain

f:id:yuki540com:20181109185129p:plain

f:id:yuki540com:20181109185246p:plain

f:id:yuki540com:20181109185259p:plain

f:id:yuki540com:20181109185314p:plain

数年前までの僕では考えられないほど、たくさんの方々とコミュニケーションをとらせていただける環境になり、本当に生きててよかったです....

今まで一番印象に残った誕生日になりました!!!!

みなさん本当にありがとうございました!!!!

これからについて

で、僕のこれからの活動ですが、直近では年内に2つのWebサイト(サービスではない)を公開します。(もちろんアニメーションをたくさん使ったサイトを作りますのでお楽しみに!)

また、ElectronアプリとWebサービス、できればiOSアプリも公開できたらなと思います。

VTuberデビューについてですが....年明けまで待ってください....🙇‍♂️🙇‍♂️🙇‍♂️

そして、来年4月からは株式会社ピクシブに入社します。

ずっと入社したかった会社なので精一杯頑張ります!!!

働き始めても今まで通り個人の活動も空いた時間に続けていきますのでこれからもよろしくおねがします!!

ということで超私的な記事ですが、最後まで読んでくれてありがとうございました!

また、どこかでお会いしましょう!

『臆病な魔女は、また長い旅に出る-------------------』

お知らせ

Twitterのヘッダー、PCの壁紙にさせていただきました🎉

可愛い....

トムさん、ありがとうございました🙇‍♂️🙇‍♂️🙇‍♂️

f:id:yuki540com:20181109191835p:plain

f:id:yuki540com:20181109191854p:plain

由比ヶ浜結衣生誕2018非公式サイトを作った話

あいさつ

f:id:yuki540com:20180616154123p:plain

やっはろー、yui540だよ!

最近、暑くなってきましたが、みなさんいかがお過ごしでしょうか?

僕は最近、食パンにハマっていて四六時中、食パン食べてます。

特に超芳醇 4枚切りが美味しいので、みなさんもよかったら食べてみてください。

で、今回「由比ヶ浜結衣生誕2018非公式サイト」を作ったので、そのことについて書きたいと思います。

🎂 yui.magical-girl.site 🎂

はじまり

推しキャラがコロコロ変わる僕ですが、これからは由比ヶ浜結衣のみを推していくことを決めたのですが、あることに気がつきました。

「あれ?由比ヶ浜結衣って誕生日いつだっけ?」

あろうことか、推しキャラを誕生日を把握していなかったのです。

なので、「僕と誕生日近かったら嬉しいな〜」などと思いながら検索すると...

【参照: ピクシブ百科事典】 f:id:yuki540com:20180616161442p:plain

f:id:yuki540com:20180616161504p:plain

「うっ...もうすぐだ...(検索した日は、5/31)」

何かを買ってお祝いしたいと思いましたが、ニートの僕にはあまりお金がないので、自分なりに何かをして誕生日をお祝いすることにしました。

で、僕には簡単なサイト作るぐらいしか能がないので、由比ヶ浜結衣生誕2018非公式サイトを作ることにしました。

↓「作るぞ」という意思表明

つくる

↓一連の制作過程のツイートです。

まず、メインのイラストを準備する。

OGP画像を作る。

パート分けして、アニメーションを作っていく(SPでも同じように動くようにもする)

※よく質問されますが、僕が1からイラストを描いているのではなく、元の画像をパーツごとになぞって塗りつぶして作っているだけです。

まあ、いつも通り脳死CSS Animation芸のサイトですね。

ソースコードが見たい方は、こちらにあります。

僕がよくやるCSS Animationのパターンを知りたい場合は、下の記事をご覧ください。

さいごに

出来は良くありませんが無事、6/18までにサイトをつくることができ、由比ヶ浜結衣の誕生日を祝ってくれる人達もいて良かったです。

このサイトをきっかけに「やはり俺の青春ラブコメはまちがっている。」をまた見てくれる人が増えてくれれば、なによりです。

みなさんも推しキャラの誕生日を祝うサイトを作ってみてはいかがでしょうか?

最後に、この場を使って、由比ヶ浜結衣というキャラクターを生み出し、命を吹き込んでくださった、

渡航先生・東山奈央さん・俺ガイル制作に関わった全ての方々に感謝します。

f:id:yuki540com:20180616154740p:plain

ニートに学ぶCSS Animation演出講座 4時間目

あいさつ

f:id:yuki540com:20180503160414j:plain

どうもどうも、また会いましたね。風邪気味のyuki540です。

先日、東京に遊びに行ってきましたが体調不良により、2日で地元に帰ってしまいました。でも、めっちゃ楽しかったです!

また近々、東京にもう一回行くと思うので、今度は1週間ぐらい滞在したいです。

今回はどんな作る?

で、今回作るものですが、

↓ この花火(?)みたいな弾けた感じのものを作っていきたいと思います。

いろんなところで使えるアニメーションパターンだと思うので、ぜひ作ってみてください。

作ろう

最終的に出来上がるものはこちらになります。

はい。作っていきましょう。

マークアップ

今回は3種類の弾けるアニメーションを解説するので、.effect_type_1~.effect_type_3という風に要素を分けます。

僕はdivタグしか知らないので、クソマークアップに関しては指摘されても無視しますのでご理解ください。

<main class="stage">
  <!-- effect_type_1 -->
  <section class="effect effect_type_1">
    <div></div><div></div><div></div><div></div>
    <div></div><div></div><div></div><div></div>
  </section>
      
  <!-- effect_type_2 -->
  <section class="effect effect_type_2">
    <div></div><div></div><div></div><div></div>
    <div></div><div></div><div></div><div></div>
  </section>
      
  <!-- effect_type_3 -->
  <section class="effect effect_type_3">
    <div></div><div></div><div></div><div></div>
    <div></div><div></div><div></div><div></div>
  </section>
</main>

スタイルをあてる

まずは、土台となる.stageのスタイルをあてていきましょう。

* {
  margin: 0;
  padding: 0;
}

/**
 * stage
 */
.stage {
  position: absolute;
  width: 100%; height: 100%;
  background-color: #D3C7C0;
}
.stage:before,
.stage:after { position: absolute; content: ""; display: block; }

.stage:before {
  top: 20px; left: 20px;
  width: calc(100% - 40px); height: calc(100% - 40px);
  border: dashed 5px #635256;
  border-radius: 30px;
  box-sizing: border-box;
  opacity: 0.3;
}
.stage:after {
  width: 400px; height: 400px;
  top: calc(50% - 200px); left: calc(50% - 200px);
  border-radius: 50%;
  background-color: #635256;
}

.stage:beforeで画面の周りに破線を引いて、.stage:afterで後々アニメーションの繋ぎで使う茶色のボールを作っています。

今回の重要なのは、.effect_type_1~.effect_type_3なので、.stageは好きなように装飾してもらっても大丈夫です。

次に.effect_type_1にスタイルをあてていきます。

/**
 * effect
 */
.effect {
  position: absolute;
  width: 400px; height: 400px;
  border-radius: 50%;
  overflow: hidden;
}
.effect div {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
}
.effect div:after {
  content: ""; display: block;
  position: absolute;
  opacity: 0;
}
.effect div:nth-child(1) { transform: rotate(0deg);   }
.effect div:nth-child(2) { transform: rotate(45deg);  }
.effect div:nth-child(3) { transform: rotate(90deg);  }
.effect div:nth-child(4) { transform: rotate(135deg); }
.effect div:nth-child(5) { transform: rotate(180deg); }
.effect div:nth-child(6) { transform: rotate(225deg); }
.effect div:nth-child(7) { transform: rotate(270deg); }
.effect div:nth-child(8) { transform: rotate(315deg); }


/*** effect_type_1 ***/
.effect_type_1 {
  top: calc(50% - 200px); left: calc(50% - 200px);
}
.effect_type_1 div:after {
  top: 5px; left: calc(50% - 20px);
  border-top: solid 70px #635256;
  border-left: solid 20px transparent;
  border-right: solid 20px transparent;
  transform: translateY(130px);
}

.effectで共通の部分をまとめてスタイルをあてています。

400 x 400の円を作って、子要素を45degずつ回転してるだけですね。

.effect_type_1では三角形を弾けさせたので、borderで縦長の三角形を作っています。

.stage:afterで隠れている&opacity: 0;で非表示になっているので、確認しづらいでしょうがこんな感じになってます。

f:id:yuki540com:20180503172606p:plain

また、初期状態ではtranslateYで中央に子要素を寄せています。

次に.effect_type_2にスタイルをあてていきましょう。

/*** effect_type_2 ***/
.effect_type_2 {
  top: 50%; left: calc(50% - 400px);
}
.effect_type_2 div:after {
  top: 0px; left: calc(50% - 40px);
  width: 40px; height: 40px;
  background-color: #8db3b1;
  border-radius: 50%;
  transform: translateY(170px);
}

.effect_type_2は、中央から少し左下にズレた位置に配置して、弾けさせる子要素は円にしています。 f:id:yuki540com:20180503173957p:plain

次に.effect_type_3にスタイルをあてていきましょう。

/*** effect_type_3 ***/
.effect_type_3 {
  top: calc(50% - 400px); left: 50%;
}
.effect_type_3 div:after {
  top: 0px; left: calc(50% - 20px);
  width: 40px; height: 40px;
  background-color: #9994A6;
  transform: translateY(150px);
}

.effect_type_3は、中央から少し右上にズレた位置に配置して、弾けさせる子要素は四角形にしています。

f:id:yuki540com:20180503174047p:plain

これでレイアウト的には完成です。

アニメーションさせよう

では、アニメーションさせていきましょう。

/*********************************************************************************
 *  animation
 *********************************************************************************/

/*** stage ***/
.stage:after { animation: hidden-ball 0.6s ease 0s forwards; }

/*** effect_type_1 ***/
.effect_type_1 div:after {
  animation:
    fadein 0.3s ease 0.5s forwards,
    show-type-1 0.6s ease 0.5s forwards;
}

/*** effect_type_2 ***/
.effect_type_2 { animation: rotate360 4s ease 0.6s forwards; }
.effect_type_2 div:after {
  animation:
    fadein 0.3s ease 1.1s forwards,
    show-type-2 0.6s ease 1.1s forwards;
}

/*** effect_type_3 ***/
.effect_type_3 div:after {
  animation:
    fadein 0.3s ease 1.7s forwards,
    show-type-3 0.6s ease 1.7s forwards;
}


/*********************************************************************************
 *  keyframes
 *********************************************************************************/
@keyframes hidden-ball {
  0%   { transform: scale(1); }
  50%  { transform: scale(1.4); }
  100% { transform: scale(0); }
}
@keyframes show-type-1 {
  from { transform: translateY(130px); }
  to   { transform: translateY(-75px); }
}
@keyframes show-type-2 {
  from { transform: translateY(170px); }
  to   { transform: translateY(-40px); }
}
@keyframes show-type-3 {
  from { transform: translateY(150px) rotate(0deg); }
  to   { transform: translateY(-40px) rotate(270deg); }
}

@keyframes fadein {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes rotate360 {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

単純なので説明する必要はないとは思いますが、一応説明しますと、

hidden-ballキーフレームで、.stage:afterをバイーンとした感じで画面から消します。

次にshow-type-1, fadeinキーフレームで.effect_type_1 divを弾ける感じでアニメーションさせています。(よく使いそうなキーフレームは、fadeinのように細かく分けて、カンマ区切りでanimationプロパティに適用するようにすると、色々便利です)

.effect_type_2 divも同じようにshow-type-2, fadeinキーフレームで弾けた感じでアニメーションさせますが、rotate360キーフレームで、.effect_type_2自体も回転させながら表示しています。

.effect_type_3 divは、show-type-3, fadeinキーフレームで四角形が回転しながら、弾けたアニメーションをさせています。

終わり

どうでしょう?上手く動きましたか?

上手くいかない方は、こちらのコードを参照しながらもう一度試してみてください。

さいごに

この記事を書いてる途中に気づきましたが、safariではborder-radius: 50%; overflow: hidden;をしても、円状に非表示してくれないみたいですね。

f:id:yuki540com:20180503181332p:plain

safariでは上手く動きませんが、アニメーションを作るときのヒントにでもなれば幸いです。

最後まで見てくれてありがとうございました。

できるだけ、簡単なものを作って記事に書いていく予定なので次回も見てくれると嬉しいです。

じゃーねー。

FANBOX始めました。)

f:id:yuki540com:20180503181755p:plain f:id:yuki540com:20180503181817p:plain

専門学校に入学して3ヶ月で絶望し、退学してニートになった男の話

はじめに

f:id:yuki540com:20180503150519p:plain

どーもーココロヤミ状態のyui540です😈

ニートに学ぶCSS Animation演出講座書けよ!」って思う人もいるかもしれませんが、"Effective CSS Animation"って読み物を書いてpdfで無料配布する予定なので待っててね。

で、現在ニート(2018/04/10時点)の僕ですが、僕のことをあまり知らない人は「なんでニートなの?」「就職先はあるの?」「親は怒ってない?」「あんた頭大丈夫?」というようなことを思っている人が多いと思うので、そこらへんのことも説明しながら書いていけたらな思います。

あ、先に言っておくと、ピクシブ株式会社様から内定を頂いているので1年後にはニートを脱却します。

なんの根拠もなく、希望を持って入学した専門学校

僕は低学歴なので、大学に行く頭がなかったので専門学校に入学するわけですが、今思えばこの時点で僕にとっての悪夢は始まっていたのかもしれません。

希望を抱いていた僕は入学してすぐに、周り同級生や先輩などに「趣味でプログラム書いてる?」や「どんな言語使ってる?」「なんの技術好き?」というような質問を投げかけていました。(先輩には敬語使ってます)

でも、みんな口を濁してアニメの話(アニメ好きなのでそれはそれで楽しい)などに会話をそらされていました。

仕方ないので、学校内に開発サークルみたいな感じよくわからん集まりがあったので見学しましたが、そこでも結局、ほとんど開発していなくて過去の成果物が 当時の僕でも1時間半あれば、再現可能なwebページ でした。本当によくわからん集まりです。

この時点で僕は本当の意味で一人だということ悟りました。

※ 僕のワガママに付き合ってくれるいい友達はいます。彼にはこの場を使って感謝させていただきます。

なんのために通っているのかわからなくなった学校

入学して3ヶ月ぐらいで、ITパスポート, C言語検定 2級を取って、並行で自分の好きなコードを書いたりしていました。(それ以降、資格は取ってません)

資格対策の授業は問題集をひたすらやるような感じだったので、先生はほとんどいてもいなくてもいい状態でした。

唯一の救いだと思っていたプログラミングの授業も酷いものでした(ここでは内容は言えませんが)

上記のようなこともあり、1年生の後半から〜3年生で退学するまで、ほとんど授業を聞いていませんでした。(僕はただの悪い生徒だったので、学生の皆さんはちゃんと授業聞きましょうね)

学校の同級生達とは違うやり方でやってみる

先輩達の就職活動の季節が来ると、「内定出た」など会話が飛び交っているので話を聞いてみると、学校にコネがある会社から内定を貰っている人たちばかりでした。(その会社をディスってる訳ではありません)

ただ、その会社で働きたいから入社するのではなく、「内定出た!これで就活しなくて済む!」という人たちが大半でした。

そこで感じたのが、「この学校の雰囲気に流されたままだと、入りたい会社に行くことは夢のまた夢になってしまう」でした。

周りの同級生たちは、授業以外でプログラムを書くことはなく、資格勉強も仕方なくやっているという感じでした。

なので当時、僕は授業と資格を捨てて、自分が書きたいコードを書いて、それをネットに公開していくことを決めました。

satella.io開発の始まり & 地獄の日々 & 反撃

で、当時のものはポートフォリオには載ってませんが、「コメントが流れるチャットサイト」をcometを自前で実装して作ったり、「YouTubeプレイヤー上に絵を描けるサイト」を作ったり、niconicoAPIを利用して色々遊んでいました。

それからしばらくして、たまたまLive2Dの紹介動画(Euclidの試作版だったかな?)をみて、衝撃を受けました。

そして、「技術ってこういう使い方もできるんだ」と感じ「自分も同じようなものを作ってみたい」と思い、開発を始めたのはいい思い出です。

↓ 最初は3D技術は使わず、canvas2Dで各パーツに動きの誤差を与えながら、それっぽく動かしていました。


キャラクターをスマートフォンで動かせるサービスを作ってみた。

で、これの後継となるsatella.ioが今では学生時代の一番重要な作品となりました。(現在公開しているものはβ版ですが)

ですが、satella.ioの開発中のモチベーションは壊滅的でした。

というのも、教師達からは「君には作ることができない」「それはIT学科が作るものじゃない」「すでにそんなソフトは出回っているので作る意味はない」といった言葉をかけられきたからです。

また、周りに技術的な相談をする人もいなく、そもそも動く状態にまで持っていけるのかわからないまま開発を続けるのは非常に苦しかったです。

それでも、開発を続けられたのは「可愛いキャラをこの手で動かしてみたい」という気持ちがあったからでした。

そして、結果的に一応が動く状態にまで持っていくことができ、学校の作品発表会でも、たくさんの方から賞賛の声をいただきました。

f:id:yuki540com:20180410151042j:plain

f:id:yuki540com:20180410151055j:plain

また、僕のことを批難していた教師達もこれを機に僕の開発を褒めるようになりました。(僕の中では反撃に成功したと思っています)

インターンシップへの参加が人生のターニングポイントになった

それから先は、インターンシップに参加することを目標にし、結果的に面白法人カヤック, ドワンゴ, ピクシブインターンシップに参加しました。

今までの学校生活と違い、僕よりも圧倒的にレベルの高いインターン同期の人たちや、優秀なメンターの方々に囲まれて、何かができることに感動したことを今でも覚えています。

そして、インターンシップをきっかけにピクシブ株式会社様から内定を頂くことができ、僕にとってインターンシップへの参加が人生のターニングポイントとなりました。

その後

で、内定が出たのは嬉しいのですが、あと一年、学校に通わないといけませんでした(4年制なので)

ここ半年近く体調も良くないことと、「このまま学校に通い続ける意味はない」という結論に至り、退学し、現在ニートです。(一年後ちゃんと働きます)

親は、ちゃんと就職先も見つけて、一年分の学費も浮くので逆に喜んでくれています。(親もピクシブに入社することに大賛成しているので)

僕自身は、この一年を自分の作りたいものや活動に使っていく予定です。(最近はcss animationネタが多いですが)

伝えたかったこと

「就職するために頑張ること」が書かれた記事をちらほら見かけたので、それに乗っかり書きました。

で、伝えたかったのは "僕みたいな低学歴で学校を退学したニートでも 、周りに自分と同じ志を持った人が一人もいなくても" 夢を叶えることができるということです。

僕と同じような境遇の人で、「今の状況を変えたいけど、怖くてうまく行動できない」という人はぜひ、いっぱい何か作ったり、活動したりしてどんどん公開していってみてください。

もしかしたら、今の状況が何か変わるかもしれません。

ちょっと長くなりましたが、これが僕の専門学校入学から〜退学までのお話です。

つまんなかったかもしれませんが、最後まで読んでくれてありがとうございます!

じゃーねー。

f:id:yuki540com:20180410155837p:plain

ニートに学ぶCSS Animation演出講座 3時間目

あいさつ

f:id:yuki540com:20180503144545p:plain

ハロー、yuki540だよ!ピロリン

↑ このテンションしんどいのでやめます

改めまして、yuki540です。

前回の記事読んでくれましたか?読んでない方は、ぜひ読んでみてください。

今回はキャラクターイラストを使ったアニメーション表現を紹介できたらなと思います。

で、今回作るのものはこちら。

Twitterで「3時間目はこれにする!」って言ってたものがコロコロ変わってしまってすみません...)

WebGLっぽい立体表現を使った演出ですね。

perspective, transform-styleともに対応状況が良くなってきたので積極的に使っていい頃合いかなと思います。

f:id:yuki540com:20180318103631p:plain

(ただ今回作るもののような演出は、処理が重めなのであくまで「こういう演出もあるんだな〜」程度にみてください)

作ろう

まず、最終的に出来上がるものはこちらです。

はい。じゃあ一緒に作っていきましょう。

まず、時計から

まず、最初に↓の時計(?)から作っていきましょう。

f:id:yuki540com:20180318104743p:plain

マークアップはこんな感じになります。

<main class="stage">
  <div class="stage__inner">
    <section class="clock">
      <div class="clock__frame">
        <div></div><div></div><div></div><div></div>
        <div></div><div></div><div></div><div></div>
        <div></div><div></div><div></div><div></div>
        <div></div><div></div><div></div><div></div>
        <div></div><div></div><div></div><div></div>
        <div></div><div></div><div></div><div></div>
      </div>
      <div class="clock__hands">
        <div></div><div></div>
      </div>
      <div class="clock__image"></div>
    </section>
  </div>
  <div class="stage__filter"></div>
</main>

先に.stageにスタイルを適用してみましょう。

といってもサイズを画面全体にするだけです。単純ですね。

あと、.stage__filterbox-shadowで内側に影をつけて、回想シーンのような雰囲気を表現しています。

* {
  margin: 0;
  padding: 0;
}
.stage {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  overflow: hidden;
}
.stage__inner,
.stage__filter {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
}
.stage__filter { box-shadow: 0 0 300px #444 inset; }

次に時計の縁(?)の部分にスタイルを適用してみましょう。

500px x 500pxの時計を画面の中心に配置しています。

そして、縁の部分の.clock__frame divを24分割して、15deg間隔を空けながら回転させています。(24個それぞれにスタイルをあてるのはsassなりを使うべきですね...)

f:id:yuki540com:20180318112425p:plain

/**
 * clock
 */
.clock {
  position: absolute;
  top: calc(50% - 250px); left: calc(50% - 250px);
  width: 500px; height: 500px;
  background-color: rgba(100, 100, 100, 0.1);
  border-radius: 50%;
}

/*** frame ***/
.clock__frame {
  position: absolute;
  top: 20px; left: 20px;
  width: calc(100% - 40px); height: calc(100% - 40px);
}
.clock__frame:before,
.clock__frame:after {
  content: ""; display: block;
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  border: solid 1px #444;
  border-radius: 50%;
  box-sizing: border-box;
}
.clock__frame:after {
  top: 10px; left: 10px;
  width: calc(100% - 20px); height: calc(100% - 20px);
}
.clock__frame div {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
}
.clock__frame div:after {
  content: ""; display: block;
  position: absolute;
  top: 0; left: calc(50% - 2.5px);
  width: 5px; height: 10px;
  background-color: #444;
}
/* 24分割して回転 --------------------------------------- */
.clock__frame div:nth-child(1)  { transform: rotate(0deg); }
.clock__frame div:nth-child(2)  { transform: rotate(15deg); }
.clock__frame div:nth-child(3)  { transform: rotate(30deg); }
.clock__frame div:nth-child(4)  { transform: rotate(45deg); }
.clock__frame div:nth-child(5)  { transform: rotate(60deg); }
.clock__frame div:nth-child(6)  { transform: rotate(75deg); }
.clock__frame div:nth-child(7)  { transform: rotate(90deg); }
.clock__frame div:nth-child(8)  { transform: rotate(105deg); }
.clock__frame div:nth-child(9)  { transform: rotate(120deg); }
.clock__frame div:nth-child(10) { transform: rotate(135deg); }
.clock__frame div:nth-child(11) { transform: rotate(150deg); }
.clock__frame div:nth-child(12) { transform: rotate(165deg); }
.clock__frame div:nth-child(13) { transform: rotate(180deg); }
.clock__frame div:nth-child(14) { transform: rotate(195deg); }
.clock__frame div:nth-child(15) { transform: rotate(210deg); }
.clock__frame div:nth-child(16) { transform: rotate(225deg); }
.clock__frame div:nth-child(17) { transform: rotate(240deg); }
.clock__frame div:nth-child(18) { transform: rotate(255deg); }
.clock__frame div:nth-child(19) { transform: rotate(270deg); }
.clock__frame div:nth-child(20) { transform: rotate(285deg); }
.clock__frame div:nth-child(21) { transform: rotate(300deg); }
.clock__frame div:nth-child(22) { transform: rotate(315deg); }
.clock__frame div:nth-child(23) { transform: rotate(330deg); }
.clock__frame div:nth-child(24) { transform: rotate(345deg); }

次に長針と短針と時計の中央に配置する画像にスタイルをあてていきましょう。

.clock__hands div:nth-child(1)(長針)が高さ50%で、.clock__hands div:nth-child(2)(短針)が高さ40%にしています。

.clock__imageは、時計の中央に配置する画像ですね。100% - 90px(410px)という大きさにしています。

f:id:yuki540com:20180318113820p:plain

画像は、お好みのものを用意してください。

/*** hands ***/
.clock__hands {
  position: absolute;
  top: 35px; left: 35px;
  width: calc(100% - 70px); height: calc(100% - 70px);
}
.clock__hands div {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
}
.clock__hands div:after {
  content: ""; display: block;
  position: absolute;
  top: 0; left: calc(50% - 5px);
  width: 10px;
  background-color: #444;
  border-radius: 5px;
}
.clock__hands div:nth-child(1):after { height: 50%; }
.clock__hands div:nth-child(2):after { height: 40%; top: 10%; }

/*** image ***/
.clock__image {
  position: absolute;
  top: 45px; left: 45px;
  width: calc(100% - 90px); height: calc(100% - 90px);
  background-image: url(/* お好きな画像を指定 */);
  background-size: auto 100%;
  background-position: center;
  background-repeat: no-repeat;
}

このままだと、止まったままなので時計っぽくありませんね。(特に画像を重ねているので)

なので、時計の針を動かしていきましょう。

.clock__hands:nth-child(2)(短針)が360deg.clock__hands:nth-child(1)(長針)が360 * 12 = 4320deg回転するようにします。(これよりいい方法がありますが脳死でいきます)

時計なので、イージングにはlinear(一定のスピードでアニメーション)を使っています。

/*********************************************************************************
  animation
*********************************************************************************/
.clock__hands div:nth-child(1) { animation: rotate4320 30s linear 0s infinite; }
.clock__hands div:nth-child(2) { animation: rotate360 30s linear 0s infinite; }

/*********************************************************************************
  keyframes
*********************************************************************************/
@keyframes rotate360 {
  from { transform: rotate(0deg); }   
  to   { transform: rotate(360deg); }   
}
@keyframes rotate4320 {
  from { transform: rotate(0deg); }
  to   { transform: rotate(4320deg); }
}

どうでしょうか?

↓のような時計ができましたか?できましたね。はい。次。

次に行く前に一旦、.clockdisplay:noneしておいてください。

回想シーンパネルのようなもの

f:id:yuki540com:20180318121027p:plain

次は↑の円状の回想シーンのパネルのようなものを作っていきましょう。

まず、↓のマークアップを追加してください。

<main class="stage">
  <div class="stage__inner">
    <section class="clock"><!-- 省略 --></section>

    <!-- 追加: ここから -->
    <section class="memories memories_layer_1">
      <div class="memories__image memories__image_type_1"></div>
      <div class="memories__frame"></div>
    </section>
    <section class="memories memories_layer_2">
     <div class="memories__image memories__image_type_2"></div>
     <div class="memories__frame"></div>
    </section>
    <section class="memories memories_layer_3">
      <div class="memories__image memories__image_type_3"></div>
      <div class="memories__frame"></div>
    </section>
    <section class="memories memories_layer_4">
      <div class="memories__image memories__image_type_4"></div>
      <div class="memories__frame"></div>
    </section>
    <section class="memories memories_layer_5">
      <div class="memories__image memories__image_type_5"></div>
      <div class="memories__frame"></div>
    </section>
    <!-- 追加: ここまで -->
      
  </div>
  <div class="stage__filter"></div>
</main>

先に縁の部分を作っていきましょう。

.memoriesの大きさは.clockと同様に500px x 500pxです。

ここでは一旦、.memories__image_type_2 ~ .memories__image_type_5display:noneで非表示にします(重なってしまって、これからデザインが確認しづらいため)

縁部分の内側(.memories__frame:before)が通常の線で、外側(.memories__frame:after)が波のような滑らかな線にしていきます。

f:id:yuki540com:20180318122301p:plain

滑らかな線は、border-topborder-bottomのような2点だけを指定するできます。

/**
 * memories
 */
.memories {
  position: absolute;
  top: calc(50% - 250px); left: calc(50% - 250px);
  width: 500px; height: 500px;
}

/*** 一旦、.memories__image_type_1だけを表示 ***/
.memories__image_type_2,
.memories__image_type_3,
.memories__image_type_4,
.memories__image_type_5 { display: none; }

/*** frame ***/
.memories__frame {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
}
.memories__frame:before,
.memories__frame:after {
  content: ""; display: block;
  position: absolute;
  border-radius: 50%;
  box-sizing: border-box;
}
.memories__frame:before {
  top: 25px; left: 25px;
  width: calc(100% - 50px); height: calc(100% - 50px);
  border: solid 1px #444;
}
.memories__frame:after {
  top: 0; left: 0;
  width: 100%; height: 100%;
  border-top: solid 10px #444;
  border-bottom: solid 10px #444;
}

次にパネルの画像にスタイルをあてていきます。

ちょっと透明にしているのは、あとでレイヤー間を通り過ぎる感覚をより際立たせるためです。

あと、内側にbox-shadowで影をつけて回想シーン感をまた出します。

f:id:yuki540com:20180318123526p:plain

画像はお好みのものを。

/*** image ***/
.memories__image {
  position: absolute;
  top: 50px; left: 50px;
  width: calc(100% - 100px); height: calc(100% - 100px);
  border-radius: 50%;
  background-size: cover;
  background-position: center;
  opacity: 0.8;
}
.memories__image:after {
  content: ""; display: block;
  position: absolute;
  width: 100%; height: 100%;
  border-radius: 50%;
  box-shadow: 0 0 40px #333 inset;
}
.memories__image_type_1 { background-image: url(/* お好きな画像を指定 */); }
.memories__image_type_2 { background-image: url(/* お好きな画像を指定 */); }
.memories__image_type_3 { background-image: url(/* お好きな画像を指定 */); }
.memories__image_type_4 { background-image: url(/* お好きな画像を指定 */); }
.memories__image_type_5 { background-image: url(/* お好きな画像を指定 */); }

このままだとつまらないので、滑らかな線(memories__frame:after)を回転させましょう。

キーフレームはrotate360を使い回しましょう。

.memories__frame:after { animation: rotate360 3.5s linear 0s infinite; }

ここまできたら、.clock.memories__image_type_2 ~ .memories__image_type_5display:noneを消してください。

立体空間をすり抜ける

最後にお待ちかねの立体空間をすり抜けるようなアニメーションですが、それを実現するためにperspectivetransform-styleを使います。

perspectiveは、"ユーザの視点" から "コンテンツ(要素)"の距離を指定することができます。

なので、対象の要素が傾いていた場合、perspectiveの値が小さければ小さいほど傾きが大きく、perspectiveの値が大きければ大きいほど傾きが小さくなります。

詳しくはこちら

f:id:yuki540com:20180318130014p:plain

transform-styleは、親要素の傾きに対して、子要素は3D空間の位置を保持するかを指定できます。

デフォルトではflatですが、preserve-3dにするとパララックス効果(視差効果)を出すことができます。

で、まず視点の基準として.stageperspectiveを指定し、各3D空間に配置する要素の親要素である.stage__innertransform-styleを指定します。

.stage { perspective: 20px; }
.stage__inner { transform-style: preserve-3d; }

次に.clock.memories_layer_1 ~ .memories_layer_5を3D空間の位置に配置しましょう。

translateZ100px間隔を空けながら、3D空間に配置していきます。

f:id:yuki540com:20180318132836p:plain

translateZを指定すると、perspectiveの値により、本来より大きくなったり小さくなったりするので、ある地点で本来の大きさになるようにscaleで調整します。

.clock { transform: translateZ(50px) scale(calc(1 - (50 / 100))); }
.memories_layer_1 { transform: translateZ(150px) scale(calc(1 - (150 / 200))); }
.memories_layer_2 { transform: translateZ(250px) scale(calc(1 - (250 / 300))); }
.memories_layer_3 { transform: translateZ(350px) scale(calc(1 - (350 / 400))); }
.memories_layer_4 { transform: translateZ(450px) scale(calc(1 - (450 / 500))); }
.memories_layer_5 { transform: translateZ(550px) scale(calc(1 - (550 / 600))); }

あとは"ユーザの視点"を行ったり来たりするためにcameraキーフレームを使います。

行き来するのは、cameraキーフレームを0% ~ 100%100% ~ 0%にするだけなので、キーフレームをカンマで区切り、reverseオプションで100% ~ 0%にすることができます。

あとswayキーフレームで斜めに揺らして、より立体感と浮遊感を表現しています。

f:id:yuki540com:20180318133700p:plain

/*********************************************************************************
  animation
*********************************************************************************/
.stage {
  animation:
    camera 8s ease-in-out 0s forwards,
    camera 4s ease 8s reverse forwards;
}
.stage__inner { animation: sway 0.7s ease-in-out 0s alternate infinite; }

/*********************************************************************************
  keyframes
*********************************************************************************/
@keyframes camera {
  from { perspective: 20px; }
  to   { perspective: 600px; }
}
@keyframes sway {
  from { transform: translate(3px, 3px); }
  to   { transform: translate(-3px, -3px); }
}

これで完成したはずです。

記述ミスや記述漏れがあるかもしれませんので、完成したコードはこちらにありますのでご確認ください。

さいごに

今回はperspectiveを使った演出を解説しましたが、いかがでしたでしょうか?

立体的に見せるだけで表現の幅がかなり広がりましたね。

また、今回の回想シーンのような表現にも注目して欲しいなと思います。対象の作品(今回はリゼロ)の雰囲気をいかに出せるかがキャラクターイラストを使った演出のキモだと僕は思います。

ですが、実際のページで使うには、まだパフォーマンスが良くないのでWebGLでの演出なんかの参考になれば幸いです。

次回も何か面白いアニメーションを用意するので、よければ見てください。

じゃーねー

f:id:yuki540com:20180318134559p:plain