JavaScript5.6(クラス継承)

5から続きます

3:thisを使いこなす

mixinとSCSSは1と同じなので省略

HTMLの記述

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
<link rel="stylesheet" href="style.css">
<link href="https://fonts.googleapis.com/css2?family=Teko:wght@500&display=swap" rel="stylesheet">
</head>
<body>
  <div id="container">
  <div class="animate-title">
    PLAY ANIMATION
  </div>
  <div class="animate-title-2">
    ANIMATIONNNNNN
  </div>
    <button id="btn">Animation</button>
  </div>
  <script src="main.js"></script>
</body>
</html>

main.jsの記述

document.addEventListener("DOMContentLoaded", function () {
  const btn = document.querySelector("#btn");
  const ta = new TextAnimation(".animate-title");
  const ta2 = new TextAnimation(".animate-title-2");
  ta.animate();
  ta2.animate();
// btn.addEventListener('click', ta.animate.bind(ta));
// bindを使いたくないとき
  btn.addEventListener("click", function () {
    ta.animate();
  });
});

// フリーな位置にあるとグローバルオブジェクト(window)を参照する
console.log(this);

// new演算子を使うことによってオブジェクトを生成するためのもの
class TextAnimation {
  constructor(el) {
// 変数taとta2参照する
  console.log(this);
  this.el = document.querySelector(el);
  this.chars = this.el.innerHTML.trim().split("");
  this.el.innerHTML = this._splitText();
}
_splitText() {
  return this.chars.reduce((acc, curr) => {
  curr = curr.replace(/\s+/, " ");
  return `${acc}<span class="char">${curr}</span>`;
}, "");
}

// animate() {
// console.log(this);
// this.el.classList.toggle("inview");
// }

// タイムアウトを設定するとき
// animate() {
// // windowは省略できるよ
// window.setTimeout(function (){
// // ここのthisはwindowsオブジェクトを参照する
// console.log(this);
// this.el.classList.toggle('inview');
// // bindを用いたthisの束縛
// }.bind(this));
// }
// }

// こちらの書き方でもOK(bindを使わないときの記法)
animate() {
  const _that = this;
    setTimeout(function () {
    console.log(_that);
   _that.el.classList.toggle('inview');
  },1000
 )};
}

※ポイント

thisはフリーな位置にあるとグローバルオブジェクト(window)を参照するclass内のthisは変数taを参照する

bindを使った記法と使わない記法がある

4:クラス継承でコードを有効利用するには?

HTMLの記述

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <link rel="stylesheet" href="style.css">
  <link href="https://fonts.googleapis.com/css2?family=Teko:wght@500&display=swap" rel="stylesheet">
</head>
<body>
  <div id="container">
    <div class="tween-animate-title">
SUPER ANIMATION SUPER ANIMATION SUPER ANIMATION SUPER ANIMATION SUPER ANIMATION SUPER ANIMATION SUPER
ANIMATION SUPER ANIMATION SUPER ANIMATION SUPER ANIMATION SUPER ANIMATION SUPER ANIMATION SUPER ANIMATION
 </div>
</div>
  <script src="TweenMax.min.js"></script>
  <script src="main.js"></script>
</body>
</html>

TweenMax.min.jsを読みこませることで、簡単に複雑なアニメーションを使うことができる。

SCSSの記述mixinは1と同じなので省略

@import "mixin";

html {
  font-family: 'Teko', sans-serif;
}

body {
  margin: 0;
}

#container {
  position: relative;
  height: 100vh;
  background-color: teal;
}

.animate-title,
.tween-animate-title {
// position: absolute;
// top: 50%;
// left: 50%;
// transform: translate(-50%, -50%);
  color: white;
  opacity: 0;
  font-size: 2em;

  &.inview {
    opacity: 1;

  & .char {
    display: inline-block;
 }
}
// inviewがついてない状態で透明にする
  & .char {
    opacity: 0;
 }
}
// .animate-title.inviewがついたタイミングで内側に存在するcharの子要素に対して
.animate-title.inview .char{
@include animation(
$name: kf-animate-chars,
$duration: 0.5s,
$timing-function: cubic-bezier(0.39, 1.57, 0.58, 1),
$fill-mode: both
);

@for $i from 1 through 30 {
  &:nth-child(#{$i}) {
    animation-delay: $i * 0.04s;
  }
 }
}
@keyframes kf-animate-chars {
  0% {
    opacity: 0;
    transform: translateY(-50%);
}

100% {
    opacity: 1;
    transform: translateY(0);
 }
}

main.jsの記述

document.addEventListener('DOMContentLoaded', function () {
  const ta = new TweenTextAnimation('.tween-animate-title');
  ta.animate();
});

// <span class>文字</span>としたい、空白も表現したい
class TextAnimation {
  constructor(el) {
// オブジェクトリテラルで初期化する
    this.DOM = {};
    this.DOM.el = document.querySelector(el);
    this.chars = this.DOM.el.innerHTML.trim().split("");
    this.DOM.el .innerHTML = this._splitText();
}
  _splitText() {
    return this.chars.reduce((acc, curr) => {
    curr = curr.replace(/\s+/, ' ');
    return `${acc}<span class="char">${curr}</span>`;
  }, "");
}
  animate() {
    this.DOM.el .classList.toggle('inview');
 }
}
// 継承を宣言する
  class TweenTextAnimation extends TextAnimation {
    constructor(el) {
// 親のコンストラクタを呼び出す
    super(el);
    console.log(el);
    this.DOM.chars = this.DOM.el.querySelectorAll('.char');
    console.log(this.DOM.chars);
    console.log(this.chars);
}
// 記載を書き換えたい(オーバーライド)場合
  animate() {
// inviewをつける
    this.DOM.el.classList.add('inview')
// iがないとi is not definedとなるよ
    this.DOM.chars.forEach((c, i) => {
// TweenMaxの書き方(toメソッド)
// 第一引数にDOM、第二引数が対象となるDOMアニメーションの間隔
     TweenMax.to(c, .6, {
// オプションeaseファンクション,delayの間隔,始まる状態
     ease: Back.easeOut,
     delay: i * .05,
// アニメーションの始まる状態
     startAt: { y: '-50%', opacity: 0},
// 終了時の状態透明度解除
     y: '0%',
     opacity: 1
   });
  });
 }
}

// この部分継承することでカットした部分
// this.dom.el = document.querySelector(el);
// this.chars = this.dom.el .innerHTML.trim().split("");
// this.dom.el .innerHTML = this._splitText();
// }
// _splitText() {
// return this.chars.reduce((acc, curr) => {
// curr = curr.replace(/\s+/, ' ');
// return `${acc}<span class="char">${curr}</span>`;
// }, "");
// }

継承することでコードの量が減りDRYになった

検証して実行結果を確かめると・・・

※テキストアニメーションのまとめ

HTMLの部分

①まず初めに<div id=”container”>の中に入れる

②<div class=”animate-title”>の中にアニメーションしたい文言を入れる

③ボタンを作成してinviewのときにクリックしたらアニメーションするように記述する。

SCSSの部分

①mixinをインポートする。mixinとはモジュール

②bodyやcontainerで初期設定を行う(余白消したり背景色決めたり)

③.animate-titleにて画面真ん中に中央寄せで表示するための設定をする。

④inviewの状態の時透明度を解除する設定をする。

⑤.charにアニメーションの設定を記述する

⑥@includeanimationにてアニメーションの具体的な設定を記述する。

その6に続きます。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です