Advance Everyday

10/7のAdvance Everyday

昨日のイラスト

昨日のスクリプト

今日から中間考査の2週間前くらいになる。

とりあえずAdvanceは一時停止させて、これまで勉強してこなかった分取り返しに行こうと思っている。

これまでは「SNSも全部消してずっと勉強せざるを得ない状況に身を置く」ことが一番の努力だと考えていたが、「正しい努力」というのはきっと、勉強は長く続かない、ということを見越した上である程度ブレイクタイムを儲けながら「勉強」というエッセンスを水で薄めてカルピスみたいに飲むことを言うんだと思う。

だからこそ、時々Advanceも進めながら、ただほとんどの時間を勉強に充てる2週間をスタートさせます。

辛い。

とにかく、辛い。

女の子から唐突にラインが来たりしたらモチベーションアップになるだろうに。

「お互い中間考査が終わったら遊ぼ!」

なんて言えた日には、僕が成績優秀者になる日も目前だろう。

CODING MANUAL

なんだかデザインもアニメーションも似通ってきてしまう。

これじゃインプットにもアウトプットにもならない。

きっとマンネリ化というのは何に置いても「作り手のインプットが滞っている状態」だと思う。

インプットの中からしかアウトプットはできないわけだから。

日々新しいインプットをしていかないといけなそうだ。

<div class="whitespace"></div>
    <div class="chat">
      <div class="set set_1">
        <div class="box"></div>
        <div class="text_chat text_chat1">
          <p>
            はぁ。。<br />
            なんて返ってくるのか、、<br />
            そもそも返信は来るのか?!
          </p>
        </div>
      </div>

      <div class="set reverse set_2">
        <div class="box"></div>
        <div class="text_chat text_chat2">
          <p>
            うーーーーーわ!!<br />
            なんか連絡きた☆<br />
            死ぬほど嬉しいねんけど!
          </p>
        </div>
      </div>

      <div class="set set_3">
        <div class="box"></div>
        <div class="text_chat text_chat3">
          <p>
            やったぁっ!<br />
            当日楽しみ!!
          </p>
        </div>
      </div>

      <div class="set reverse">
        <div class="special">
          <svg
            xmlns="http://www.w3.org/2000/svg"
            xmlns:xlink="http://www.w3.org/1999/xlink"
            viewBox="0 0 562.5 488"
            class="svg_heart"
          >
            <defs>
              <style>
                .cls-1 {
                  fill: none;
                }
                .cls-2 {
                  clip-path: url(#clip-path);
                }
                .cls-3 {
                  fill: #e86b79;
                }
                .cls-4 {
                  fill: #fff;
                  stroke: #e86b79;
                  stroke-miterlimit: 10;
                  stroke-width: 5px;
                }
                .cls-5 {
                  clip-path: url(#clip-path-2);
                }
              </style>
              <clipPath id="clip-path" transform="translate(-205 -65)">
                <rect class="cls-1" x="234" width="531" height="309" />
              </clipPath>
              <clipPath id="clip-path-2" transform="translate(-205 -65)">
                <rect class="cls-1" y="309" width="624" height="342" />
              </clipPath>
            </defs>
            <g id="レイヤー_2" data-name="レイヤー 2">
              <g id="レイヤー_1-2" data-name="レイヤー 1">
                <g class="cls-2">
                  <polygon
                    class="cls-3 hurt"
                    points="1 470 530 33 496 0 560 0 560 82 541 63 34 488 1 470"
                  />
                </g>
                <path
                  class="cls-4"
                  d="M748.53,215.17s-139.41-148.89-216.87,0c0,0-123.92-148.89-193.63,0,0,0-74.87,227.12,206.54,302.83C544.57,518,836.31,389.3,748.53,215.17Z"
                  transform="translate(-205 -65)"
                />
                <g class="cls-5">
                  <polygon
                    class="cls-3 hurt"
                    points="0 470 529 33 495 0 559 0 559 82 540 63 33 488 0 470"
                  />
                </g>
              </g>
            </g>
          </svg>
        </div>
      </div>
    </div>

    <div class="whitespace"></div>
.whitespace {
  height: 100vh;
}

.chat {
  @include inner;
  max-width: 350px;
  overflow: hidden;

  .set {
    margin: 0 auto 60px auto;
    display: flex;
    flex-direction: column;
    align-items: flex-start;

    .box {
      margin: 0 0 20px 0;
      width: 55%;
      height: 42px;
      border-radius: 21px;
      @include original_back;
      overflow: hidden;
    }

    .text_chat {
      width: 70%;

      p {
        font-size: 0.6rem;
      }
    }

    .special {
      width: 80%;
      overflow: hidden;

    }
  }

  .reverse {
    align-items: flex-end;

    p {
      text-align: right;
    }
  }
}
var tl_heart = new TimelineMax();


//最後のハートをアニメーション
var tl_heart_hurt = tl_heart
  .from(".svg_heart", 0.3, { opacity: 0 })
  .from(".svg_heart", 0.3, { scale: 0.8 })
  .from(".hurt", 0.3, { opacity: 0 });

var heart_whole = new ScrollMagic.Scene({
  triggerElement: ".special",
  triggerHook: 0.4,
})
  .setTween(tl_heart_hurt)
  .addTo(controller);


// 1つ目のチャットボックスに対してアニメーション
var tl_chat1 = new TweenMax.from(".text_chat1", 0.5, { x: -200 });

var heart_chat1 = new ScrollMagic.Scene({
  triggerElement: ".set_1",
  triggerHook: 0.7,
})
  .setTween(tl_chat1)
  .addTo(controller);


// 1つ目のチャットボックスにおける心情表現を表示するアニメーション
var tl_chat1_op = new TweenMax.from(".text_chat1", 0.5, { opacity: 0 });

var heart_chat1_op = new ScrollMagic.Scene({
  triggerElement: ".set_1",
  triggerHook: 0.7,
})
  .setTween(tl_chat1_op)
  .addTo(controller);


// 2つ目のチャットに対してアニメーション
var tl_chat2 = new TweenMax.from(".text_chat2", 0.5, { x: 200 });

var heart_chat2 = new ScrollMagic.Scene({
  triggerElement: ".set_2",
  triggerHook: 0.6,
})
  .setTween(tl_chat2)
  .addTo(controller);

// 2つ目のチャットボックスにおける心情表現を表示するアニメーション
var tl_chat2_op = new TweenMax.from(".text_chat2", 0.5, { opacity: 0 });

var heart_chat2_op = new ScrollMagic.Scene({
  triggerElement: ".set_2",
  triggerHook: 0.6,
})
  .setTween(tl_chat2_op)
  .addTo(controller);


// 3つ目のチャットボックスに対してアニメーション
var tl_chat3 = new TweenMax.from(".text_chat3", 0.5, { x: -200 });

var heart_chat3 = new ScrollMagic.Scene({
  triggerElement: ".set_3",
  triggerHook: 0.5,
})
  .setTween(tl_chat3)
  .addTo(controller);


// 3つ目のチャットボックスにおける心情表現を表示するアニメーション
var tl_chat3_op = new TweenMax.from(".text_chat3", 0.5, { opacity: 0 });

var heart_chat3_op = new ScrollMagic.Scene({
  triggerElement: ".set_3",
  triggerHook: 0.5,
})
  .setTween(tl_chat3_op)
  .addTo(controller);

10/6のAdvance Everyday

昨日のイラスト

昨日のスクリプト

勉強と課外活動と、どうバランスを取っていくのかっていうのはかなり頭を抱える悩みになると思うのですが、個人的には最近になって整理がついた気がしてて。

ビル・ゲイツとかマーク・ザッカーバーグも、結局大学には行っていて、でも在学中に外で進めている活動が大きくなりすぎた結果大学を中退したわけです。

この「みんなが通る道」を残しながら、他の時間で事業を大きくして最終的に「みんなが通る道」から「降りざるを得ない状況」を作り出していくことが目標になるのかなと。

CODING MANUAL

今回はすごくイケてるデザインになったと思います。

ドッツの色を変えると同時にサイズを少し大きくしたりも考えたのですが、レイアウトが崩れてしまったので次回以降に後回し。

<div class="timeline_whole">
      <div class="timeline">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 495 1709">
          <defs>
            <style>
              .cls-1 {
                fill: #e86b79;
              }
              .cls-2 {
                fill: none;
                stroke: #e86b79;
                stroke-miterlimit: 10;
                stroke-width: 8px;
              }
            </style>
          </defs>
          <g id="レイヤー_2" data-name="レイヤー 2">
            <g id="レイヤー_1-2" data-name="レイヤー 1">
              <rect
                class="cls-1 ball1"
                x="326"
                width="169"
                height="169"
                rx="84.5"
              />
              <rect
                class="cls-1 ball2"
                x="127"
                y="308"
                width="169"
                height="169"
                rx="84.5"
              />
              <rect
                class="cls-1 ball3"
                x="23"
                y="616"
                width="169"
                height="169"
                rx="84.5"
              />
              <rect
                class="cls-1 ball4"
                y="924"
                width="169"
                height="169"
                rx="84.5"
              />
              <rect
                class="cls-1 ball5"
                x="85"
                y="1232"
                width="169"
                height="169"
                rx="84.5"
              />
              <rect
                class="cls-1 ball6"
                x="296"
                y="1540"
                width="169"
                height="169"
                rx="84.5"
              />
              <path class="cls-2" d="M410.6,49.94s-734,922,0,1596" />
            </g>
          </g>
        </svg>
      </div>

      <div class="text_timeline">
        <h3 class="timeline_1">生まれるかも<span>2003</span></h3>
        <h3 class="timeline_2">生まれるのか<span>2004</span></h3>
        <h3 class="timeline_3">生まれるんだろうか<span>2005</span></h3>
        <h3 class="timeline_4">生まれるのでしょうか<span>2006</span></h3>
        <h3 class="timeline_5">生まれる!?<span>2007</span></h3>
        <h3 class="timeline_6">生まれるわけない<span>2008</span></h3>
      </div>
    </div>
.timeline_whole {
  @include flex(row, space-between);

  max-width: 350px;
  margin: 1000px auto 1000px auto;

  .timeline {
    width: 50%;

    .ball1 {
      fill: #ff69b4;
    }
  }

  .text_timeline {
    width: 40%;
    @include flex(column, space-between);

    h3 {
      span {
        display: block;
        font-size: 0.8;
      }
    }

    .timeline_2,
    .timeline_3,
    .timeline_4,
    .timeline_5,
    .timeline_6 {
      display: none;
      opacity: 0;
    }
  }
}
timeline = new TweenMax.to(".timeline", 0.5, { scale: 1.2 });

var timeline_scene = new ScrollMagic.Scene({
  triggerElement: ".timeline_whole",
  triggerHook: 0,
  duration: 1000,
})
  .setPin(".timeline")
  .setTween(timeline)
  .addTo(controller);

var tl_timeline = new TimelineMax();

var timeline1 = tl_timeline
  .to(".timeline_1", 2, { opacity: 0 })
  .set(".timeline_1", { display: "none" })
  .set(".timeline_2", { display: "block" })
  .to(".timeline_2", 2, { opacity: 1 }) //
  .to(".timeline_2", 2, { opacity: 0 })
  .set(".timeline_2", { display: "none" })
  .set(".timeline_3", { display: "block" })
  .to(".timeline_3", 2, { opacity: 1 }) //
  .to(".timeline_3", 2, { opacity: 0 })
  .set(".timeline_3", { display: "none" })
  .set(".timeline_4", { display: "block" })
  .to(".timeline_4", 2, { opacity: 1 }) //
  .to(".timeline_4", 2, { opacity: 0 })
  .set(".timeline_4", { display: "none" })
  .set(".timeline_5", { display: "block" })
  .to(".timeline_5", 2, { opacity: 1 }) //
  .to(".timeline_5", 2, { opacity: 0 })
  .set(".timeline_5", { display: "none" })
  .set(".timeline_6", { display: "block" })
  .to(".timeline_6", 2, { opacity: 1 }); //

var timeline_scene_text = new ScrollMagic.Scene({
  triggerElement: ".timeline_whole",
  triggerHook: 0,
  duration: 1000,
})
  .setPin(".text_timeline")
  .setTween(timeline1)
  .addTo(controller);

var tl_timeline_ball = new TimelineMax();

var timeline_ball = tl_timeline_ball
  .to(".ball1", 1, { fill: "#E86B79" })
  .to(".ball2", 1, { fill: "#FF69B4" })
  .to(".ball2", 1, { fill: "#E86B79" })
  .to(".ball3", 1, { fill: "#FF69B4" })
  .to(".ball3", 1, { fill: "#E86B79" })
  .to(".ball4", 1, { fill: "#FF69B4" })
  .to(".ball4", 1, { fill: "#E86B79" })
  .to(".ball5", 1, { fill: "#FF69B4" })
  .to(".ball5", 1, { fill: "#E86B79" })
  .to(".ball6", 1, { fill: "#FF69B4" });

var timeline_scene_ball = new ScrollMagic.Scene({
  triggerElement: ".timeline_whole",
  triggerHook: 0,
  duration: 1000,
})
  .setTween(timeline_ball)
  .addTo(controller);

コード長めだけど結構整理されてると思うっ

10/5のAdvance Everyday

昨日のイラスト

アイコンたちはここからダウンロードしたものを使っています。

http://iconstore.co/

昨日のスクリプト

「SNSをやめたい」みたいなことを最近すごく思うようになったんですが、SNSって存在としては大きいから、全部止めるのはすごいもったいないと思うんです。

個人的におすすめなのは、作業合間にiPadで観る「YouTube」を「NewsPicks」にリプレイスすること。

NewsPicksもプレミアム会員であれば動画コンテンツは充実してるし、更新頻度も高いから、作業途中に流すのはYouTubeみたいにどうでもいい動画を観ることにはならないNewsPicksをお勧めします。笑

CODING MANUAL

先に断っておきたいのですが、これ正しい書き方か分からないです。笑

setPinで要素の差をつけてからそのままスクロールアウトさせるのってdurationの数字をずらす方法であってるんだろうか…

あと工夫した点としてアイコンのサイズをスケールさせてますっ

<div class="icon_on_phone">
      <img src="svg/instagram_icon_on_phone.svg" class="icon_scale instagram" />
      <img src="svg/twitter_icon_on_phone.svg" class="icon_scale twitter" />
      <img src="svg/youtube_icon_on_phone.svg" class="icon_scale youtube" />
    </div>

    <div class="text">
      <p>
        マルチディスプレイ環境(複数のPCモニターを同時使用すること)が整ったら、ぜひ体験しておきたいのが「モニターの縦置き」です。筆者もデュアルディスプレイの片方を縦置きにして3ヶ月ほど経ちますが、もう横置きには戻れません!これまでは視野の外になっていた情報をスクロールなしで表示でき、以前と比べ物にならないくらい作業効率がアップしました。<br />
        この記事は次のような方におすすめです。
      </p>
    </div>
.icon_on_phone {
  max-width: 250px;
  margin: 1000px auto 50px auto;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  img {
    display: block;
    width: 60px;
  }
}

.text {
  margin: 0 auto 10000px auto;
}
icon_scale = new TweenMax.to(".icon_scale", 0.5, { scale: 1.5 });

var icon_on_phone1 = new ScrollMagic.Scene({
  triggerElement: ".instagram",
  triggerHook: 0.6,
  duration: 120,
})
  .setPin(".instagram")
  .setTween(icon_scale)
  .addTo(controller);

var icon_on_phone2 = new ScrollMagic.Scene({
  triggerElement: ".twitter",
  triggerHook: 0.6,
  duration: 1,
})
  .setPin(".twitter")
  .setTween(icon_scale)
  .addTo(controller);

var icon_on_phone3 = new ScrollMagic.Scene({
  triggerElement: ".youtube",
  triggerHook: 0.6,
  duration: 180,
})
  .setPin(".youtube")
  .setTween(icon_scale)
  .addTo(controller);

10月4日のAdvance Everyday

昨日のイラスト

昨日のスクリプト

このAdvanceでポッドキャストを開設し、多くの人が聴けるようにSpitifyへ配信をしているわけだが、ここ最近になってさらにSpotifyのことが好きになった気がする。

というのも、UIが素敵すぎるのだ。

ポッドキャストを登録する際も、ブラウザでRSSコードというものを使ってプロフィールをつくっていくんだけど、Webでもここまでイケてるルックスをしてるなんて流石すぎる…とずっと感動してました。笑

CODING MANUAL

風景だったり情景をざっくり表現するのもいいですが、こんな感じで「実際スマホにのっかってるもの」をアニメーションさせる面白さもありますよね。

// ドットを移動
var advance_music = new TweenMax.to(".played_music_dots", 1, {
  ease: Power3.linear,
  x: 318,
});

var music_let_short = new ScrollMagic.Scene({
  triggerElement: ".music_play_svg",
  triggerHook: 0.4,
})
  .setTween(advance_music)
  .addTo(controller);

// 左の線を伸ばす
var advance_music_play = new TweenMax.to(".played_music", 1, {
  ease: Power3.linear,
  scale: 2,
});

var music_let_play = new ScrollMagic.Scene({
  triggerElement: ".music_play_svg",
  triggerHook: 0.4,
})
  .setTween(advance_music_play)
  .addTo(controller);


// 再生中マークを消す
var tlMusic = new TimelineMax();

var advance_music_button = tlMusic
  .to(".play_button_left", 0.2, {
    ease: Power3.linear,
    opacity: 0,
  })
  .to(".play_button_right", 0.2, {
    ease: Power3.linear,
    opacity: 0,
  })
  .from(".stop_button", 0.2, {
    ease: Power3.linear,
    opacity: 0,
  });

// 停止マークを表示する
var music_button = new ScrollMagic.Scene({
  triggerElement: ".music_play_svg",
  triggerHook: 0.4,
})
  .setTween(advance_music_button)
  .addTo(controller);

今回のドットを移動させるアニメーションに関しては「rect」というタグの名前で表示されていたので、SVGですし、TweenMaxで「left: 100」みたいな指定も機能しなかった。

ここはしょうがないと思ってX軸に目分量で調節して、線の延長とマッチするくらいの数字を設定して耐えています。

線の延長も「scale」で設置しちゃっていますが、センスがないかもしれないですね。。

どうすればいいんでしょうかっ考えてみます。

10/3のAdvance Everyday

昨日のイラスト

昨日のスクリプト

最近朝にスマホのアラームをベッドの隣で鳴らしているので、家を出るタイミングでは充電が20%しかない、みたいな日が続いていて、電車の中でもスマホをいじらずに本を読んでいたりするんですね。

それで感じたのは「スマホ触ってる時間って目に入る情報は多いんだけど何にもなってないな」ってこと。

すごいもったいない時間の過ごし方だし、僕のリスペクトしてる同級生の友達とかはスマホを家から持って出ないという習慣をつけてて、僕もそれ真似しようかしらなんて思ってる今日この頃。

CODING MANUAL

今日はずっと作ってみようと思っていた「クローズアップからの切り替え」を作ってみました。

これ、AppleのWebサイトであったりしますよね。それを丸々参考にしました。笑

ポイントはいつもと違ってScrollMagicの「setPin」と「duration」を使い、よりスクロールと合わせた動きをさせたところです!

<div class="whitespace">
      <div class="phone_advance">
        <div class="img phone_scale">
          <img src="svg/advance_phone.svg" />
        </div>
      </div>
    </div>

    <div class="text">
      <p>
        僕の勝手な感覚ですが、大して結果も出していない低空飛行の状態でコロコロとやることなすことを変えていくのはちょっとダサい気がしていて、だからこのSpillは「ビジネス」みたいな側面を持たせずに「作品」という位置づけで留めたいと思ってます。
        SOSOでビジネスとしての結果を出すために、このSpillを楽しみながら進めていこうって感じ。
        それでは、Spillなんてカッコいい名前を付けといて何をするかが大事でしょというツッコミに答えます。
      </p>
    </div>
.whitespace {
  margin: 1000px auto 100px auto;
  position: relative;
  overflow: hidden;

  .img {
    width: 50%;
    display: block;
    margin: auto;
  }
}

.text {
  color: #fff;
  max-width: 350px;
  display: block;
  margin: 0 auto 500px auto;
  padding: 0 10px;
}
const phone_scale = new TimelineMax();

var advance_phone = phone_scale
  .to(".phone_scale", 1, {
    ease: Power3.linear,
    width: "200%",
  })
  .set("body", { backgroundColor: "#E86B79" })
  .set(".phone_advance", { display: "none" });

var pin_phone = new ScrollMagic.Scene({
  triggerElement: ".phone_advance",
  triggerHook: 0,
  duration: 500,
})
  .setTween(advance_phone)
  .setPin(".phone_advance")
  .addTo(controller);

今日のポッドキャスト

10/2のAdvance Everyday

昨日のイラスト

昨日のスクリプト

とにかく今日は家に帰ってからが大変だった。

とある依頼が来ていて、それに答えるべくこの「Advance」に関するドキュメントを急遽まとめなきゃいけないことになり、家についてすぐに作業を始めた。

具体的にはAdvanceのHPをある程度整えたりファビコンの設定、テキストの編集やイラストの作成などをしたのだが、これらは「3日後にはできていたらいいね」レベルのもので、ずっと後回しにしていたから、今回こうして急いで作る機会がくると精神的にはかなり辛いけど、その時間がガッツリ凝縮されて大きな前進をもたらしてくれるからすごく個人的にはウェルカムだなと感じた。

これからも「Advance」という名前に負けないよう、猛スピードで前進し続ける。

CODING MANUAL

今回も前回同様「前から作ってみたかったシリーズ」の第二弾。

背景に要素をつけてスクロールに応じて移動させたり大きくしたりする作業をしてみた。

もっと工夫のしようはあるが、ちょっと疲れていたので勘弁。。笑

const tweet = new TimelineMax();

var tweet_forcus = tweet.to(".svg_back", 0.5, {
  ease: Power3.linear,
  right: "-=150px",
  bottom: "-=150px",
});

var Tweetscene = new ScrollMagic.Scene({
  triggerElement: ".text_advance",
  triggerHook: 0.5,
})
  .setTween(tweet_forcus)
  .addTo(controller);
<div class="whitespace">
      <div class="text_advance">
        <div class="svg_back">
          <img src="svg/twitter_feed.svg" />
        </div>
        <p>
          僕の勝手な感覚ですが、大して結果も出していない低空飛行の状態でコロコロとやることなすことを変えていくのはちょっとダサい気がしていて、だからこのSpillは「ビジネス」みたいな側面を持たせずに「作品」という位置づけで留めたいと思ってます。
          SOSOでビジネスとしての結果を出すために、このSpillを楽しみながら進めていこうって感じ。
          それでは、Spillなんてカッコいい名前を付けといて何をするかが大事でしょというツッコミに答えます。
        </p>
      </div>
    </div>
.whitespace {
  margin: 1000px auto 1000px auto;
  position: relative;
  overflow: hidden;

  .svg_back {
    width: 100px;
    position: absolute;
    z-index: -1;
    opacity: 0.3;
  }
}

10/1のAdvance Everyday

昨日のイラスト

昨日のスクリプト

Web制作のスキルがあるといいこととして、「どこでもプロダクトを誰の手元でも見せられる」という点がありますよね。

これ、結構大事だと思ってて、今日も僕が何をしているのかという話題になり、学校で配布された友達のiPadで「advance.love/week1」と入力してアクセスするだけで、自分の力をリアルな距離感で感じてもらえたんですね。

「うわぁ、自分が手ぶらでも自分のことを知ってもらえるのってすごいことやな」

と感心してなおさらWebデザインが大好きになった一日でした。

CODING MANUAL

相変わらずイラストが雑だぁ…

今回も相変わらずScrollMagicとTweenMaxですが、昨日とは異なりTimelineMaxを使ってます。

というのも今回のテーマが「シーンがスクロールで進むにつれて固定された月の満ち欠け

が進んでいく」というアニメーションの実装で、「background-image」のすり替えをスムーズに、違和感なく行うことが必要だったからです。

ここは僕自身昔詰まったところで、というのもbackground-imageをすり替えるのって、transitionが効かないんです。

JavaScriptでも変更できないことはないようですが、自然な変化をさせるためにひと工夫必要だったのでシェアします!

const changemoon2 = new TimelineMax();

var changeMoon2 = changemoon2
  .to(".fixed_moon", 0.2, {
    ease: Power3.linear,
    opacity: 0,
  })
  .set(".fixed_moon", { className: "-=moon1" })
  .set(".fixed_moon", { className: "+=moon2" })
  .to(".fixed_moon", 0.5, { ease: Power3.linear, opacity: 1 });

var sceneChangeMoon = new ScrollMagic.Scene({
  triggerElement: ".object_moon2",
  triggerHook: 0.2,
})
  .setTween(changeMoon2)
  .addTo(controller);

const changemoon3 = new TimelineMax();

var changeMoon3 = changemoon3
  .to(".fixed_moon", 0.2, {
    ease: Power3.linear,
    opacity: 0,
  })
  .set(".fixed_moon", { className: "-=moon2" })
  .set(".fixed_moon", { className: "+=moon3" })
  .to(".fixed_moon", 0.5, { ease: Power3.linear, opacity: 1 });

var sceneChangeMoon = new ScrollMagic.Scene({
  triggerElement: ".object_moon3",
  triggerHook: 0.2,
})
  .setTween(changeMoon3)
  .addTo(controller);

鍵は「CSS」です!

今回、スタイルをこんな感じに書いています。

.fixed_moon {
  position: fixed;
  bottom: 20px;
  right: 20px;
  width: 70px;
  height: 70px;
  background-size: contain;
  background-repeat: no-repeat;
}

.moon1 {
  background-image: url("svg/moon1.svg");
}

.moon2 {
  background-image: url("svg/moon2.svg");
}

// 省略

.moon11 {
  background-image: url("svg/moon11.svg");
}
  .set(".fixed_moon", { className: "-=moon1" })
  .set(".fixed_moon", { className: "+=moon2" })

ここの記述によって、スタイルで予め書いておいたクラス名をつけたり外したりしています。

そして、background-imageをすり替える際は、がたつきを隠すために一度opacityを0まで下げて、次にクラスを付け替えてから再度opacityを1にすることで滑らかな変化を実現させてます。

我ながらいい書き方。

9/30のAdvance Everyday

昨日のイラスト

昨日のスクリプト

今日は火曜日で、昨日の疲れを引きずりながらも意地で4:30にアラームとともに起きた。

とにかく最近は早寝早起きを徹底していて、夜は22時から23時の間にベットにつくよう努めてるし、睡眠時間はしっかり取れているんだが、やっぱり夜に作業を中断するのがすごく気持ちが悪いし、朝起きれずに1日が台無しになってしまうこともあってもう少し慣れが必要な気がしてる。

前からポッドキャスト×ブログ記事っていうのが面白そうだなと思っていて、ついに今日の朝適当に収録した音源をもとにSpotifyにてポッドキャストを開設してみた。

学校の行きにストーリーでスクリーンショットとともに自分の朝の究極の鼻声を聴くよう友達に促して「聞くわ!」みたいなポジティブリアクションをたくさんもらえて最高の出だしだった。

朝早くに起きて通学・通勤前に1、2時間自分の好きな作業を進めることっていろいろメリットがありそうだなと感じた1日だった。

CODING MANUAL

前回のAdvance Week1で言っていたように、画像ごとの整理されたアニメーション以外に、画面全体でテキストも巻き込んだ大きなムーブメントを作れたらもっと魅力的になるんじゃないか、ということで、今日はこんなコンポーネントを実装してみました。

先ほどIllustratorでペンツールを使ったベジェ曲線の書き方を覚えまして、その練習も兼ねて適当に書いたキャラクターをSVGで書き出し、前回と同様ScrollMagicとTweenMaxでアニメーションさせています。

//全体の背景色をダークモードに

tobedark1 = new TweenMax.to(".toBeDark", 0.3, {
  backgroundColor: "#2c2c2c",
});

var scene1 = new ScrollMagic.Scene({
  triggerElement: ".toBeDark",
  triggerHook: 0.3,
})
  .setTween(tobedark1)
  .addTo(controller);

//SVGの背景を白に反転

const tobedark2 = new TweenMax.to(".advance_dark", 0.5, { fill: "#fff" });

var scene2 = new ScrollMagic.Scene({
  triggerElement: ".toBeDark",
  triggerHook: 0.2,
})
  .setTween(tobedark2)
  .addTo(controller);

//SVGを囲っている<div class="svg_tobedark">に対して。上の動画では書いていないコード!

const tobedark3 = new TweenMax.to(".svg_tobedark", 0.5, {
  scale: 1.1,
  rotation: 360,
});

var scene3 = new ScrollMagic.Scene({
  triggerElement: ".svg_tobedark",
  triggerHook: 0.2,
})
  .setTween(tobedark3)
  .addTo(controller);

//テキストカラーを反転

const tobedark4 = new TweenMax.to(".tobedark_p", 0.3, { color: "#fff" });

var scene4 = new ScrollMagic.Scene({
  triggerElement: ".toBeDark",
  triggerHook: 0.1,
})
  .setTween(tobedark4)
  .addTo(controller);

上のようにSVGに直接scaleやrotationを指定しまうと下のようにトリミングされてしまったので、上記のようにSVGを囲っているdiv要素に対しての指定をした。

(よく考えてみればwidthをdiv要素に対して指定していたから、SVGに対してscaleやrotationをさせて変になってしまうのは当然だった)

今日のポッドキャスト

今日9/30の朝は忙しくしてしまったので、本日のポッドキャストリンクは昨日テストで収録したものをシェアします。すみませんっ💦

Advance Week1 コーディングの振り返り(解説)

PRODUCT: https://advance.love/week1

今回の「Week1」はAdvanceの最初のプロダクトで、つくりながらどんなことができるかを考えてコーディングしていくような進め方をしました。

イラストをIllustratorで描くのも初めてだったし、アニメーションやコーディングを想定した描き方もしなかったのでまず1つ反省。

このブログ記事ではAdvanceの「コーディング」を振り返る内容にしようと思っていて、その書き方が正しいかどうかは正直僕は分からないです。

なので「あー、これってそういう書き方をしてたんや」「こういう書き方もできるんだ」といい具合に参考にしてもらえたら嬉しいです!

それではっ

全体の構成

ファイル構成

  • index.html
  • images – 画像素材(jpg、png)
  • javascript – index.js
  • scss – _content.scss、mixin.scss
  • svg – 画像素材(SVG)
  • style.scss
  • style.css

ファイル構成はこんな感じになってます。

エディタはVisual Studio Codeを使っていて、拡張プラグインの「Live Sass Compiler」でSASSを書いています。

AdvanceはSVG素材がメインのコンテンツなので、Illustratorでイラストを描いてからそれをsvg形式で書き出して「svg」というフォルダに格納しています。

また、「scss」フォルダの中に「_contenet.scss」と「_mixin.scss」がありますが、

_content.scssのindex.htmlのスタイルを書いているもので、

_mixin.scssにSASSの便利な書き方「mixin」をまとめています。

ファイル名に「_」をつけることで、style.scssに

@import "./scss/mixin";
@import "./scss/content";

と記述してstyle.cssにコードを書き出してくれる仕組みです。

セッティング

リセットCSS

スタイルを書く中で「なんでここに余白できちゃうの?」「margin: 0; にしてるんだけどなぁ」といろいろ思うようにいかないことがよくあります。

そんな悩みを解決してくれるのが「リセットCSS」で、これをコピペで使うことにより、意図しない挙動を防いでいます。

参考ページ: https://meyerweb.com/eric/tools/css/reset/

/* <http://meyerweb.com/eric/tools/css/reset/> 
   v2.0 | 20110126
   License: none (public domain)
*/

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
	margin: 0;
	padding: 0;
	border: 0;
	font-size: 100%;
	font: inherit;
	vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
	display: block;
}
body {
	line-height: 1;
}
ol, ul {
	list-style: none;
}
blockquote, q {
	quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
	content: '';
	content: none;
}
table {
	border-collapse: collapse;
	border-spacing: 0;
}

フォント

Webデザインをする上でフォントがかなり大事だということを最近になって意識するようになり、現時点ではGoogle Fontsしか利用したことがないのですが、今後MorisawaだったりAdobe Fontkitを活用していこうと思っています。

今回用いたのは「Noto Sans JP」と「Lato」、「Shadows Into Light」です。

@mixin Lato {
  font-family: "Lato, sans-serif";
}

こんな具合でmixinにして効率化したかったこともあり、特に意味はありませんが _mixin.scss の「@import」でそれらを読み込みました。

これもSASSの強みみたい!

@import url("<https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;500;700&display=swap>");
@import url("<https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400;1,700&display=swap>");
@import url("<https://fonts.googleapis.com/css2?family=Shadows+Into+Light&display=swap>");

CSSライブラリ

いつもindex.htmlの<head></head>内にAnimate.cssを読み込ませています。

<link rel="stylesheet"
      href="<https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css>"
    />

JavaScriptライブラリ

アニメーションだったりパララックス だったり、Webページに動きを与える際に何も考えずにすぐコードをかけるよう、必要か否かに関係なく、とりあえず最初にJavaScriptライブラリのCDNをまとめて</body>タグの直前にコピペしているものがこちら。↓

<script src="<https://cdnjs.cloudflare.com/ajax/libs/wow/1.1.2/wow.min.js>"></script>
    <script src="<https://cdnjs.cloudflare.com/ajax/libs/rellax/1.9.1/rellax.min.js>"></script>
    <script
      src="<https://code.jquery.com/jquery-3.5.1.js>"
      integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc="
      crossorigin="anonymous"
    ></script>
    <script src="<https://cdn.jsdelivr.net/scrollreveal.js/3.0.3/scrollreveal.min.js>"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.7/ScrollMagic.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.7/plugins/debug.addIndicators.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/gsap/latest/TweenMax.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.5/plugins/animation.gsap.min.js"></script>
    <script src="javascript/index.js"></script>

最後の「<script src=”javascript/index.js”></script>」はオリジナルでjavascriptフォルダに格納してあるファイルなので、それ以外が僕が普段使っているCDNたちになります。

上から

  • wow.js – もともとanimate.cssをスクロールと連携させるために使っていましたが、最近はanimate.css単体でスクロールアニメーションができるらしく、その書き方を学んで次第、出番がなくなっちゃうかも
  • Rellax.js – 簡単にパララックスを実装できるライブラリ。理由はないけど個人的に推し
  • jQuery – JavaScriptライブラリはjQueryに依存するケースが多いので読み込んでおくべし!
  • ScrollReveal.js – 要素を画角に入ったタイミングでアニメーションさせる、手軽でリッチなライブラリ
  • ScrollMagic – スクロールに応じたアニメーションを実装する際に使います
  • TweenMax – ScrollMagicと相性の良い最高のアニメーションライブラリ(超大好き)。TimelineMaxもここに含まれます。

イメージのアニメーション

パララックス を採用しなかった理由

個人的にパララックスが素敵なサイトを見ると「うわぁ、すき。」ってなるんですが、今回Advanceではこのパララックス 効果を使いませんでした。

普段なら先ほどのRellax.jsを大いに活用したいところだったのですが、このAdvanceがモバイルファーストで書いていくこともあり、アニメーションの自然さだったりヌルヌル感みたいなものを大事にしたかったんですね。

そこで1つ問題が生じたのが「スマホで見るとパララックスにがたつきが出る問題」でした。

PCで見る分には全く問題がない一方、スマホでスクロールをさせると細切れながたつきが出てしまって、これはどうしたものかと他のパララックスサイトをいくつが見てみたところ、スマホではどれもパララックス をさせていないことが判明しました。

PCでのスクロールに比べてスマホのスクロールは数値の取得が難しいのでしょうか(分からなくてごめんなさいっ)。

今回は他のサイトに習って、まず「スマホではパララックスを使わない」と決めました。

ただ、もう1つの問題が浮上してきて、最終的にはPCでもパララックスを使わず、完全にRellax.jsの役目がないままになってしまいまして、それは「ScrollMagicとパララックスの相性がよくなかった」ことが原因です。

例えば、

const tl7 = new TimelineMax();

tween7 = tl7
  .from(".number_m", 0.5, { scale: 4 })
  .from(".number_other", 0.3, { opacity: 0 });

var scene7 = new ScrollMagic.Scene({
  triggerElement: ".mail_svg",
  triggerHook: 0.5,
})
  .setTween(tween7)
  .addTo(controller);

こんなコードを書いた時に、スクリーンの中心に要素がきた時、アニメーションを起こすことになっていますよね。

ただ、この「<div class=”mail_svg”></div>」に

<div class="mail_svg rellax" data-rellax-speed="-1"></div>

などのパララックスをつけていた場合、一度ScrollMagicで設定した中央を通過した後、要素が下に下がっていってしまうので、すぐにアニメーションさせた後の状態からすぐ元に戻ってしまったんです。

スクロールに合わせて要素が動く前提でアニメーションを組んでいるので、スクロールとは別に要素が移動してしまうとすごく大変になっちゃうということで、今回はとりあえずパララックスの導入をしないことにしました。

SVGの活用

今回のAdvanceでは、SVGのアニメーションをたくさん取り入れたわけなんですが、「複数のSVGごとにアニメーションさせる」「色を変更する」「1つのSVGの一部をアニメーションさせる」の3つについて、現時点で僕が知っている実装の仕方を最後にシェアします。

(これもまた信憑性がない…)

「複数のSVGごとにアニメーションさせる」

これは通常通りScrollMagicとTweenMaxを使えば簡単に実装できます。

例えば

このアニメーションでは、まず右にあるタンブラーに対してrotationを指定して、その次に真ん中の水のopacityを0から1へ変化させ、最後にPCのopacityを少し下げながらscaleを小さくすることで実装しています。

TimelineMaxがすごい便利。

const tl1 = new TimelineMax();

tween1 = tl1
  .to(".tumblr", 0.5, { left: "-=30%" })
  .to(".tumblr", 0.5, { scale: 1.4, rotation: -45 })
  .from(".water", 0.5, { scale: 0.5, opacity: 0 })
  .to(".pc", 1, { scale: 0.95, opacity: 0.7 });

var scene1 = new ScrollMagic.Scene({
  triggerElement: ".pc", // 要素の指定
  triggerHook: 0.3, // トリガーのスクロール位置指定。onEnter, onLeaveの指定が可能
})
  .setTween(tween1) // Tweenアニメーション指定
  .addTo(controller); // コントローラへ追加

const tl2 = new TimelineMax();

こんな感じ。

「色を変更する」

これもJavaScript側で書くのですが、HTMLでSVGの表示のさせ方を少し変える必要があります。

僕は最初に全てのSVGを

<img src="svg/camera.svg" class="camera" />

と<img>タグで表示していたのですが、SVGの色を変更したりするためには、<svg>タグで記述してあげる必要があるそうです。

<div class="svg">
  <svg xmlns="<http://www.w3.org/2000/svg>" viewBox="0 0 1130.63 540.37">
    <defs>
      <style>
        .cls-1 {
          fill: #2c2c2c;
        }
      </style>
    </defs>
    <g id="レイヤー_2" data-name="レイヤー 2">
      <g id="描画レイヤー">
        <path
          class="cls-1 svg_colorchange"
          d="M174.75,117.46a75.89,75.89,0,0,0-8.52.87c-3.58.47-7.15,1-10.72,1.53A170.83,170.83,0,0,0,124,127.53a252,252,0,0,0-33.26,1
<-- 省略 -->
3.3,48.52,48.52,0,0,0-9.87-1.08Zm8.72,24.28h0l0,0,0,0ZM130.32,443.92c-1.63.7-3.25,1.4-4.89,2.07l4.89-2.07Z"
        />
      </g>
    </g>
  </svg>
</div>

コードが長くなってしまって見づらいのですが、Vidual Studio Codeの拡張プラグイン「Prettier」を有効化しておくと上のように<path>で整理してくれるので、細かいクラスの付与をする際にすごくわかりやすかったです!

もともとは<path>タグに「svg_colorchange」というクラスはついていなかったのですが、他のSVGとは別に固有のクラスを持たせることでTweenMaxで色の変更を指定することができます。

(cls-1 みたいなクラス名は他のSVGでも使われてたりするので)

「1つのSVGの一部をアニメーションさせる」

このストローが傾くアニメーションとかは、左の全体のグラスのSVGを上記と同様に<svg>タグで書いた後にストローをつくっている線の<path>にだけ名前をつけて、そのクラスに対してrotationを指定しています。

ただ、僕は「どのpathがストローを描いてるのか」を見つけるのに苦労したので、何か良い方法がないか模索してみます。

ちなみに今回はGoogle Chromeの「検証ツール」を用いて、対象のSVGをハイライトした後、コードを1つ1つ上からなぞっていき、対応している<path>に対してエディタからクラスをつけました。

今回の反省と展望

ここまでざざっと振り返りをしてきたのですが、illustratorで描く絵をもっとこんな適当なものではなく、魅力的なものにすることと、アニメーションを想定した設計にするべきだったと思いました。

そして、今回はところどころで出てくるSVGそれぞれにアニメーションを充てるようなつくりになりましたが、今後はスクリーン全体に対するアニメーション(「落ち込んだ」みたいな描写の際にダークモードみたいな表示に変化させる、背景のアニメーション、など)を実装して、もっとシネマティックな記事を実装したいと考えていますので、次回以降も温かく見守っていただけたら嬉しいです!

冒頭にも書きました通り、僕はまだまだ知識不足で、部分部分で間違った情報だったり非効率な書き方をしてると思います。

今後その内容に関しては、今後のブログ記事にて「この時のブログで書いたこれは間違ってました!!ごめんなさい!!」といった形で訂正していこうと思いますのでご理解いただけたら幸いです。

最後まで長くありがとうございました!