- 本文链接:使用 Lottie 动画装饰一下你的 404 页面
- 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议,转载请注明出处!
使用 Lottie 动画装饰一下你的 404 页面
使用 Lottie 动画装饰一下你的 404 页面
自己博客的 404 页面太单调无趣了,由于之前项目使用过Lottie-Web做过动画,想着给 404 页面加上一个有趣的动画。然后就去 LottieFiles动画库搜索了下404
,发现一个和谷歌浏览器断网小恐龙游戏类似的的 404 动画效果,感觉很有趣,那就用它了,最终的效果大家可以通过访问 404 页面查看。
下载动画 JSON
LottieFiles上面能找到很多 404 页面的动画,可以挑一个你喜欢了。
这里就选择小恐龙的动画,点击右上角的Download
按钮,选择Lottie JSON
进行下载。
下载完成后会得到一个 json 文件。
提示
目前提供dotLottie文件下载了,体积更迷你,上面下载的100多kb的JSON文件,下载后的dotLottie
文件只有7kb左右。集成文档参考@lottiefiles/dotlottie-web
修改默认颜色
由于动画内容的黑色和博客默认的黑色不太一样,所以还需要借助 LottieFiles 提供的编辑器修改下颜色。
上传刚刚下载的 json 文件,将Unique colors
里面的黑色修改成想要的颜色。
点击Save
按钮保存后就能在自己的项目中找到修改后的动画了。
同样是下载 Lottie JSON 文件。
动画组件
Lottie Web 的动画使用很简单,只需要传入一个容器container
和动画 json 所在路径path
,下面是文档中的一个初始化示例。
var animation = bodymovin.loadAnimation({
container: document.getElementById('lottie'), // Required
path: 'data.json', // Required
renderer: 'svg/canvas/html', // Required
loop: true, // Optional
autoplay: true, // Optional
name: 'Hello World' // Name for future reference. Optional.
})
所以可以写一个简单的组件,传入相关参数即可,当然你也可以使用别人封装好的lottie-web-vue,这里由于使用场景比较简单,就自己撸一个了,先将 lottie-web 安装一下。
npm install lottie-web
yarn add lottie-web
由于自己的博客使用的 vuepress2,可以在src/.vuepress/components
目录中新建一个LottieWeb
的自定义组件。
由于使用场景比较简单,将相关配置直接通过options
传入,派发一个DOMLoaded
事件。
<template>
<div class="lottie-web" ref="animContainer"></div>
</template>
<script lang="ts" setup>
import { onBeforeUnmount, onMounted, ref } from 'vue'
import type { AnimationItem } from 'lottie-web'
import lottie from 'lottie-web'
const props = defineProps({
options: {
type: Object,
required: true
}
})
const emit = defineEmits(['DOMLoaded'])
const animContainer = ref<Element | null>(null)
const anim = ref<AnimationItem | null>(null)
onMounted(() => {
anim.value = lottie.loadAnimation({
container: animContainer.value as Element,
renderer: 'svg',
loop: props.options.loop !== false,
autoplay: props.options.autoplay !== false,
animationData: props.options.animationData,
path: props.options.path,
rendererSettings: props.options.rendererSettings
})
anim.value.addEventListener('DOMLoaded', () => {
emit('DOMLoaded', anim)
})
})
onBeforeUnmount(() => {
if (anim.value && anim.value) {
anim.value.destroy()
}
})
</script>
集成到 404
可以参照 Vuepress 的继承文档说明替换默认的 404 页面。博客主题使用的是Mr.Hope大佬写的VuePress Theme Hope主题,好在大佬贴心的给NotFound布局提供了一个默认的内容插槽,所以我们只需要引用内置的NotFound
,将动画内容放到里面即可。
在src/.vuepress/layouts
下面新建一个新的 NotFound 布局,将上面下载的 json 数据放到同级目录下并通过new URL('./data.json', import.meta.url).href
形式传入 path。
新的 NotFound 布局写好后在src/.vuepress/client.ts
中的layouts
中引入即可。
<template>
<NotFound>
<div class="not-found-hint">
<p class="error-code">404</p>
<h1 class="error-title">页面不存在</h1>
</div>
<LottieWeb
:options="options"
:style="{
height: '50vh',
opacity: showLottieWeb ? 1 : 0,
'margin-top': '-60px'
}"
@DOMLoaded="DOMLoaded"
/>
</NotFound>
</template>
<script lang="ts" setup>
import NotFound from 'vuepress-theme-hope/layouts/NotFound'
import LottieWeb from '../../components/LottieWeb/index.vue'
import { ref } from 'vue'
const showLottieWeb = ref(false)
const options = ref({
path: new URL('./data.json', import.meta.url).href
})
function DOMLoaded() {
const $rectList = document.querySelectorAll(
'.lottie-web rect[fill="#ffffff"]'
)
$rectList.forEach((element) => {
element.setAttribute('fill', 'transparent')
})
showLottieWeb.value = true
}
</script>
<style scoped lang="scss">
.not-found-hint {
padding-bottom: 0;
}
</style>
import NotFound from './layouts/NotFound/index.vue'
import { defineClientConfig } from '@vuepress/client'
export default defineClientConfig({
layouts: {
NotFound
}
})
适配暗黑模式
由于动画背景是白色的,在暗黑模式下还是白色的会很刺眼,所以在上述代码在DOMLoaded
的时候做了特殊处理。
我们可以在生成的动画 SVG 中找到背景的元素rect
元素,
通过document.querySelectorAll('.lottie-web rect[fill="#ffffff"]')
定位到该元素,
使用setAttribute
修改该背景的fill
为transparent
透明色。
此时在暗黑模式下刷新页面的时候会存在白色背景一闪的情况,如下图所示:
为了解决这个可以在动画组件上加个style
样式opacity
默认为 0,这样初始的时候不可见,通过showLottieWeb
变量控制最终的显示,在样式替换完成后将动画组件显示可见,这样有一个缓冲就不会出现上述的现象了。