LP(ランディングページ)でよく使われる要素のつくりかたまとめ
最近YouTubeチャンネルのLP(ランディングページ)を作りましたが、要所要所で備忘録的なメモがあったので共有します。パーツ単位のTipsはあると思いますが、LP作成全体を通してというまとめはあまりなかったので。
作成したもの
Nyamber | 猫YouTubeチャンネル
https:://www.nyamber.net
備忘録内容
- ローディング画面
- ローディング画面完了後にアニメーション
- 動画を流す
- 動画のレスポンシブ対応
- iPhoneの低電力モードでの動画再生されない対処
- パララックスとスクロールアニメ
- スクロールアニメのレスポンシブ対応
- YouTube Data API(おまけ)
- YouTubeブランドロゴについて(おまけ)
※環境
ビルドツールはNuxt3でVue3のComposition API記法、CSS記法はSCSS、ライブラリにtailwind.cssを使用しています。nuxt run generateで静的ページ書き出し。サーバーはNext.jsでおなじみのVercelで運用。(React派の人ごめんなさい。Nuxt3試したかった)
ローディング画面
プログレスバー付きのローディング画面を作りたいときはpace.jsを使います。
pace.js
ローディング中のプログレスバーを出すライブラリ
https://codebyzach.github.io/pace/
サンプル
ローディング完了後にアニメーション
引き続きpace.js
pace.jsの仕様でbodyにクラスが付与されるので、これとtransformを利用してアニメーションさせる
body.pace-running {
// ローディング中のプロパティを書く
}
body.pace-done {
// ローディング完了のプロパティを書く
}
アニメーションの例
.overlayがロード後右にスライドする
<template>
<div class="overlay"><img src="neko.jpg"></div>
</temaplate>
<style lang="scss">
.overlay {
height: 100vh;
width: 100vw;
transition: all 0.3s 2s ease; // 2sはロゴとローディングバーが消える時間を考慮してdelay(遅延させる)
}
body.pace-done { // ローディング完了
.overlay {
transform: translateX(100vw);
}
}
</style>
※JSでローディング状況を取得する場合
ローディングが完了したらJSプログラムを発動させたり、classをhtmlに追加してアニメーションを開始させたりできます。今回も、ローディング完了から2秒間は背景画像の下に動画が再生されているため、2秒経ったら再再生するようにします。
<template>
<video
class="w-full h-full object-contain absolute top-0 left-0"
ref="video"
muted
playsinline
loop
>
</template>
<script setup>
// -- ref -------------- //
const video = ref(null);
// -- methods -------------- //
const startMovie = () => {
// console.log('ビデオ再生');
video.value.play();
};
// -- mount -------------- //
onMounted(() => {
Pace.on('start', function () {
console.log('ローディング中');
});
Pace.on('done', function () {
console.log('ローディング完了');
setTimeout(startMovie, 2000); // 2秒後に動画再生
});
});
</script>
動画を流す
mp4形式の動画ファイルを用意してvideoタグで流します。
<template>
<video
class="w-full h-full object-contain absolute top-0 left-0"
muted
playsinline
loop
>
<source src="/movies/movie.mp4" type="video/mp4" />
お使いのブラウザはサポートされていません
</video>
</template>
属性にあるmutedは音声をカット、playsinlineは全画面ではなく埋め込みモード、loopは動画をループさせる設定です。詳しくはこちらを参考にして下さい
videoタグ
動画のレスポンシブ対応
PCで閲覧、スマホで閲覧で別々の動画ファイルを読み込む
動画をPC用とスマホ用に作り、PCはpc.mp4、スマホはsp.mp4を読み込むようにします。
動画のレスポンシブ対応は、調べてもなぜか1つの動画ファイルをPCでもスマホでも画面調整して見られる「サイズ調整」をする方法しか載ってないんですよね。
動画ファイルは重いので、PC用の重い動画をスマホで読み込むのはきついのでなるべくなら分けます。むしろこちらの方がレスポンシブ対応ではないでしょうか。
PC画面幅のブレイクポイント以上でアクセス→PC、それ以外→スマホ
PC画面幅ブレイクポイントでアクセス→PC、それ以外→スマホと判別してPC用かスマホ用のファイルを読み込むようにします。CSSでdisplayで制御とかは2つの動画を読み込んじゃうのでJSで画面幅を拾ってファイル名を条件分岐させます。例えば画面幅が1024px以上ならPC、1023px以下ならスマホ用を読み込むなどです。
画面幅判別のJavaScript関数 window.matchMedia
画面幅を条件に渡してtrue/falseを返します。
window.matchMedia
サンプル
※v-if="videoFile"を記述しないとDOMを読み込む前に処理が走りエラーになります。
<template>
<video
v-if="videoFile"
class="w-full h-full object-contain absolute top-0 left-0"
muted
playsinline
loop
>
<source :src="`/movies/${videoFile}`" type="video/mp4" />
お使いのブラウザはサポートされていません
</video>
</template>
<script setup>
const videoFile = ref('');
const setWindowWidth = (bool) => {
// console.log(bool);
if (bool) {
videoFile.value = 'pc.mp4';
} else {
videoFile.value = 'sp.mp4';
}
};
// window.matchMediaはdomがマウントされてから使用できるのでonMounted内で行う
onMounted(() => {
setWindowWidth(window.matchMedia('(min-device-width: 1024px)').matches);
}
</script>
iPhoneの低電力モードでの動画再生されない対処
動画をautoplayで読みこんだあとに再生する場合、iPhoneの低電力モードだと、動画再生は電力を多く使うと判定されて読み込むけど再生されません。
これに関してですが、一応回避策はあって、
短いmp4ファイルを使ってautoplayさせて、play()されてるかPromise errorを得て判別するものです。
以下を参考にして下さい。
なお、今回のLPではPace.jsでローディングを実装し、その間は動画を停止してるのでこの方法は使えません。他にも色々問題があり、検証中です。対処できたら書きます。
パララックスとスクロールアニメ
パララックスというのはページをスクロールした場合、背景模様を少しスクロールの速度と変化させることによって視差効果のことです。まあ演出の一種です。結構前にアップルとかがやり始めて流行り始めました。
スクロールアニメはその名の通りスクロールしてアニメーションを要所要所に入れるものです。
今回のものを作るに当たり2種類のやり方を記述します。
GSAP
色々ライブラリはあるんですが、老舗ということでGreenSockのライブラリ(通称GSAP)を使います。とにかく種類が豊富で、老舗なので資料もたくさんあります。
GreenSock
今回のLPでは標準のスクロールアニメ機能と、ある要素が画面内に現れたら発動させるスクロールトリガー(scrollTrigger)という機能を使います。おそらくこれがGSAPの二台巨塔です。一応CodePenでサンプル作ったのでご参考下さい。
サンプル
wow.jsとAnimate.css
今回は使用していませんが、他にはwow.jsとAnimate.cssを組み合わせも紹介しておきます。
wow.js
Animate.css
こちらも詳細解説は公式ドキュメントを見ながら、下のサンプルを参考にしていただければ。
サンプル
スクロールアニメのレスポンシブ対応
これは普通のwebサイトコーディングと同じようにおかしな所があったら調整します。
GSAPのレスポンシブ対応
matchMedia()判別が事前に用意されています。
ScrollTrigger.matchMedia()
<script setup>
onMounted(() => {
ScrollTrigger.matchMedia({
"(min-width: 1024px)": function() {
// desktopの設定
},
"(max-width: 1023px)": function() {
// mobileの設定
},
})
});
</script>
YouTube Data API(おまけ)
ここからは、今回はYouTube関連のLPということでどんなことに使えるのがさらっとおまけ的に書きます。赤枠で囲った、自分のYouTubeチャンネルの最新の〜件を出したり、再生リストを出したりします。
まず、概要については公式を御覧ください
YouTube Data API の概要
vueファイルで記述しますとこのような感じです。
<template>
<ul class="el_lists flex justify-between">
<li v-for="n in preData" :key="n.id">
<a
class="block"
:href="`https://www.youtube.com/watch?v=${n.snippet.resourceId.videoId}`"
target="_blank"
>
<img :src="n.snippet.thumbnails.medium.url" alt="" />
<p>{{ n.snippet.title }}</p>
</a>
<time>{{ dateChanger(n.snippet.publishedAt) }}</time>
</li>
</ul>
</template>
<script setup>
import axios from 'axios';
const preData = ref([]);
const getData = async () => {
const url =
'https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=PLI03iRUlUNvUp-nVW1d-7V57ZcUsmCuq-&key=(API_KEY)';
const tmpData = await axios
.get(url)
.then((response) => (preData.value = response.data.items));
console.log(preData);
return tmpData;
};
const dateChanger = (time) => {
return new Date(time).toLocaleDateString();
};
onMounted(() => {
getData();
})
</script>
const urlのところでAPI_KEY付きのパラメーターを指定して取得します。
const url =
'https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=PLI03iRUlUNvUp-nVW1d-7V57ZcUsmCuq-&key=(API_KEY)';
- playlistItems?...再生リストのアイテム
- part=snippet・・・レスポンスに含める必要がある形式を指定。ここではsnippet
- playlistId=PLI…・・・自分の再生リストのID
- key=(APIkey)・・・自分のAPI_KEY
YouTubeブランドロゴについて(おまけ)
Youtubeのロゴを使うときは、申請が必要です。なお、申請フォームは英語です
流れ的には
申請→返信(ここで何度か)→OK
のような単純流れで、私の場合は1回目の返信が2週間、2回目のデザイン修正後の返信が1週間後、その後OKメールが来ました。
申請時に貼り付けるデザインカンプの例
ここにロゴを使ったよ、修正依頼が来たときはここのは削除したよ、みたいな枠を付けたりすると相手が日本人じゃなくてもスムーズです。
Discussion