文字列アニメーションツール「text-appear」について
LPの目的は、商品などの広告や、何かしらの告知なので、伝えたいキーワードが明確になっています。 たまに、ゴチャゴチャ小さい文字が書かれているだけのページもありますが、アレ、何の意味もない効果の薄いページだという事に気がついていないのが残念ですね。 でも、効果時に文字を見せるコツとして、比較的目立つ感じの大きめの文字が、スクロールインしてきた時に、フワッと浮き上がってきて、確実に目線がそこにいくようにする、 そんな効果を毎回作っているとしんどいので、class名を書き込むだけ簡単に実装できるライブラリを作ってみました。これがサンプルです。
ソース
(function(){
let __options = {
selector : ".text-appear",
target_className : "text-appear-word",
appear_speed : 100 // *ms
};
function MAIN(){
this.options = __options;
this.event();
this.init();
this.scroll();
}
MAIN.prototype.event = function(){
window.addEventListener("scroll" , this.scroll.bind(this));
window.addEventListener("resize" , this.scroll.bind(this));
};
MAIN.prototype.init = function(){
let elms = document.querySelectorAll(this.options.selector);
for(let elm of elms){
this.set_split_value(elm);
}
};
MAIN.prototype.set_split_value = function(elm){
if(!elm || !elm.innerHTML){return;}
let new_elm = document.createElement("div");
let num = 0;
while(elm.innerHTML){
let delay_num = (num * this.options.appear_speed);
switch(elm.firstChild.nodeType){
// element
case 1:
elm.style.setProperty("animation-delay" , delay_num +"ms");
new_elm.appendChild(elm.firstChild);
num++;
break;
// text
case 3:
let word = elm.firstChild.textContent.slice(0,1);
elm.firstChild.textContent = elm.firstChild.textContent.slice(1);
// 改行コード
if(word === "\n"){
let new_text = document.createTextNode(word);
new_elm.appendChild(new_text);
}
// 文字列
else{
let span = document.createElement("span");
span.className = this.options.target_className;
span.style.setProperty("animation-delay" , delay_num +"ms");
span.textContent = word;
new_elm.appendChild(span);
num++;
}
if(elm.firstChild.textContent === ""){
elm.removeChild(elm.firstChild);
}
break;
}
}
elm.innerHTML = new_elm.innerHTML;
elm.setAttribute("data-view","1");
};
MAIN.prototype.scroll = function(e){
var h = this.get_pageheight();
// 対象エレメントがページ表示エリアに入った場合にフラグを立てる
let elms = document.querySelectorAll(this.options.selector);
for(let elm of elms){
let rect = elm.getBoundingClientRect();
if(elm.getAttribute("data-anim") !== "1"
// && rect.top > -rect.height +100
&& rect.top > -100
&& rect.top - h < -100){
elm.setAttribute("data-anim" , "1");
}
else if(elm.getAttribute("data-repeat") !== "0"
&& elm.getAttribute("data-anim") === "1"
&& rect.top - h > 0){
elm.setAttribute("data-anim" , "0");
}
else if(elm.getAttribute("data-repeat") !== "0"
&& elm.getAttribute("data-anim") === "1"
&& rect.top < (-rect.height)){
console.log(2);
elm.setAttribute("data-anim" , "0");
}
}
};
MAIN.prototype.get_scroll_y = function(){
return document.scrollingElement.scrollTop;
};
MAIN.prototype.get_pageheight = function(){
return window.innerHeight;
};
MAIN.prototype.get_pagesize = function(){
return document.scrollingElement.scrollHeight;
}
switch(document.readyState){
case "complete" : new MAIN();break;
default : window.addEventListener("load" , function(){new MAIN()});break;
}
})()
:root{
--size-move-distance:50px;
--anim-duration:500ms;
}
.text-appear{
display:none;
}
.text-appear[data-view="1"]{
display:block;
}
.text-appear,
.text-appear .text-appear-word{
white-space:pre-wrap;
word-break:break-all;
font-size:50px;
font-weight:bold;
}
.text-appear .text-appear-word{
display:inline-block;
transform:translateY(var(--size-move-distance));
opacity:0;
}
.text-appear[data-anim="1"]{
border:1px solid red;
}
.text-appear[data-anim="1"] .text-appear-word{
animation-name : anim-text-appear;
animation-duration : var(--anim-duration);
animation-timing-function : ease;
animation-fill-mode:forwards;
}
@keyframes anim-text-appear{
0% {
opacity:0;
transform:translateY(var(--size-move-distance));
}
70%{
transform:translateY(-5px);
}
100% {
opacity:1;
transform:translateY(0);
}
}
<div class="sample text-appear">これがサンプルです。</div>
0 件のコメント:
コメントを投稿