このブログ記事のバナー部分がスクロールしながら切り替わっていますが、かなり効果的にホームページのバナー効果で使える上、かなり軽量に動作できるので、ソースコードを公開しておきたいと思います。
ソースコード
banner.html
<link rel="stylesheet" href="banner.css">
<script type="module" src="banner.js">
<div class="images">
<img width="800" height="400" alt="eyecatch" border="0" src="画像1"/>
<img width="800" height="400" alt="eyecatch" border="0" data-src="画像2"/>
<img width="800" height="400" alt="eyecatch" border="0" data-src="画像3"/>
<img width="800" height="400" alt="eyecatch" border="0" data-src="画像4"/>
</div>
【注意】
・画像は好きなものを登録してお使いください。
・画像の枚数は2枚以上であれば、いくつでも登録しても構いません。
・先頭の画像のみ、src属性をセットしてそれいがいは、data-srcでセットしてください。
banner.css
.images{
width:800px;
max-width:100%;
height:400px;
overflow:hidden;
position:relative;
}
.images img{
display:block;
width:100%;
height:100%;
object-fit:cover;
transform:scale(1.1);
margin-left:10%;
margin-left:10%;
position:absolute;
top:0;
left:0;
z-index:1;
}
/* Slide */
.images{
--slice-time : 30.0s;
}
.images img{
opacity:0.0;
}
.images img.active{
opacity:1.0;
animation : anim-banner var(--slice-time) linear 0.0s forwards;
}
@keyframes anim-banner{
0%{
margin-left:5%;
opacity:1.0;
}
90%{
opacity:1.0;
}
99%{
opacity:0.0;
}
100%{
margin-left:-5%;
opacity:0.0;
}
}
banner.js
class Banner{
constructor(){
this.init()
this.load_images()
}
time = 5 * 1000
get root(){
return document.querySelector(`.images`)
}
init(){
this.root.style.setProperty("--slice-time" , `${this.time}ms`)
window.addEventListener("animationend" , this.anim_end.bind(this))
}
load_images(){
const images = this.root.querySelectorAll(`img[data-src]`)
if(images && images.length){
this.load_image(images[0])
}
this.anim_start(this.root.querySelector(`img[src]`))
}
load_image(img){
img.onload = this.load_images.bind(this)
img.setAttribute("src", img.getAttribute("data-src"))
img.removeAttribute("data-src")
}
anim_start(img){
// ブラウザがアクティブじゃなくなった場合に、アニメーションがすでに終了している場合の処理
img = img || this.root.querySelector(`img`)
img.classList.add("active")
this.set_sorts(img)
setTimeout(this.anim_start.bind(this, img.nextElementSibling) , this.time * 0.8)
}
anim_end(e){
const img = e.target
if(this.root.querySelector(".active") !== img){return}
img.classList.remove("active")
img.style.setProperty("z-index","","")
this.root.appendChild(img)
}
set_sorts(active_img){
const active_imgs = this.root.querySelectorAll("img.active")
if(!active_imgs || !active_imgs.length){return}
for(const img of active_imgs){
if(img === active_img){
img.style.setProperty("z-index","0","")
}
else{
img.style.setProperty("z-index","2","")
}
}
}
}
new Banner()
導入方法
上記ソースコードと、画像を同じフォルダに入れてhtmlファイルをインターネットブラウザで起動すれば表示できます。
※httpプロトコルで表示してください。
技術ポイント
トップバナーを見て、cssで簡単にできると思った人は、是非自分で構築してみるといいでしょう。
きっと、質の悪いバナー表示になって、どうしてもjavascriptを使わないと実現できないという現実に打ちのめされるでしょう。
ただ、画像の枚数が固定であれば、keyframeを固定で掛けばある程度はできるかもしれませんが、2周目の切り替わりの際に画像の前後判定がうまくできなくて気持ち悪くなるでしょう。
このバナーアニメのポイントは、切り替わりのタイミングで半透明のクロスフェードを行っているんですが、
背景側の画像も同時にスクロールアニメが実行されていないと違和感が生じてしまうという事です。
そしてそのタイミングを図ってイベント制御するには、Javascriptを使わざるを得ないんですね。
個人的にCSSだけでこの仕組みを実現したかったんですが、どうしてもJSに頼らざるを得なかったというのが残念ですが、結果的に、画像の遅延ロードなどの処理も入れて、ページの読み込みを早くすることができたり、
CSSの@keyframeとの連動で安定した動きができるようになったので、いい感じの着地に落ち着きました。
あとがき
とある会社さんのWebページで作った今回のトップページバナーアニメ機能でしたが、ブログに残しておくことで今後別のページで再利用することが可能になりました。
ちなみに、その会社さん、画像が乏しいんですよね。
この機能を使うには、質の良い画像をたくさんなければいけないのに・・・
0 件のコメント:
コメントを投稿