点击查看更新记录
更新记录
2021-12-21:插件版1.0.5
- 将cdn配置项外露,支持自定义CDN链接
- 将CDN改为npm.elemecdn.com
2021-06-19:新增提示
- 插件化完成。从此告别繁琐的配置。
- 只需两步,安装插件,添加配置项。
2021-01-31:新增提示
- 更新butterfly_v3.6.0适配方案
2020-12-26:内测版v0.04
- 新增外挂标签写法
2020-12-26:内测版v0.03
- 在基础方案基础上实现插件化配置。
- 新增四个配置项
- 优化配置逻辑,弃用
_data/wowjs.yml
- 支持直接在主题配置文件内配置动画类和动画效果
- 优化了各静态资源的引入逻辑
2020-12-24:内测版v0.02
- 优化基础引入方案的异步加载和pjax适配
2020-12-23:内测版v0.01
- 编写参考文档
- 编写TODO
- 编写基础引入方案
点击查看参考教程
参考方向 | 教程原贴 |
---|---|
动画样式依赖 | animate.css |
wowjs文档 |
插件化版本(推荐)
安装插件即可使用,已包含外挂标签内容
安装插件,在博客根目录
[Blogroot]
下打开终端,运行以下指令:1
npm install hexo-butterfly-wowjs --save
添加配置信息,以下为写法示例
在站点配置文件_config.yml
或者主题配置文件_config.butterfly.yml
中添加1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16wowjs:
enable: true #控制动画开关。true是打开,false是关闭
priority: 10 #过滤器优先级
mobile: false #移动端是否启用,默认移动端禁用
animateitem:
- class: recent-post-item #必填项,需要添加动画的元素的class
style: animate__zoomIn #必填项,需要添加的动画
duration: 2s #选填项,动画持续时间,单位可以是ms也可以是s。例如3s,700ms。
delay: 1s #选填项,动画开始的延迟时间,单位可以是ms也可以是s。例如3s,700ms。
offset: 100 #选填项,开始动画的距离(相对浏览器底部)
iteration: 2 #选填项,动画重复的次数
- class: card-widget
style: animate__zoomIn
animate_css: https://npm.elemecdn.com/hexo-butterfly-wowjs/lib/animate.min.css
wow_js: https://npm.elemecdn.com/hexo-butterfly-wowjs/lib/wow.min.js
wow_init_js: https://npm.elemecdn.com/hexo-butterfly-wowjs/lib/wow_init.js- 参数释义
参数 | 备选值/类型 | 释义 |
---|---|---|
enable | true/false | 【必选】控制开关 |
priority | number | 【可选】过滤器优先级,数值越小,执行越早,默认为10,选填 |
mobile | true/false | 控制移动端是否启用,默认移动端禁用 |
animateitem.class | class | 【可选】添加动画类名,只支持给class添加 |
animateitem.style | text | 【可选】动画样式,具体类型参考animate.css |
animateitem.duration | time,单位为s或ms | 【可选】动画持续时间,单位可以是ms也可以是s。例如3s,700ms。 |
animateitem.delay | time,单位为s或ms | 【可选】动画开始的延迟时间,单位可以是ms也可以是s。例如3s,700ms。 |
animateitem.offset | number,单位为px | 【可选】开始动画的距离(相对浏览器底部)。 |
animateitem.iteration | number,单位为s或ms | 【可选】动画重复的次数 |
animate_css | URL | 【可选】animate.css的CDN链接,默认为https://npm.elemecdn.com/hexo-butterfly-wowjs/lib/animate.min.css |
wow_js | URL | 【可选】wow.min.js的CDN链接,默认为https://npm.elemecdn.com/hexo-butterfly-wowjs/lib/wow.min.js |
wow_init_js | URL | 【可选】wow_init.js的CDN链接,默认为https://npm.elemecdn.com/hexo-butterfly-wowjs/lib/wow_init.js |
外挂标签用法
1 | {% wow [animete],[duration],[delay],[offset],[iteration] %} |
animate
: 动画样式,效果详见animate.css参考文档duration
: 选填项,动画持续时间,单位可以是ms
也可以是s
。例如3s
,700ms
。delay
: 选填项,动画开始的延迟时间,单位可以是ms
也可以是s
。例如3s
,700ms
。offset
: 选填项,开始动画的距离(相对浏览器底部)iteration
: 选填项,动画重复的次数
注意,后面四个虽然是选填项,但是当有跨位选填时,次序不能乱。详见示例。
支持嵌套其他外挂标签。
flip
动画效果。flip
动画效果。zoomIn
动画效果,持续5s
,延时5s
,离底部100
距离时启动,重复10
次。zoomIn
动画效果,持续5s
,延时5s
,离底部100
距离时启动,重复10
次slideInRight
动画效果,持续5s
,延时5s
。heartBeat
动画效果,延时5s
,重复10
次。heartBeat
动画效果,延时5s
,重复10
次。
flip
动画效果。1
2
3
4
5{% wow animate__flip %}
{% note green 'fas fa-fan' modern%}
`flip`动画效果。
{% endnote %}
{% endwow %}zoomIn
动画效果,持续5s
,延时5s
,离底部100
距离时启动,重复10
次。1
2
3
4
5{% wow animate__zoomIn,5s,5s,100,10 %}
{% note blue 'fas fa-bullhorn' modern%}
`zoomIn`动画效果,持续`5s`,延时`5s`,离底部`100`距离时启动,重复`10`次
{% endnote %}
{% endwow %}slideInRight
动画效果,持续5s
,延时5s
。1
2
3
4
5{% wow animate__slideInRight,5s,5s %}
{% note orange 'fas fa-car' modern%}
`slideInRight`动画效果,持续`5s`,延时`5s`。
{% endnote %}
{% endwow %}heartBeat
动画效果,延时5s
,重复10
次。此处注意不用的参数位置要留空,用逗号间隔。1
2
3
4
5{% wow animate__heartBeat,,5s,,10 %}
{% note red 'fas fa-battery-half' modern%}
`heartBeat`动画效果,延时`5s`,重复`10`次。
{% endnote %}
{% endwow %}
基础引用
若您不想修改源码,只需使用基础引用方案即可
新建
[Blogroot]\themes\butterfly\source\js\wow_init.js
,配置特性动画的默认项。1
2
3
4
5
6
7
8
9
10
11
12
13
14wow = new WOW({
boxClass: 'wow',
// 当用户滚动时显示隐藏框的类名称
animateClass: 'animate__animated',
// 触发 CSS 动画的类名称(动画库默认为"animate.css"库)
offset: 0,
// 定义浏览器视口底部与隐藏框顶部之间的距离。
// 当用户滚动并到达此距离时,将显示隐藏的框。
mobile: false,
// 在移动设备上打开/关闭wow.js。
live: true
// 在页面上检查新的 wow.js元素。
})
wow.init();引入js和css样式,修改
[Blogroot]\_config.butterfly.yml
的inject
配置项,添加样式资源。1
2
3
4
5
6inject:
head:
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css" media="defer" onload="this.media='all'">
bottom:
- <script defer src="https://cdn.jsdelivr.net/gh/graingert/wow@1.3.0/dist/wow.min.js"></script>
- <script defer data-pjax src="/js/wow_init.js"></script>选择需要添加动画的dom元素,添加动画class类。此处提供三种写法。
- 页面内写法,拟给
<div class='example'><div>
套上动画。一般在page页面或post页面中使用(也就是写博客的.md文件)。1
2
3
4
5
6<!-- raw的外挂标签是告诉渲染引擎这段代码不用渲染。 -->
{% raw %}
<div class="example wow animate__bounceInUp">
Content to Reveal Here
</div>
{% endraw %} - pug写法,拟给首页文章卡片套上动画,直接源码修改:
修改[Blogroot]\themes\butterfly\layout\includes\mixins\post-ui.pug
1
2
3
4
5
6mixin postUI(posts)
each article , index in page.posts.data
- .recent-post-item
+ .recent-post-item.wow.animate__zoomIn
- let link = article.link || article.path
- let title = article.title || _p('no_title') - js批量添加写法(引入顺序需要在wow_init.js之前,而且需要pjax重载,每页重新添加一遍class)。通过在页面按F12,使用控制台右上角的元素选择器找到对应元素并获取class类名。
修改[Blogroot]\themes\butterfly\source\js\wow_init.js
,在原有内容之前添加内容:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27// 给首页文章卡片套上动画
var arr = document.getElementsByClassName("recent-post-item");
for(var i = 0;i<arr.length;i++){
arr[i].classList.add("wow"); //必要项,添加wow.js标记
arr[i].classList.add("animate__zoomIn"); //必要项,添加样式动画
}
// 给侧栏卡片套上动画
var arr = document.getElementsByClassName("card-widget");
for(var i = 0;i<arr.length;i++){
arr[i].classList.add("wow");
arr[i].classList.add("animate__slideInRight");
}
//初始化函数
wow = new WOW({
boxClass: 'wow',
// 当用户滚动时显示隐藏框的类名称
animateClass: 'animate__animated',
// 触发 CSS 动画的类名称(动画库默认为"animate.css"库)
offset: 0,
// 定义浏览器视口底部与隐藏框顶部之间的距离。
// 当用户滚动并到达此距离时,将显示隐藏的框。
mobile: true,
// 在移动设备上打开/关闭wow.js。
live: true
// 在页面上检查新的 wow.js元素。
})
wow.init();
- 页面内写法,拟给
- 运行
hexo cl && hexo g
之后即可看到效果。更多动画样式可以查看animate.css参考文档。
魔改源码方案
点击查看魔改源码方案
魔改源码方案是基于Butterfly_v3.4.1
编写的,低版本可能有些许不适用,可以考虑使用基础引入方案或者升级主题。或者自己理解后重构配置。
- 新建
[Blogroot]\themes\butterfly\source\js\wow_init.js
,配置默认值。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15wow = new WOW({
boxClass: 'wow',
// 当用户滚动时显示隐藏框的类名称
animateClass: 'animate__animated',
// 触发 CSS 动画的类名称(动画库默认为"animate.css"库)
offset: 0,
// 定义浏览器视口底部与隐藏框顶部之间的距离。
// 当用户滚动并到达此距离时,将显示隐藏的框。
mobile: false,
// 在移动设备上打开/关闭wow.js。
// 经测试此项配置无效。
live: true
// 在页面上检查新的 wow.js元素。
})
wow.init(); - 新建
[Blogroot]\themes\butterfly\layout\includes\third-party\wowjs.pug
,1
2
3
4
5
6
7
8
9
10
11
12
13
14
15.pjax-reload
if theme.wowjs.animateitem
each item in theme.wowjs.animateitem
script(async).
var arr = document.getElementsByClassName('!{item.class}');
for(var i = 0;i<arr.length;i++){
arr[i].classList.add('wow');
arr[i].classList.add('!{item.style}');
arr[i].setAttribute('data-wow-duration', '!{item.duration}');
arr[i].setAttribute('data-wow-delay', '!{item.delay}');
arr[i].setAttribute('data-wow-offset', '!{item.offset}');
arr[i].setAttribute('data-wow-iteration', '!{item.iteration}');
}
script(defer src=url_for(theme.CDN.wowjs))
script(defer src=url_for(theme.CDN.wowjs_init)) - 修改
[Blogroot]\themes\butterfly\layout\includes\head.pug
的内容,注意butterfly_v3.6.0
取消了缓存配置,转为完全默认,需要将{cache:theme.fragment_cache}
改为{cache: true}
。1
2
3
4
5
6
7
8//- font
if theme.blog_title_font && theme.blog_title_font.font_link
link(rel='stylesheet' href=url_for(theme.blog_title_font.font_link) media="print" onload="this.media='all'")
+ //- animate_css
+ if theme.wowjs.enable
+ link(rel='stylesheet' href=url_for(theme.CDN.animate_css) media="print" onload="this.media='all'")
//- global config
!=partial('includes/head/config', {}, {cache:theme.fragment_cache}) - 修改
[Blogroot]\themes\butterfly\layout\includes\additional-js.pug
的内容,注意butterfly_v3.6.0
取消了缓存配置,转为完全默认,需要将{cache:theme.fragment_cache}
改为{cache: true}
。1
2
3
4
5
6
7if theme.pjax.enable
!=partial('includes/third-party/pjax', {}, {cache:theme.fragment_cache})
!=partial('includes/third-party/baidu_push', {}, {cache:theme.fragment_cache})
+ if theme.wowjs.enable
+ !=partial('includes/third-party/wowjs', {}, {cache:theme.fragment_cache}) - 修改
[Blogroot]\themes\butterfly\layout\includes\third-party\pjax.pug
的内容。原则上不推荐再用低于v3.4.0的版本,新版方案已经实现去jquery化,而此处的pjax适配仍然是需要jquery的。
1
2
3
4- $('script[data-pjax]').each(function () {
+ $('script[data-pjax], .pjax-reload script').each(function () {
$(this).parent().append($(this).remove())
})1
2
3
4
5
6
7
8- document.querySelectorAll('script[data-pjax]').forEach(item => {
+ document.querySelectorAll('script[data-pjax], .pjax-reload script').forEach(item => {
const newScript = document.createElement('script')
const content = item.text || item.textContent || item.innerHTML || ""
Array.from(item.attributes).forEach(attr => newScript.setAttribute(attr.name, attr.value))
newScript.appendChild(document.createTextNode(content))
item.parentNode.replaceChild(newScript, item)
}) - 修改
[Blogroot]\_config.butterfly.yml
,添加CDN配置项1
2
3
4
5
6
7
8
9CDN:
# main
main_css: /css/index.css
jquery: https://npm.elemecdn.com/jquery@latest/dist/jquery.min.js
main: /js/main.js
utils: /js/utils.js
+ wowjs: https://cdn.jsdelivr.net/gh/graingert/wow@1.3.0/dist/wow.min.js
+ wowjs_init: /js/wow_init.js # 之后可以自己换成CDN链接
+ animate_css: https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css - 修改
[Blogroot]\_config.butterfly.yml
,添加wowjs开关配置项,其中class和style是必填项,其余四个是选填项。此处提供首页文章卡片和侧栏卡片添加动画的示例。1
2
3
4
5
6
7
8
9
10
11wowjs:
enable: true #控制动画开关。true是打开,false是关闭
animateitem:
- class: recent-post-item #必填项,需要添加动画的元素的class
style: animate__zoomIn #必填项,需要添加的动画
duration: 2s #选填项,动画持续时间,单位可以是ms也可以是s。例如3s,700ms。
delay: 1s #选填项,动画开始的延迟时间,单位可以是ms也可以是s。例如3s,700ms。
offset: 100 #选填项,开始动画的距离(相对浏览器底部)
iteration: 2 #选填项,动画重复的次数
- class: card-widget
style: animate__zoomIn - 运行
hexo cl && hexo g
之后即可看到效果。更多动画样式可以查看animate.css参考文档。
外挂标签写法配置方案
点击查看外挂标签写法配置教程
- 外挂标签写法生效的前提是完成了上面的基础引入方案或者插件引入方案(二选一即可)。
- 新建
[Blogroot]\themes\butterfly\scripts\tag\wowanimate.js
:1
2
3
4
5
6
7
8
9
10
11
12
13
function wow (args, content) {
args = args.join(' ').split(',')
let p0 = args[0]?args[0].trim():''
let p1 = args[1]?args[1].trim():''
let p2 = args[2]?args[2].trim():''
let p3 = args[3]?args[3].trim():''
let p4 = args[4]?args[4].trim():''
return `<div class='wow ${p0}' data-wow-duration='${p1}' data-wow-delay='${p2}' data-wow-offset='${p3}' data-wow-iteration='${p4}' >${hexo.render.renderSync({ text: content, engine: 'markdown' })}</div>`
}
hexo.extend.tag.register('wow',wow,{ ends: true }); - 使用方式
1
2
3{% wow [animete],[duration],[delay],[offset],[iteration] %}
内容
{% endwow %}animate
: 动画样式,效果详见animate.css参考文档duration
: 选填项,动画持续时间,单位可以是ms
也可以是s
。例如3s
,700ms
。delay
: 选填项,动画开始的延迟时间,单位可以是ms
也可以是s
。例如3s
,700ms
。offset
: 选填项,开始动画的距离(相对浏览器底部)iteration
: 选填项,动画重复的次数
注意,后面四个虽然是选填项,但是当有跨位选填时,次序不能乱。详见示例。
支持嵌套其他外挂标签。flip
动画效果。flip
动画效果。zoomIn
动画效果,持续5s
,延时5s
,离底部100
距离时启动,重复10
次。zoomIn
动画效果,持续5s
,延时5s
,离底部100
距离时启动,重复10
次slideInRight
动画效果,持续5s
,延时5s
。heartBeat
动画效果,延时5s
,重复10
次。heartBeat
动画效果,延时5s
,重复10
次。
flip
动画效果。1
2
3
4
5{% wow animate__flip %}
{% note green 'fas fa-fan' modern%}
`flip`动画效果。
{% endnote %}
{% endwow %}zoomIn
动画效果,持续5s
,延时5s
,离底部100
距离时启动,重复10
次。1
2
3
4
5{% wow animate__zoomIn,5s,5s,100,10 %}
{% note blue 'fas fa-bullhorn' modern%}
`zoomIn`动画效果,持续`5s`,延时`5s`,离底部`100`距离时启动,重复`10`次
{% endnote %}
{% endwow %}slideInRight
动画效果,持续5s
,延时5s
。1
2
3
4
5{% wow animate__slideInRight,5s,5s %}
{% note orange 'fas fa-car' modern%}
`slideInRight`动画效果,持续`5s`,延时`5s`。
{% endnote %}
{% endwow %}heartBeat
动画效果,延时5s
,重复10
次。此处注意不用的参数位置要留空,用逗号间隔。1
2
3
4
5{% wow animate__heartBeat,,5s,,10 %}
{% note red 'fas fa-battery-half' modern%}
`heartBeat`动画效果,延时`5s`,重复`10`次。
{% endnote %}
{% endwow %}
TO DO
提供wowjs引入基本方案
将配置内容整合进配置文件
添加异步加载和pjax适配
编写外挂标签
将wowjs开关整合进front-matter的控制项(废弃,与pjax冲突过大)
BUG反馈归纳
如果使用了gulp-babel,在压缩js时可能报错:
1
wow_init.js:1 Uncaught ReferenceError: wow is not defined
修改
[Blogroot]\gulpfile.js
,添加一行屏蔽项,不要压缩wow_init.js
1
2
3
4
5
6//minify js babel
gulp.task('compress', () =>
- gulp.src(['./public/**/*.js', '!./public/**/*.min.js'])
+ gulp.src(['./public/**/*.js', '!./public/**/*.min.js','!./public/js/wow_init.js'])
.pipe(babel({
presets: ['@babel/preset-env']在wowjs初始化设置中设置了mobile为false,但是手机依然生效。
推测是因为wowjs原本是基于animate.css_v3.0编写的,但是本帖沿用的是4.0。好吧,经测试,3.0也不生效
解决方案是自主添加媒体选择。在css异步加载的适配中将onload="this.media='all'"
改为onload="this.media='screen'"
,这样,样式就只会对电脑设备(或等宽度的设备)生效了。
Use this card to join the candyhome and participate in a pleasant discussion together .
Welcome to 测试's candyhome,wish you a nice day .