2021.09.26

iPhone12が発表されたのでAppleのWebページはScrollMagicとGSAPで実装できるのか検証してみた!

お疲れ様です!

先日10/14に開催されたAppleの製品発表会で噂通りiPhone12が発表されましたね!

今僕はiPhone8を使っているのでホームボタンがないiPhoneを早く持ちたいと思っているのですが、それよりも心躍ったのは「そういえばAppleのWebページって今の自分の知識でもなんとか実装できるんじゃないの!?」という気付き。

 

AppleのWebデザインはとんでもなく新規性があってクールで毎回驚かされます。
もちろん「デザイン」からあのレベルのものを考えられる自信はまったくありませんが、でも「コーディング」のフェーズに特化して言えば「まだ頑張れるぞ!!」と思い、AppleのWebページを今の自分のナレッジで実装してみようと奮起しましたので、この記事ではそのまとめをしていきます!

 

「飛ぶように、つぎの次元へ。」

今回は相性の良い高機能なScrollMagicとGSAP3のみを用いてAppleのiPhone12の公式ページの部分部分を実装していきます。(ScrollMagicとGSAPしか使えない)

まずはiPhone12のトップビジュアルから見ていきたいのですが、この特徴はタイトルと画像でスクロールアップする速度が若干異なるパラパックスが使われている点。

Rellax.jsなどのパララックス ライブラリを使っても良いのですが、これらはモバイルで見たときに細かいがたつきが出てしまうので、おすすめはCSSのtransformをうまく使うこと。

<body>
    <div class="white_space"></div>
    <h3 class="h3_progress">ベゼルを削って、スクリーンを広く。</h3>
    <img src="aboutlink.jpg" class="img" alt="" />
    <div class="white_space"></div>
    <script
      src="https://cdnjs.cloudflare.com/ajax/libs/vivus/0.4.5/vivus.min.js"
      integrity="sha512-NBLGIjYyAoYAr23l+dmAcUv7TvFj0XrqZoFa4i1o+F2VvF9SrERyMD8BHNnJn1SEGjl1AouBDcCv/q52L3ozBQ=="
      crossorigin="anonymous"
    ></script>
    <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://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/gsap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/ScrollTrigger.min.js"></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/ScrollMagic/2.0.5/plugins/animation.gsap.min.js"></script>
    <script src="javascript/scrolleo.js"></script>
    <script src="javascript/index.js"></script>
  </body>
.h3_progress {
  font-size: 30px;
  text-align: center;
  margin: 0 auto 100px auto;
}
.img {
  width: 600px;
  height: auto;
  display: block;
  margin: auto;
  transform-origin: center;
}
var parallax = gsap.to(".img", {
  y: -150,
});
var scene_parallax = new ScrollMagic.Scene({
  triggerElement: ".h3_progress",
  triggerHook: 0.3,
  duration: 100,
})
  .setTween(parallax)
  .addTo(controller);

「医療に使われるレベルの
ステレンススチール」

こちらに関してはコードをそのまま使っているのと数字をいじったためがたつきが酷くなってます。参考にさせていただいた記事をご覧になった方がいいかもしれないです。。

 

スクロールに応じて動画が再生される仕組みですが、これは現時点ではどうしても一定のがたつきが目立ってしまうみたいです。

「Scrolleo」というスクリプトを採用しているらしく、これはScrollMagicともGSAPとも無関係ですが、個人的にどんな技術を使っているのか気になったのでご紹介。

参考にさせていただいた(というよりモロそのままじゃないか…)記事のリンクです。↓

https://b.hatena.ne.jp/entry/s/coliss.com/articles/build-websites/operation/javascript/videos-reacting-to-scrolling-inspired-by-apple.html

  <body>
    <div class="white_space"></div>
    <div style="margin-top: 100vh">
      <h3>スクロールに応じた動画の再生!</h3>
      <!-- Video 1 -->
      <video
        id="scrolleo-1"
        width="100%"
        height="100%"
        autobuffer="autobuffer"
        preload="preload"
      >
        <source src="photographer.mp4" />
      </video>
    </div>
    <div class="white_space"></div>
    <script
      src="https://cdnjs.cloudflare.com/ajax/libs/vivus/0.4.5/vivus.min.js"
      integrity="sha512-NBLGIjYyAoYAr23l+dmAcUv7TvFj0XrqZoFa4i1o+F2VvF9SrERyMD8BHNnJn1SEGjl1AouBDcCv/q52L3ozBQ=="
      crossorigin="anonymous"
    ></script>
    <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://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/gsap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/ScrollTrigger.min.js"></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/ScrollMagic/2.0.5/plugins/animation.gsap.min.js"></script>
    <script src="javascript/scrolleo.js"></script>
    <script src="javascript/index.js"></script>
  </body>
.white_space {
  width: 100%;
  display: block;
  height: 100vh;
  background-color: #fff;
}
var scrolleo1 = new Scrolleo({
  acceleration: 1, // 1 = instant, 0 = never
  secondsPerScreen: 4, // Defaults to video duration
  additionalOffset: -500, // Positive starts the video later, negative starts earlier. default starts when top of video hits bottom of the screen
  wrapperEl: "#scrolleo-1", // id of the video you want to control
});
scrolleo1.init();

「こんにちは、5G。」

動画がダウンロードされているマークのみSVGが使用されています。

<body>
    <div class="white_space"></div>
    <div class="phone">
      <h3>ダウンロード済み</h3>
      <hr />
      <div class="movie">
        <img src="movie.png" alt="" />
        <h4>グレイハウンド<span>1時間31分・2020</span></h4>
        <div class="svg">
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="-20 -20 220 220">
            <defs>
              <style>
                .cls-1 {
                  fill: none;
                }
              </style>
            </defs>
            <g id="レイヤー_2" data-name="レイヤー 2">
              <g id="レイヤー_1-2" data-name="レイヤー 1">
                <rect class="cls-1 apple" width="177" height="177" rx="88.5" />
              </g>
            </g>
          </svg>
        </div>
      </div>
      <div class="movie_under"></div>
    </div>
    <div class="white_space"></div>
    <script
      src="https://cdnjs.cloudflare.com/ajax/libs/vivus/0.4.5/vivus.min.js"
      integrity="sha512-NBLGIjYyAoYAr23l+dmAcUv7TvFj0XrqZoFa4i1o+F2VvF9SrERyMD8BHNnJn1SEGjl1AouBDcCv/q52L3ozBQ=="
      crossorigin="anonymous"
    ></script>
    <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://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/gsap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/ScrollTrigger.min.js"></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/ScrollMagic/2.0.5/plugins/animation.gsap.min.js"></script>
    <script src="javascript/scrolleo.js"></script>
    <script src="javascript/index.js"></script>
  </body>
.white_space {
  width: 100%;
  display: block;
  height: 100vh;
  background-color: #000000;
}
.phone {
  width: 650px;
  height: 1500px;
  display: block;
  margin: auto;
  background-color: #000000;
  border: 4px solid #00bfff;
  border-radius: 30px;
  box-shadow: 0 0 30px gray;
  h3 {
    font-size: 40px;
    color: #fff;
    margin: 50px auto 10px 40px;
    font-family: "Noto Sans JP";
  }
  hr {
    background-color: gray;
    opacity: 0.2;
    width: 620px;
    text-align: center;
    margin: 0 auto 50px auto;
  }
  .movie {
    width: 600px;
    height: 180px;
    display: flex;
    margin: auto;
    flex-wrap: nowrap;
    justify-content: space-between;
    align-items: center;
    background-color: transparent;
    img {
      width: 220px;
      height: auto;
    }
    h4 {
      font-size: 15px;
      color: #fff;
      span {
        display: block;
        color: gray;
        font-size: 10px;
      }
    }
    .svg {
      width: 80px;
      height: 80px;
      display: block;
      fill: transparent;
      .apple {
        stroke: #4fa8df;
        stroke-width: 25;
        stroke-dasharray: 600;
        stroke-dashoffset: 600;
      }
    }
  }
  .movie_under {
    width: 600px;
    height: 180px;
    display: flex;
    margin: auto;
    flex-wrap: nowrap;
    justify-content: space-between;
    align-items: center;
    background-color: transparent;
    border-top: 1px solid #484848;
    opacity: 0;
  }
}
var apple = gsap.to(".apple", {
  strokeDashoffset: 0,
});
var scene_apple = new ScrollMagic.Scene({
  triggerElement: ".phone",
  triggerHook: 0.4,
  duration: 400,
})
  .setTween(apple)
  .addTo(controller);
var movie = gsap
  .timeline()
  .from(".movie", {
    scale: 1.7,
    opacity: 0.4,
    y: 300,
  })
  .to(".movie_under", {
    opacity: 1,
  });
var scene_movie = new ScrollMagic.Scene({
  triggerElement: ".phone",
  triggerHook: 0.3,
  duration: 400,
})
  .setTween(movie)
  .addTo(controller);

「ライバルは、
一つ前のiPhoneのチップだけ。」

https://twitter.com/Shun21002526/status/1325532718721949696

これを見ていただければわかると思いますが、青い淵はborderで描いているのではなく、ボックスを狭い隙間をとって並べて、全体の背景に複数の円状にグラデーションがかかった画像を置き、先ほど同様transformで絶妙にスクロールスピードより早くシフトさせることで、青がスクロールに応じて光っているように見えるようになっています。

これを見つけたとき僕はあまりの驚きと感動に20秒ほど開いた口が塞がらなかったです。恐るべしApple。

 <body>
    <div class="white_space"></div>
    <div class="whole">
      <div class="backlights">
        <img src="image/gradient_cercle.png" class="light1" alt="" />
        <img src="image/gradient_cercle.png" class="light2" alt="" />
        <img src="image/gradient_cercle.png" class="light3" alt="" />
      </div>
      <div class="grid">
        <div class="box1"></div>
        <div class="box2">
          <h2 class="box_text1">Appleの<br />製品ページは</h2>
        </div>
        <div class="box3"></div>
        <div class="box4">
          <h2 class="box_text2">素敵</h2>
        </div>
        <div class="box5"></div>
        <div class="box6">
          <h2 class="box_text3">アイディアが<br />すごい</h2>
        </div>
        <div class="box7"></div>
        <div class="box8">
          <h2 class="box_text3">
            実現できる<br />範囲でデザインを<br />考えるって
          </h2>
        </div>
        <div class="box9">
          <h2 class="box_text4">思ってるよりすごい</h2>
        </div>
        <div class="box10"></div>
      </div>
    </div>
    <div class="white_space"></div>
    <script
      src="https://cdnjs.cloudflare.com/ajax/libs/vivus/0.4.5/vivus.min.js"
      integrity="sha512-NBLGIjYyAoYAr23l+dmAcUv7TvFj0XrqZoFa4i1o+F2VvF9SrERyMD8BHNnJn1SEGjl1AouBDcCv/q52L3ozBQ=="
      crossorigin="anonymous"
    ></script>
    <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://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/gsap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/ScrollTrigger.min.js"></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/ScrollMagic/2.0.5/plugins/animation.gsap.min.js"></script>
    <script src="javascript/index.js"></script>
  </body>

 

.white_space {
  width: 100%;
  display: block;
  height: 100vh;
  background-color: #000000;
}
.whole {
  width: 700px;
  height: 100vh;
  display: block;
  margin: auto;
  position: relative;
  overflow: hidden;
  .backlights {
    width: 100%;
    height: 100vh;
    position: absolute;
    top: 0;
    img {
      width: 300px;
      height: auto;
      display: block;
      transform-origin: center;
    }
    .light1 {
      position: absolute;
      top: -100px;
      right: 50px;
      opacity: 0;
    }
    .light2 {
      position: absolute;
      top: 180px;
      left: 0;
      right: 0;
      display: block;
      margin: auto;
      opacity: 0;
    }
    .light3 {
      position: absolute;
      top: 400px;
      left: 50px;
      opacity: 0;
    }
  }
  .grid {
    position: absolute;
    top: 0;
    display: grid;
    grid-template:
      "head_left head_left head_right"
      "second_left second_center second_right"
      "third_left third_center third_right"
      "bottom_left bottom_right bottom_right";
    width: 100%;
    min-height: 100vh;
    gap: 15px;
    h2 {
      color: #fff;
      font-family: "Noto Sans JP";
      line-height: 2;
    }
    .box1 {
      grid-area: head_left;
      background-color: #000000;
      box-shadow: 0 0 3px gray;
    }
    .box2 {
      grid-area: head_right;
      background-color: #000000;
      box-shadow: 0 0 3px gray;
      display: flex;
      justify-content: center;
      align-items: center;
      h2 {
        font-size: 22px;
      }
    }
    .box3 {
      grid-area: second_left;
      background-color: #000000;
      box-shadow: 0 0 3px gray;
    }
    .box4 {
      grid-area: second_center;
      background-color: #000000;
      box-shadow: 0 0 3px gray;
      display: flex;
      justify-content: center;
      align-items: center;
      h2 {
        font-size: 50px;
      }
    }
    .box5 {
      grid-area: second_right;
      background-color: #000000;
      box-shadow: 0 0 3px gray;
    }
    .box6 {
      grid-area: third_left;
      background-color: #000000;
      box-shadow: 0 0 3px gray;
      display: flex;
      justify-content: center;
      align-items: center;
      h2 {
        font-size: 23px;
      }
    }
    .box7 {
      grid-area: third_center;
      background-color: #000000;
      box-shadow: 0 0 3px gray;
    }
    .box8 {
      grid-area: third_right;
      background-color: #000000;
      box-shadow: 0 0 3px gray;
      display: flex;
      justify-content: center;
      align-items: center;
      h2 {
        font-size: 23px;
      }
    }
    .box9 {
      grid-area: bottom_left;
      background-color: #000000;
      box-shadow: 0 0 3px gray;
      display: flex;
      justify-content: center;
      align-items: center;
      h2 {
        font-size: 22px;
      }
    }
    .box10 {
      grid-area: bottom_right;
      background-color: #000000;
      box-shadow: 0 0 3px gray;
    }
  }
}

「ポートレートモードに、
夜の表情を。」

今回のiPhone12では画像が後ろから現れて後からテキストが続くようなちょっとお洒落だけど似たようなレイアウトをよく見るこのシーンが多く使われていましたね!

 <body>
    <div class="white_space"></div>
    <div class="photo">
      <div class="text_cover">
        <h1>誰よりも、美しく。</h1>
      </div>
      <div class="whole">
        <img src="image/girl.jpg" class="mainimg" alt="" />
        <p class="detail">
          ナイトモードのポートレートを広角カメラで。明かりに照らされた建物や街灯など、背景のあらゆる光を際立たせながら、あざやかな色と美しいボケのある写真が撮れます。
        </p>
      </div>
    </div>
    <div class="white_space"></div>
    <script
      src="https://cdnjs.cloudflare.com/ajax/libs/vivus/0.4.5/vivus.min.js"
      integrity="sha512-NBLGIjYyAoYAr23l+dmAcUv7TvFj0XrqZoFa4i1o+F2VvF9SrERyMD8BHNnJn1SEGjl1AouBDcCv/q52L3ozBQ=="
      crossorigin="anonymous"
    ></script>
    <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://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/gsap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/ScrollTrigger.min.js"></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/ScrollMagic/2.0.5/plugins/animation.gsap.min.js"></script>
    <script src="javascript/index.js"></script>
  </body>
.white_space {
  width: 100%;
  display: block;
  height: 100vh;
  background-color: #000000;
}
.photo {
  display: block;
  width: 800px;
  margin: auto;
  .text_cover {
    width: 100%;
    height: 700px;
    display: block;
    margin: auto;
    position: relative;
    z-index: 2;
    background: linear-gradient(rgba(0, 0, 0, 1), rgba(0, 0, 0, 0));
    h1 {
      margin: 0 0 0 10px;
      color: #fff;
      font-size: 40px;
      font-family: "Noto Sans JP";
    }
  }
  .whole {
    transform-origin: top;
    margin: -600px auto 20px auto;
    .mainimg {
      width: 100%;
      display: block;
      margin: 0 auto 20px auto;
    }
    .detail {
      width: 700px;
      display: block;
      margin: auto;
      font-size: 15px;
      color: #fff;
      line-height: 1.2;
      font-family: "Noto Sans JP";
    }
  }
}

var photo = gsap
  .timeline()
  .from(".whole", {
    scale: 0.8,
    opacity: 0.3,
  })
  .from(".detail", {
    opacity: 0,
    ease: Circ.easeOut,
  });
var scene_photo = new ScrollMagic.Scene({
  triggerElement: ".whole",
  triggerHook: 0.2,
  duration: 600,
})
  .setTween(photo)
  .setPin(".whole")
  .addTo(controller);

「使いたいものが
すぐに使える。」

ScrollMagicとGSAPの集大成って感じですね。

でも1つ1つを見つめればこれまでのコーディングと大きく異なる箇所はありません。

僕の場合はiPhoneの上に乗っているアプリの動きをiPhone基準で作ってから、それと同時に全体の3つのiPhoneを縮小させるアニメーションを発火させています。

  <body>
    <div class="white_space"></div>
    <div class="apple_ios">
      <div class="phone1">
        <img src="svg/phone_object1.svg" alt="" />
      </div>
      <div class="phone2">
        <img src="svg/phone_object2.svg" class="img1" alt="" />
        <img src="svg/icon1.svg" class="img2" alt="" />
        <img src="svg/icon2.svg" class="img3" alt="" />
        <img src="svg/icon3.svg" class="img4" alt="" />
        <img src="svg/icon4.svg" class="img5" alt="" />
        <img src="svg/icon5.svg" class="img6" alt="" />
        <img src="svg/icon6.svg" class="img7" alt="" />
        <img src="svg/icon7.svg" class="img8" alt="" />
        <img src="svg/icon8.svg" class="img9" alt="" />
      </div>
      <div class="phone3">
        <img src="svg/phone_object3.svg" alt="" />
      </div>
    </div>
    <div class="white_space"></div>
    <script
      src="https://cdnjs.cloudflare.com/ajax/libs/vivus/0.4.5/vivus.min.js"
      integrity="sha512-NBLGIjYyAoYAr23l+dmAcUv7TvFj0XrqZoFa4i1o+F2VvF9SrERyMD8BHNnJn1SEGjl1AouBDcCv/q52L3ozBQ=="
      crossorigin="anonymous"
    ></script>
    <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://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/gsap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/ScrollTrigger.min.js"></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/ScrollMagic/2.0.5/plugins/animation.gsap.min.js"></script>
    <script src="javascript/index.js"></script>
  </body>
.white_space {
  width: 100%;
  display: block;
  height: 100vh;
  background-color: #000000;
}
.apple_ios {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  width: 1000px;
  margin: auto;
  background-color: #000000;
  transform-origin: top;
  .phone1,
  .phone3 {
    width: 300px;
    img {
      width: 100%;
      height: auto;
    }
  }
  .phone2 {
    width: 300px;
    position: relative;
    .img1 {
      width: 100%;
      z-index: -1;
    }
    .img2,
    .img3,
    .img6,
    .img7,
    .img8 {
      width: 60px;
    }
    .img4,
    .img5,
    .img9 {
      width: 120px;
    }
    .img2 {
      position: absolute;
      top: 60px;
      left: 20px;
    }
    .img3 {
      position: absolute;
      top: 60px;
      left: 90px;
    }
    .img4 {
      position: absolute;
      top: 60px;
      right: 20px;
    }
    .img5 {
      position: absolute;
      top: 250px;
      left: 20px;
    }
    .img6 {
      position: absolute;
      top: 250px;
      right: 90px;
    }
    .img7 {
      position: absolute;
      top: 310px;
      right: 20px;
    }
    .img8 {
      position: absolute;
      bottom: 60px;
      left: 20px;
    }
    .img9 {
      position: absolute;
      bottom: 60px;
      right: 20px;
    }
  }
}
var whole_ios = gsap.from(".apple_ios", {
  scale: 2.5,
});
var scene_whole_ios = new ScrollMagic.Scene({
  triggerElement: ".apple_ios",
  triggerHook: 0.2,
  duration: 1000,
})
  .setTween(whole_ios)
  .setPin(".apple_ios")
  .addTo(controller);
var with1 = gsap.from(".img1", {
  opacity: 0.1,
});
var scene_with1 = new ScrollMagic.Scene({
  triggerElement: ".apple_ios",
  triggerHook: 0.2,
  duration: 1000,
})
  .setTween(with1)
  .addTo(controller);
var with2 = gsap.from(".img2", {
  x: -200,
  y: -30,
  scale: 1.5,
});
var scene_with2 = new ScrollMagic.Scene({
  triggerElement: ".apple_ios",
  triggerHook: 0.2,
  duration: 1000,
})
  .setTween(with2)
  .addTo(controller);
var with3 = gsap.from(".img3", {
  x: -80,
  y: 80,
  scale: 1.5,
});
var scene_with3 = new ScrollMagic.Scene({
  triggerElement: ".apple_ios",
  triggerHook: 0.2,
  duration: 1000,
})
  .setTween(with3)
  .addTo(controller);
var with4 = gsap.from(".img4", {
  x: 320,
  y: -30,
  scale: 1.5,
});
var scene_with4 = new ScrollMagic.Scene({
  triggerElement: ".apple_ios",
  triggerHook: 0.2,
  duration: 1000,
})
  .setTween(with4)
  .addTo(controller);
var with5 = gsap.from(".img5", {
  x: -400,
  scale: 1.5,
});
var scene_with5 = new ScrollMagic.Scene({
  triggerElement: ".apple_ios",
  triggerHook: 0.2,
  duration: 1000,
})
  .setTween(with5)
  .addTo(controller);
var with6 = gsap.from(".img6", {
  x: 200,
  y: -200,
  scale: 1.5,
});
var scene_with6 = new ScrollMagic.Scene({
  triggerElement: ".apple_ios",
  triggerHook: 0.2,
  duration: 1000,
})
  .setTween(with6)
  .addTo(controller);
var with7 = gsap.from(".img7", {
  x: 320,
  y: 120,
  scale: 1.5,
});
var scene_with7 = new ScrollMagic.Scene({
  triggerElement: ".apple_ios",
  triggerHook: 0.2,
  duration: 1000,
})
  .setTween(with7)
  .addTo(controller);
var with8 = gsap.from(".img8", {
  x: -200,
  y: 200,
  scale: 1.5,
});
var scene_with8 = new ScrollMagic.Scene({
  triggerElement: ".apple_ios",
  triggerHook: 0.2,
  duration: 1000,
})
  .setTween(with8)
  .addTo(controller);
var with9 = gsap.from(".img9", {
  x: 320,
  y: 320,
  scale: 1.5,
});
var scene_with9 = new ScrollMagic.Scene({
  triggerElement: ".apple_ios",
  triggerHook: 0.2,
  duration: 1000,
})
  .setTween(with9)
  .addTo(controller);

どうでしたか??

個人的にはやっぱりAppleの「神は細部に宿る」って感じの凄さをコーディングしながら感じました。

やっぱりプログラミング勉強中の人間が挑戦しようとしても見た目がどうしてもまとまらなかったりダサくなったり、安っぽく見えてしまいます。

Webデザインにおいて共通することだとは思いますが、大事なのは「デザイン」で、「コーディング」に関してはさしてレベルの高い技術が求められるわけではないということを実感しました。

#apple偉大

村木 瞬Shun Muraki
Web Designer

Neutral between linear and non-linear.

デジタルメディアのフォーマット
「Linear Native」について研究。

テーマは”リニアとノンリニアのニュートラル”