文字が順番に表示できるアニメーションを作成していたのですが見本と見比べてもどこが間違ってるのかわかりません
どなたかわかる方ご教授よろしくお願いいたします
【HTML】
<!DOCTYPE html> <html lang="ja"> <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"> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.13/css/all.css" integrity="sha384-DNOHZ68U8hZfKXOrtjWvjxusGo9WQnrNx2sqG0tfsghAvtVlRW3tvkXWZh58N9jp" crossorigin="anonymous"> <link href="https://fonts.googleapis.com/css2?family=Teko:wght@500&display=swap" rel="stylesheet"> <link rel="stylesheet" href="style.css"> <title>Document</title> </head> <body> <section></body> </html><div class="animate-title"> where you are.</div> </section> <section> <div class="animate-title">Use what you have.</div> </section> <section> <div class="animate-title">Do what you can.</div> </section> <script src="text-animation.js"></script> <script src="main.js"></script>
【SCSS】
@import "mixin";
html {
font-family: "Teko", sans-serif;
}
body {
margin: 0;
}
section {
position: relative;
height: 100vh;
background-color: teal;
&:nth-child(2) {
background-color: rgb(138, 43, 201);
}
&:nth-child(3) {
background-color: orange;
}
}
.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; }
}
& .char {
opacity: 0;
}
}
.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);
}
}
【javascript (text-animation.js)】
class TextAnimation {
constructor(el) {
this.DOM = {};
this.DOM.el = el instanceof HTMLElement ? 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);
this.DOM.chars = this.DOM.el.querySelectorAll('.char');
}
animate() { this.DOM.el.classList.add('inview'); this.DOM.chars.forEach((c, i) => { TweenMax.to(c, .6, { ease: Back.easeOut, delay: i * .05, startAt: { y: '-50%', opacity: 0}, y: '0%', opacity: 1 }); }); }
}
【javascript (main.js)】
document.addEventListener('DOMContentLoaded', function () {
const cb = function (el, isIntersecting) {
if(isIntersecting) {
const ta = new TextAnimation(el);
ta.animate();
}
}
});
const so = new ScrollObserver('.animate-title', cb);
class ScrollObserver {
constructor(els, cb, options) {
this.els = document.querySelectorAll(els);
const defaultOptions = {
root: null,
rootMargin: '0px',
threshold: 0,
};
this.cb = cb;
this.options = Object.assign(defaultOptions, options);
this._init();
}//constructor
_init() {
const callback = function (entries, observer){
entries.forEach(entry => {
if(entry.isIntersecting) {
this.cb(entry.target, true);
observer.unobserve(entry.target);
}else {
this.cb(entry.target, false);
}
});
};
const io = new IntersectionObserver(callback.bind(this), this.options);
this.els.forEach(el => io.observe(el));
}
}
回答1件
あなたの回答
tips
プレビュー