开发记录

开发记录

2020-11-4:内测版v0.01

  1. 使用ejs模板
  2. 直接替换源码。
  3. 使用inject配置项来外挂css。

2020-11-5:内测版v0.02

  1. 修改为pug模板。
  2. 优化了css代码结构。

2020-11-5:正式版v1.0

  1. 成功实现多主题配置
  2. css转为stylus,支持根据指定选项加载对应样式,节省资源。
  3. 保留原版spinner-box加载动画,与自定义wizard动画并存。
  4. 优化代码结构,可以根据教程示例和魔改思路,自行尝试添加自定义样式。

2020-11-8:正式版v1.1

  1. 新增直接使用gif图作为加载动画配置。
  2. 支持自定义配置加载动画背景颜色。

2020-11-22:正式版v1.2

  1. 自选修改,删除夜间模式背景色覆盖以适配image主题加载动画。

旧版教程,只需要本站同款巫师主题的可以看这个

魔改示例

  1. 修改[Blogroot]\themes\butterfly\layout\includes\loading\loading.pug

    #loading-box
    .loading-left-bg
    .loading-right-bg
    .wizard-scene
    .wizard-objects
    .wizard-square
    .wizard-circle
    .wizard-triangle
    .wizard
    .wizard-body
    .wizard-right-arm
    .wizard-right-hand
    .wizard-left-arm
    .wizard-left-hand
    .wizard-head
    .wizard-beard
    .wizard-face
    .wizard-adds
    .wizard-hat
    .wizard-hat-of-the-hat
    .wizard-four-point-star.--first
    .wizard-four-point-star.--second
    .wizard-four-point-star.--third

    这里我保留了原代码的前三行内容,这三行配合loading-js.pug控制加载动画的显隐和背景色的帷幕动画效果。

  2. [Blogroot]\themes\butterfly\source\css\目录下新建loading_wizard.css文件

    @charset "UTF-8";
    #loading-box {
    position: fixed;
    z-index: 1000; /*初始调高loading-box层级在众网页元素之上*/
    display: -webkit-box;
    display: flex;
    -webkit-box-align: center;
    align-items: center;
    -webkit-box-pack: center;
    justify-content: center;
    -webkit-box-orient: vertical;
    -webkit-box-direction: normal;
    flex-direction: column;
    flex-wrap: wrap;
    width: 100vw;
    height: 100vh;
    overflow: hidden;
    }
    #loading-box.loaded{
    z-index: -1000; /*加载完成后把loading-box的三维层级调低,免得遮罩其他网页元素*/
    }
    .wizard-scene {
    position: fixed;
    z-index: 1001; /*巫师动画还要比loading-box层级高一点点*/
    display: -webkit-box;
    display: flex;
    }
    #loading-box.loaded .wizard-scene{
    display: none; /*加载完成后隐藏巫师动画*/
    }
    /** Wizard CSS & Animations */
    .wizard {
    position: relative;
    width: 190px;
    height: 240px;
    }

    .wizard-body {
    position: absolute;
    bottom: 0;
    left: 68px;
    height: 100px;
    width: 60px;
    background: #3f64ce;
    }
    .wizard-body::after {
    content: "";
    position: absolute;
    bottom: 0;
    left: 20px;
    height: 100px;
    width: 60px;
    background: #3f64ce;
    -webkit-transform: skewX(14deg);
    transform: skewX(14deg);
    }

    .wizard-right-arm {
    position: absolute;
    bottom: 74px;
    left: 110px;
    height: 44px;
    width: 90px;
    background: #3f64ce;
    border-radius: 22px;
    /** animation */
    -webkit-transform-origin: 16px 22px;
    transform-origin: 16px 22px;
    -webkit-transform: rotate(70deg);
    transform: rotate(70deg);
    -webkit-animation: right_arm 10s ease-in-out infinite;
    animation: right_arm 10s ease-in-out infinite;
    }
    .wizard-right-arm .right-hand {
    position: absolute;
    right: 8px;
    bottom: 8px;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: #f1c5b4;
    /** animation */
    -webkit-transform-origin: center center;
    transform-origin: center center;
    -webkit-transform: rotate(-40deg);
    transform: rotate(-40deg);
    -webkit-animation: right_hand 10s ease-in-out infinite;
    animation: right_hand 10s ease-in-out infinite;
    }
    .wizard-right-arm .wizard-right-hand::after {
    content: "";
    position: absolute;
    right: 0px;
    top: -8px;
    width: 15px;
    height: 30px;
    border-radius: 10px;
    background: #f1c5b4;
    /** Animation */
    -webkit-transform: translateY(16px);
    transform: translateY(16px);
    -webkit-animation: right_finger 10s ease-in-out infinite;
    animation: right_finger 10s ease-in-out infinite;
    }

    .wizard-left-arm {
    position: absolute;
    bottom: 74px;
    left: 26px;
    height: 44px;
    width: 70px;
    background: #3f64ce;
    border-bottom-left-radius: 8px;
    /** animation */
    -webkit-transform-origin: 60px 26px;
    transform-origin: 60px 26px;
    -webkit-transform: rotate(-70deg);
    transform: rotate(-70deg);
    -webkit-animation: left_arm 10s ease-in-out infinite;
    animation: left_arm 10s ease-in-out infinite;
    }
    .wizard-left-arm .wizard-left-hand {
    position: absolute;
    left: -18px;
    top: 0;
    width: 18px;
    height: 30px;
    border-top-left-radius: 35px;
    border-bottom-left-radius: 35px;
    background: #f1c5b4;
    }
    .wizard-left-arm .wizard-left-hand::after {
    content: "";
    position: absolute;
    right: 0;
    top: 0;
    width: 30px;
    height: 15px;
    border-radius: 20px;
    background: #f1c5b4;
    /** Animation */
    -webkit-transform-origin: right bottom;
    transform-origin: right bottom;
    -webkit-transform: scaleX(0);
    transform: scaleX(0);
    -webkit-animation: left_finger 10s ease-in-out infinite;
    animation: left_finger 10s ease-in-out infinite;
    }

    .wizard-head {
    position: absolute;
    top: 0;
    left: 14px;
    width: 160px;
    height: 210px;
    /** Animation */
    -webkit-transform-origin: center center;
    transform-origin: center center;
    -webkit-transform: rotate(-3deg);
    transform: rotate(-3deg);
    -webkit-animation: head 10s ease-in-out infinite;
    animation: head 10s ease-in-out infinite;
    }
    .wizard-head .wizard-beard {
    position: absolute;
    bottom: 0;
    left: 38px;
    height: 106px;
    width: 80px;
    border-bottom-right-radius: 55%;
    background: #ffffff;
    }
    .wizard-head .wizard-beard::after {
    content: "";
    position: absolute;
    top: 16px;
    left: -10px;
    width: 40px;
    height: 20px;
    border-radius: 20px;
    background: #ffffff;
    }
    .wizard-head .wizard-face {
    position: absolute;
    bottom: 76px;
    left: 38px;
    height: 30px;
    width: 60px;
    background: #f1c5b4;
    }
    .wizard-head .wizard-face::before {
    content: "";
    position: absolute;
    top: 0px;
    left: 40px;
    width: 20px;
    height: 40px;
    border-bottom-right-radius: 20px;
    border-bottom-left-radius: 20px;
    background: #f1c5b4;
    }
    .wizard-head .wizard-face::after {
    content: "";
    position: absolute;
    top: 16px;
    left: -10px;
    width: 50px;
    height: 20px;
    border-radius: 20px;
    border-bottom-right-radius: 0px;
    background: #ffffff;
    }
    .wizard-head .wizard-face .wizard-adds {
    /** Nose */
    position: absolute;
    top: 0px;
    left: -10px;
    width: 40px;
    height: 20px;
    border-radius: 20px;
    background: #f1c5b4;
    }
    .wizard-head .wizard-face .wizard-adds::after {
    /** Ear */
    content: "";
    position: absolute;
    top: 5px;
    left: 80px;
    width: 15px;
    height: 20px;
    border-bottom-right-radius: 20px;
    border-top-right-radius: 20px;
    background: #f1c5b4;
    }
    .wizard-head .wizard-hat {
    position: absolute;
    bottom: 106px;
    left: 0;
    width: 160px;
    height: 20px;
    border-radius: 20px;
    background: #3f64ce;
    }
    .wizard-head .wizard-hat::before {
    content: "";
    position: absolute;
    top: -70px;
    left: 50%;
    -webkit-transform: translatex(-50%);
    transform: translatex(-50%);
    width: 0;
    height: 0;
    border-style: solid;
    border-width: 0 34px 70px 50px;
    border-color: transparent transparent #3f64ce transparent;
    }
    .wizard-head .wizard-hat::after {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 160px;
    height: 20px;
    background: #3f64ce;
    border-radius: 20px;
    }
    .wizard-head .wizard-hat .wizard-hat-of-the-hat {
    position: absolute;
    bottom: 78px;
    left: 79px;
    width: 0;
    height: 0;
    border-style: solid;
    border-width: 0 25px 25px 19px;
    border-color: transparent transparent #3f64ce transparent;
    }
    .wizard-head .wizard-hat .wizard-hat-of-the-hat::after {
    content: "";
    position: absolute;
    top: 6px;
    left: -4px;
    width: 35px;
    height: 10px;
    border-radius: 10px;
    border-bottom-left-radius: 0px;
    background: #3f64ce;
    -webkit-transform: rotate(40deg);
    transform: rotate(40deg);
    }
    .wizard-head .wizard-hat .wizard-four-point-star {
    position: absolute;
    width: 12px;
    height: 12px;
    }
    .wizard-head .wizard-hat .wizard-four-point-star::after, .wizard-head .wizard-hat .wizard-four-point-star::before {
    content: "";
    position: absolute;
    background: #ffffff;
    display: block;
    left: 0;
    width: 141.4213%;
    /* 100% * √2 */
    top: 0;
    bottom: 0;
    border-radius: 10%;
    -webkit-transform: rotate(66.66deg) skewX(45deg);
    transform: rotate(66.66deg) skewX(45deg);
    }
    .wizard-head .wizard-hat .wizard-four-point-star::after {
    -webkit-transform: rotate(156.66deg) skew(45deg);
    transform: rotate(156.66deg) skew(45deg);
    }
    .wizard-head .wizard-hat .wizard-four-point-star.--first {
    bottom: 28px;
    left: 46px;
    }
    .wizard-head .wizard-hat .wizard-four-point-star.--second {
    bottom: 40px;
    left: 80px;
    }
    .wizard-head .wizard-hat .wizard-four-point-star.--third {
    bottom: 15px;
    left: 108px;
    }

    /** 10s animation - 10% = 1s */
    @-webkit-keyframes right_arm {
    0% {
    -webkit-transform: rotate(70deg);
    transform: rotate(70deg);
    }
    10% {
    -webkit-transform: rotate(8deg);
    transform: rotate(8deg);
    }
    15% {
    -webkit-transform: rotate(20deg);
    transform: rotate(20deg);
    }
    20% {
    -webkit-transform: rotate(10deg);
    transform: rotate(10deg);
    }
    25% {
    -webkit-transform: rotate(26deg);
    transform: rotate(26deg);
    }
    30% {
    -webkit-transform: rotate(10deg);
    transform: rotate(10deg);
    }
    35% {
    -webkit-transform: rotate(28deg);
    transform: rotate(28deg);
    }
    40% {
    -webkit-transform: rotate(9deg);
    transform: rotate(9deg);
    }
    45% {
    -webkit-transform: rotate(28deg);
    transform: rotate(28deg);
    }
    50% {
    -webkit-transform: rotate(8deg);
    transform: rotate(8deg);
    }
    58% {
    -webkit-transform: rotate(74deg);
    transform: rotate(74deg);
    }
    62% {
    -webkit-transform: rotate(70deg);
    transform: rotate(70deg);
    }
    }
    @keyframes right_arm {
    0% {
    -webkit-transform: rotate(70deg);
    transform: rotate(70deg);
    }
    10% {
    -webkit-transform: rotate(8deg);
    transform: rotate(8deg);
    }
    15% {
    -webkit-transform: rotate(20deg);
    transform: rotate(20deg);
    }
    20% {
    -webkit-transform: rotate(10deg);
    transform: rotate(10deg);
    }
    25% {
    -webkit-transform: rotate(26deg);
    transform: rotate(26deg);
    }
    30% {
    -webkit-transform: rotate(10deg);
    transform: rotate(10deg);
    }
    35% {
    -webkit-transform: rotate(28deg);
    transform: rotate(28deg);
    }
    40% {
    -webkit-transform: rotate(9deg);
    transform: rotate(9deg);
    }
    45% {
    -webkit-transform: rotate(28deg);
    transform: rotate(28deg);
    }
    50% {
    -webkit-transform: rotate(8deg);
    transform: rotate(8deg);
    }
    58% {
    -webkit-transform: rotate(74deg);
    transform: rotate(74deg);
    }
    62% {
    -webkit-transform: rotate(70deg);
    transform: rotate(70deg);
    }
    }
    @-webkit-keyframes left_arm {
    0% {
    -webkit-transform: rotate(-70deg);
    transform: rotate(-70deg);
    }
    10% {
    -webkit-transform: rotate(6deg);
    transform: rotate(6deg);
    }
    15% {
    -webkit-transform: rotate(-18deg);
    transform: rotate(-18deg);
    }
    20% {
    -webkit-transform: rotate(5deg);
    transform: rotate(5deg);
    }
    25% {
    -webkit-transform: rotate(-18deg);
    transform: rotate(-18deg);
    }
    30% {
    -webkit-transform: rotate(5deg);
    transform: rotate(5deg);
    }
    35% {
    -webkit-transform: rotate(-17deg);
    transform: rotate(-17deg);
    }
    40% {
    -webkit-transform: rotate(5deg);
    transform: rotate(5deg);
    }
    45% {
    -webkit-transform: rotate(-18deg);
    transform: rotate(-18deg);
    }
    50% {
    -webkit-transform: rotate(6deg);
    transform: rotate(6deg);
    }
    58% {
    -webkit-transform: rotate(-74deg);
    transform: rotate(-74deg);
    }
    62% {
    -webkit-transform: rotate(-70deg);
    transform: rotate(-70deg);
    }
    }
    @keyframes left_arm {
    0% {
    -webkit-transform: rotate(-70deg);
    transform: rotate(-70deg);
    }
    10% {
    -webkit-transform: rotate(6deg);
    transform: rotate(6deg);
    }
    15% {
    -webkit-transform: rotate(-18deg);
    transform: rotate(-18deg);
    }
    20% {
    -webkit-transform: rotate(5deg);
    transform: rotate(5deg);
    }
    25% {
    -webkit-transform: rotate(-18deg);
    transform: rotate(-18deg);
    }
    30% {
    -webkit-transform: rotate(5deg);
    transform: rotate(5deg);
    }
    35% {
    -webkit-transform: rotate(-17deg);
    transform: rotate(-17deg);
    }
    40% {
    -webkit-transform: rotate(5deg);
    transform: rotate(5deg);
    }
    45% {
    -webkit-transform: rotate(-18deg);
    transform: rotate(-18deg);
    }
    50% {
    -webkit-transform: rotate(6deg);
    transform: rotate(6deg);
    }
    58% {
    -webkit-transform: rotate(-74deg);
    transform: rotate(-74deg);
    }
    62% {
    -webkit-transform: rotate(-70deg);
    transform: rotate(-70deg);
    }
    }
    @-webkit-keyframes right_hand {
    0% {
    -webkit-transform: rotate(-40deg);
    transform: rotate(-40deg);
    }
    10% {
    -webkit-transform: rotate(-20deg);
    transform: rotate(-20deg);
    }
    15% {
    -webkit-transform: rotate(-5deg);
    transform: rotate(-5deg);
    }
    20% {
    -webkit-transform: rotate(-60deg);
    transform: rotate(-60deg);
    }
    25% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
    }
    30% {
    -webkit-transform: rotate(-60deg);
    transform: rotate(-60deg);
    }
    35% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
    }
    40% {
    -webkit-transform: rotate(-40deg);
    transform: rotate(-40deg);
    }
    45% {
    -webkit-transform: rotate(-60deg);
    transform: rotate(-60deg);
    }
    50% {
    -webkit-transform: rotate(10deg);
    transform: rotate(10deg);
    }
    60% {
    -webkit-transform: rotate(-40deg);
    transform: rotate(-40deg);
    }
    }
    @keyframes right_hand {
    0% {
    -webkit-transform: rotate(-40deg);
    transform: rotate(-40deg);
    }
    10% {
    -webkit-transform: rotate(-20deg);
    transform: rotate(-20deg);
    }
    15% {
    -webkit-transform: rotate(-5deg);
    transform: rotate(-5deg);
    }
    20% {
    -webkit-transform: rotate(-60deg);
    transform: rotate(-60deg);
    }
    25% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
    }
    30% {
    -webkit-transform: rotate(-60deg);
    transform: rotate(-60deg);
    }
    35% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
    }
    40% {
    -webkit-transform: rotate(-40deg);
    transform: rotate(-40deg);
    }
    45% {
    -webkit-transform: rotate(-60deg);
    transform: rotate(-60deg);
    }
    50% {
    -webkit-transform: rotate(10deg);
    transform: rotate(10deg);
    }
    60% {
    -webkit-transform: rotate(-40deg);
    transform: rotate(-40deg);
    }
    }
    @-webkit-keyframes right_finger {
    0% {
    -webkit-transform: translateY(16px);
    transform: translateY(16px);
    }
    10% {
    -webkit-transform: none;
    transform: none;
    }
    50% {
    -webkit-transform: none;
    transform: none;
    }
    60% {
    -webkit-transform: translateY(16px);
    transform: translateY(16px);
    }
    }
    @keyframes right_finger {
    0% {
    -webkit-transform: translateY(16px);
    transform: translateY(16px);
    }
    10% {
    -webkit-transform: none;
    transform: none;
    }
    50% {
    -webkit-transform: none;
    transform: none;
    }
    60% {
    -webkit-transform: translateY(16px);
    transform: translateY(16px);
    }
    }
    @-webkit-keyframes left_finger {
    0% {
    -webkit-transform: scaleX(0);
    transform: scaleX(0);
    }
    10% {
    -webkit-transform: scaleX(1) rotate(6deg);
    transform: scaleX(1) rotate(6deg);
    }
    15% {
    -webkit-transform: scaleX(1) rotate(0deg);
    transform: scaleX(1) rotate(0deg);
    }
    20% {
    -webkit-transform: scaleX(1) rotate(8deg);
    transform: scaleX(1) rotate(8deg);
    }
    25% {
    -webkit-transform: scaleX(1) rotate(0deg);
    transform: scaleX(1) rotate(0deg);
    }
    30% {
    -webkit-transform: scaleX(1) rotate(7deg);
    transform: scaleX(1) rotate(7deg);
    }
    35% {
    -webkit-transform: scaleX(1) rotate(0deg);
    transform: scaleX(1) rotate(0deg);
    }
    40% {
    -webkit-transform: scaleX(1) rotate(5deg);
    transform: scaleX(1) rotate(5deg);
    }
    45% {
    -webkit-transform: scaleX(1) rotate(0deg);
    transform: scaleX(1) rotate(0deg);
    }
    50% {
    -webkit-transform: scaleX(1) rotate(6deg);
    transform: scaleX(1) rotate(6deg);
    }
    58% {
    -webkit-transform: scaleX(0);
    transform: scaleX(0);
    }
    }
    @keyframes left_finger {
    0% {
    -webkit-transform: scaleX(0);
    transform: scaleX(0);
    }
    10% {
    -webkit-transform: scaleX(1) rotate(6deg);
    transform: scaleX(1) rotate(6deg);
    }
    15% {
    -webkit-transform: scaleX(1) rotate(0deg);
    transform: scaleX(1) rotate(0deg);
    }
    20% {
    -webkit-transform: scaleX(1) rotate(8deg);
    transform: scaleX(1) rotate(8deg);
    }
    25% {
    -webkit-transform: scaleX(1) rotate(0deg);
    transform: scaleX(1) rotate(0deg);
    }
    30% {
    -webkit-transform: scaleX(1) rotate(7deg);
    transform: scaleX(1) rotate(7deg);
    }
    35% {
    -webkit-transform: scaleX(1) rotate(0deg);
    transform: scaleX(1) rotate(0deg);
    }
    40% {
    -webkit-transform: scaleX(1) rotate(5deg);
    transform: scaleX(1) rotate(5deg);
    }
    45% {
    -webkit-transform: scaleX(1) rotate(0deg);
    transform: scaleX(1) rotate(0deg);
    }
    50% {
    -webkit-transform: scaleX(1) rotate(6deg);
    transform: scaleX(1) rotate(6deg);
    }
    58% {
    -webkit-transform: scaleX(0);
    transform: scaleX(0);
    }
    }
    @-webkit-keyframes head {
    0% {
    -webkit-transform: rotate(-3deg);
    transform: rotate(-3deg);
    }
    10% {
    -webkit-transform: translatex(10px) rotate(7deg);
    transform: translatex(10px) rotate(7deg);
    }
    50% {
    -webkit-transform: translatex(0px) rotate(0deg);
    transform: translatex(0px) rotate(0deg);
    }
    56% {
    -webkit-transform: rotate(-3deg);
    transform: rotate(-3deg);
    }
    }
    @keyframes head {
    0% {
    -webkit-transform: rotate(-3deg);
    transform: rotate(-3deg);
    }
    10% {
    -webkit-transform: translatex(10px) rotate(7deg);
    transform: translatex(10px) rotate(7deg);
    }
    50% {
    -webkit-transform: translatex(0px) rotate(0deg);
    transform: translatex(0px) rotate(0deg);
    }
    56% {
    -webkit-transform: rotate(-3deg);
    transform: rotate(-3deg);
    }
    }
    /** Objects CSS & Animations */
    .wizard-objects {
    position: relative;
    width: 200px;
    height: 240px;
    }

    .wizard-square {
    position: absolute;
    bottom: -60px;
    left: -5px;
    width: 120px;
    height: 120px;
    border-radius: 50%;
    /** Animation */
    -webkit-transform: rotate(-360deg);
    transform: rotate(-360deg);
    -webkit-animation: path_square 10s ease-in-out infinite;
    animation: path_square 10s ease-in-out infinite;
    }
    .wizard-square::after {
    content: "";
    position: absolute;
    top: 10px;
    left: 0;
    width: 50px;
    height: 50px;
    background: #9ab3f5;
    }

    .wizard-circle {
    position: absolute;
    bottom: 10px;
    left: 0;
    width: 100px;
    height: 100px;
    border-radius: 50%;
    /** Animation */
    -webkit-transform: rotate(-360deg);
    transform: rotate(-360deg);
    -webkit-animation: path_circle 10s ease-in-out infinite;
    animation: path_circle 10s ease-in-out infinite;
    }
    .wizard-circle::after {
    content: "";
    position: absolute;
    bottom: -10px;
    left: 25px;
    width: 50px;
    height: 50px;
    border-radius: 50%;
    background: #c56183;
    }

    .wizard-triangle {
    position: absolute;
    bottom: -62px;
    left: -10px;
    width: 110px;
    height: 110px;
    border-radius: 50%;
    /** Animation */
    -webkit-transform: rotate(-360deg);
    transform: rotate(-360deg);
    -webkit-animation: path_triangle 10s ease-in-out infinite;
    animation: path_triangle 10s ease-in-out infinite;
    }
    .wizard-triangle::after {
    content: "";
    position: absolute;
    top: 0;
    right: -10px;
    width: 0;
    height: 0;
    border-style: solid;
    border-width: 0 28px 48px 28px;
    border-color: transparent transparent #89beb3 transparent;
    }

    /** 10s animation - 10% = 1s */
    @-webkit-keyframes path_circle {
    0% {
    -webkit-transform: translateY(0);
    transform: translateY(0);
    }
    10% {
    -webkit-transform: translateY(-100px) rotate(-5deg);
    transform: translateY(-100px) rotate(-5deg);
    }
    55% {
    -webkit-transform: translateY(-100px) rotate(-360deg);
    transform: translateY(-100px) rotate(-360deg);
    }
    58% {
    -webkit-transform: translateY(-100px) rotate(-360deg);
    transform: translateY(-100px) rotate(-360deg);
    }
    63% {
    -webkit-transform: rotate(-360deg);
    transform: rotate(-360deg);
    }
    }
    @keyframes path_circle {
    0% {
    -webkit-transform: translateY(0);
    transform: translateY(0);
    }
    10% {
    -webkit-transform: translateY(-100px) rotate(-5deg);
    transform: translateY(-100px) rotate(-5deg);
    }
    55% {
    -webkit-transform: translateY(-100px) rotate(-360deg);
    transform: translateY(-100px) rotate(-360deg);
    }
    58% {
    -webkit-transform: translateY(-100px) rotate(-360deg);
    transform: translateY(-100px) rotate(-360deg);
    }
    63% {
    -webkit-transform: rotate(-360deg);
    transform: rotate(-360deg);
    }
    }
    @-webkit-keyframes path_square {
    0% {
    -webkit-transform: translateY(0);
    transform: translateY(0);
    }
    10% {
    -webkit-transform: translateY(-155px) translatex(-15px) rotate(10deg);
    transform: translateY(-155px) translatex(-15px) rotate(10deg);
    }
    55% {
    -webkit-transform: translateY(-155px) translatex(-15px) rotate(-350deg);
    transform: translateY(-155px) translatex(-15px) rotate(-350deg);
    }
    57% {
    -webkit-transform: translateY(-155px) translatex(-15px) rotate(-350deg);
    transform: translateY(-155px) translatex(-15px) rotate(-350deg);
    }
    63% {
    -webkit-transform: rotate(-360deg);
    transform: rotate(-360deg);
    }
    }
    @keyframes path_square {
    0% {
    -webkit-transform: translateY(0);
    transform: translateY(0);
    }
    10% {
    -webkit-transform: translateY(-155px) translatex(-15px) rotate(10deg);
    transform: translateY(-155px) translatex(-15px) rotate(10deg);
    }
    55% {
    -webkit-transform: translateY(-155px) translatex(-15px) rotate(-350deg);
    transform: translateY(-155px) translatex(-15px) rotate(-350deg);
    }
    57% {
    -webkit-transform: translateY(-155px) translatex(-15px) rotate(-350deg);
    transform: translateY(-155px) translatex(-15px) rotate(-350deg);
    }
    63% {
    -webkit-transform: rotate(-360deg);
    transform: rotate(-360deg);
    }
    }
    @-webkit-keyframes path_triangle {
    0% {
    -webkit-transform: translateY(0);
    transform: translateY(0);
    }
    10% {
    -webkit-transform: translateY(-172px) translatex(10px) rotate(-10deg);
    transform: translateY(-172px) translatex(10px) rotate(-10deg);
    }
    55% {
    -webkit-transform: translateY(-172px) translatex(10px) rotate(-365deg);
    transform: translateY(-172px) translatex(10px) rotate(-365deg);
    }
    58% {
    -webkit-transform: translateY(-172px) translatex(10px) rotate(-365deg);
    transform: translateY(-172px) translatex(10px) rotate(-365deg);
    }
    63% {
    -webkit-transform: rotate(-360deg);
    transform: rotate(-360deg);
    }
    }
    @keyframes path_triangle {
    0% {
    -webkit-transform: translateY(0);
    transform: translateY(0);
    }
    10% {
    -webkit-transform: translateY(-172px) translatex(10px) rotate(-10deg);
    transform: translateY(-172px) translatex(10px) rotate(-10deg);
    }
    55% {
    -webkit-transform: translateY(-172px) translatex(10px) rotate(-365deg);
    transform: translateY(-172px) translatex(10px) rotate(-365deg);
    }
    58% {
    -webkit-transform: translateY(-172px) translatex(10px) rotate(-365deg);
    transform: translateY(-172px) translatex(10px) rotate(-365deg);
    }
    63% {
    -webkit-transform: rotate(-360deg);
    transform: rotate(-360deg);
    }
    }
  3. 修改[Blogroot]\_config.butterfly.yml中的配置项,

    • 确保你打开了preloader
      -    preloader: false
      + preloader: true
    • 在inject: head:配置项中引入巫师加载动画的css样式
          inject:
      head:
      + - <link rel="stylesheet" link="/css/loading_wizard.css"/>
  4. 运行hexo clean && hexo generate && hexo server即可查看加载动画样式了。

  5. bug归纳

    • 遮罩背景层缩入不完全,左边始终有半扇门的遮罩。
      检查[Blogroot]\themes\butterfly\source\css\_layout\loading.styl
      确保开头为以下内容
      if hexo-config('preloader')
      .loading-bg
      position: fixed
      z-index: 1000 /*这是遮罩背景的三维高度,请确保动画的三维高度大于它*/
      width: 50%
      height: 100%
      background-color: var(--preloader-bg)

      #loading-box
      .loading-left-bg
      @extend .loading-bg
      left: 0 /* 原代码中可能没有这项 */
      .loading-right-bg
      @extend .loading-bg
      right: 0

以下为新版教程,需要改动五个主题源码文件。
相比旧版教程,优势在于可以根据配置项内的指定选项加载对应样式。
不选的样式就不加载了,有效节省资源。
同时优化了代码结构,方便读者融会贯通以后,自行添加其他加载动画。
最新版内容支持自定义图片(png,jpg,gif均可)作为加载动画

由于本教程涉及的所有修改对缩进格式等有严格要求,担心自己控制不好的可以直接下载静态资源,将压缩包内的butterfly文件夹复制到[Blogroot]\theme\目录下覆盖现有主题文件夹即可跳过以下教程的前4步,直接到主题配置文件_config.butterfly.yml中参照第5步修改配置项。

魔改步骤

  1. 修改[Blogroot]\themes\butterfly\layout\includes\loading\loading.pug,直接复制以下代码替换所有原代码。

    if theme.preloader.enable
    if (theme.preloader.load_style === 'spinner-box')
    #loading-box
    .loading-left-bg
    .loading-right-bg
    .spinner-box
    .configure-border-1
    .configure-core
    .configure-border-2
    .configure-core
    .loading-word= _p('loading')
    else if (theme.preloader.load_style === 'wizard')
    #loading-box
    .loading-left-bg
    .loading-right-bg
    .wizard-scene
    .wizard-objects
    .wizard-square
    .wizard-circle
    .wizard-triangle
    .wizard
    .wizard-body
    .wizard-right-arm
    .wizard-right-hand
    .wizard-left-arm
    .wizard-left-hand
    .wizard-head
    .wizard-beard
    .wizard-face
    .wizard-adds
    .wizard-hat
    .wizard-hat-of-the-hat
    .wizard-four-point-star.--first
    .wizard-four-point-star.--second
    .wizard-four-point-star.--third
    else if (theme.preloader.load_style === 'image')
    #loading-box
    .loading-left-bg
    .loading-right-bg
    img.load-image(src=url_for(theme.preloader.load_image) alt='')

    此处第一行的if用于判断preloader功能是否打开。下面的if和else if则是根据配置项的内容加载指定的页面元素。

  2. 修改[Blogroot]\themes\butterfly\source\css\_layout\loading.styl,复制以下代码替换全部内容。

    if hexo-config('preloader.enable') && hexo-config('preloader.load_style') == 'spinner-box'
    .loading-bg
    position: fixed
    z-index: 1000
    width: 50%
    height: 100%
    background-color: var(--preloader-bg)

    #loading-box
    .loading-left-bg
    @extend .loading-bg
    left: 0

    .loading-right-bg
    @extend .loading-bg
    right: 0

    .spinner-box
    position: fixed
    z-index: 1001
    display: flex
    justify-content: center
    align-items: center
    width: 100%
    height: 100vh

    .configure-border-1
    position: absolute
    padding: 3px
    width: 115px
    height: 115px
    background: #ffab91
    animation: configure-clockwise 3s ease-in-out 0s infinite alternate

    .configure-border-2
    left: -115px
    padding: 3px
    width: 115px
    height: 115px
    background: rgb(63, 249, 220)
    transform: rotate(45deg)
    animation: configure-xclockwise 3s ease-in-out 0s infinite alternate

    .loading-word
    position: absolute
    color: var(--preloader-color)
    font-size: .8rem

    .configure-core
    width: 100%
    height: 100%
    background-color: var(--preloader-bg)

    &.loaded
    .loading-left-bg
    transition: all 1.0s
    transform: translate(-100%, 0)

    .loading-right-bg
    transition: all 1.0s
    transform: translate(100%, 0)

    .spinner-box
    display: none

    @keyframes configure-clockwise
    0%
    transform: rotate(0)

    25%
    transform: rotate(90deg)

    50%
    transform: rotate(180deg)

    75%
    transform: rotate(270deg)

    100%
    transform: rotate(360deg)

    @keyframes configure-xclockwise
    0%
    transform: rotate(45deg)

    25%
    transform: rotate(-45deg)

    50%
    transform: rotate(-135deg)

    75%
    transform: rotate(-225deg)

    100%
    transform: rotate(-315deg)
    else if hexo-config('preloader.enable') && hexo-config('preloader.load_style') == 'wizard'
    .loading-bg
    position: fixed
    z-index: 1000
    width: 50%
    height: 100%
    background-color: var(--preloader-bg)

    #loading-box
    position fixed
    z-index 1000
    display -webkit-box
    display flex
    -webkit-box-align center
    align-items center
    -webkit-box-pack center
    justify-content center
    -webkit-box-orient vertical
    -webkit-box-direction normal
    flex-direction column
    flex-wrap wrap
    width 100vw
    height 100vh
    overflow hidden

    .loading-left-bg
    @extend .loading-bg
    left 0

    .loading-right-bg
    @extend .loading-bg
    right 0

    &.loaded
    z-index -1000
    .wizard-scene
    display none
    .loading-left-bg
    transition all 1.0s
    transform translate(-100%, 0)
    .loading-right-bg
    transition all 1.0s
    transform translate(100%, 0)

    .wizard-scene
    position fixed
    z-index 1001
    display -webkit-box
    display flex

    .wizard
    position relative
    width 190px
    height 240px

    .wizard-body
    position absolute
    bottom 0
    left 68px
    height 100px
    width 60px
    background #3f64ce
    &::after
    content ""
    position absolute
    bottom 0
    left 20px
    height 100px
    width 60px
    background #3f64ce
    -webkit-transform skewX(14deg)
    transform skewX(14deg)

    .wizard-right-arm
    position absolute
    bottom 74px
    left 110px
    height 44px
    width 90px
    background #3f64ce
    border-radius 22px
    -webkit-transform-origin 16px 22px
    transform-origin 16px 22px
    -webkit-transform rotate(70deg)
    transform rotate(70deg)
    -webkit-animation right_arm 10s ease-in-out infinite
    animation right_arm 10s ease-in-out infinite
    .right-hand
    position absolute
    right 8px
    bottom 8px
    width 30px
    height 30px
    border-radius 50%
    background #f1c5b4
    -webkit-transform-origin center center
    transform-origin center center
    -webkit-transform rotate(-40deg)
    transform rotate(-40deg)
    -webkit-animation right_hand 10s ease-in-out infinite
    animation right_hand 10s ease-in-out infinite
    .wizard-right-hand
    &::after
    content ""
    position absolute
    right 0px
    top -8px
    width 15px
    height 30px
    border-radius 10px
    background #f1c5b4
    -webkit-transform translateY(16px)
    transform translateY(16px)
    -webkit-animation right_finger 10s ease-in-out infinite
    animation right_finger 10s ease-in-out infinite

    .wizard-left-arm
    position absolute
    bottom 74px
    left 26px
    height 44px
    width 70px
    background #3f64ce
    border-bottom-left-radius 8px
    -webkit-transform-origin 60px 26px
    transform-origin 60px 26px
    -webkit-transform rotate(-70deg)
    transform rotate(-70deg)
    -webkit-animation left_arm 10s ease-in-out infinite
    animation left_arm 10s ease-in-out infinite
    .wizard-left-hand
    position absolute
    left -18px
    top 0
    width 18px
    height 30px
    border-top-left-radius 35px
    border-bottom-left-radius 35px
    background #f1c5b4
    &::after
    content ""
    position absolute
    right 0
    top 0
    width 30px
    height 15px
    border-radius 20px
    background #f1c5b4
    -webkit-transform-origin right bottom
    transform-origin right bottom
    -webkit-transform scaleX(0)
    transform scaleX(0)
    -webkit-animation left_finger 10s ease-in-out infinite
    animation left_finger 10s ease-in-out infinite

    .wizard-head
    position absolute
    top 0
    left 14px
    width 160px
    height 210px
    -webkit-transform-origin center center
    transform-origin center center
    -webkit-transform rotate(-3deg)
    transform rotate(-3deg)
    -webkit-animation head 10s ease-in-out infinite
    animation head 10s ease-in-out infinite
    .wizard-beard
    position absolute
    bottom 0
    left 38px
    height 106px
    width 80px
    border-bottom-right-radius 55%
    background #ffffff
    &::after
    content ""
    position absolute
    top 16px
    left -10px
    width 40px
    height 20px
    border-radius 20px
    background #ffffff
    .wizard-face
    position absolute
    bottom 76px
    left 38px
    height 30px
    width 60px
    background #f1c5b4
    &::before
    content ""
    position absolute
    top 0px
    left 40px
    width 20px
    height 40px
    border-bottom-right-radius 20px
    border-bottom-left-radius 20px
    background #f1c5b4
    &::after
    content ""
    position absolute
    top 16px
    left -10px
    width 50px
    height 20px
    border-radius 20px
    border-bottom-right-radius 0px
    background #ffffff
    .wizard-adds
    position absolute
    top 0px
    left -10px
    width 40px
    height 20px
    border-radius 20px
    background #f1c5b4
    &::after
    content ""
    position absolute
    top 5px
    left 80px
    width 15px
    height 20px
    border-bottom-right-radius 20px
    border-top-right-radius 20px
    background #f1c5b4
    .wizard-hat
    position absolute
    bottom 106px
    left 0
    width 160px
    height 20px
    border-radius 20px
    background #3f64ce
    &::before
    content ""
    position absolute
    top -70px
    left 50%
    -webkit-transform translatex(-50%)
    transform translatex(-50%)
    width 0
    height 0
    border-style solid
    border-width 0 34px 70px 50px
    border-color transparent transparent #3f64ce transparent
    &::after
    content ""
    position absolute
    top 0
    left 0
    width 160px
    height 20px
    background #3f64ce
    border-radius 20px
    .wizard-hat-of-the-hat
    position absolute
    bottom 78px
    left 79px
    width 0
    height 0
    border-style solid
    border-width 0 25px 25px 19px
    border-color transparent transparent #3f64ce transparent
    &::after
    content ""
    position absolute
    top 6px
    left -4px
    width 35px
    height 10px
    border-radius 10px
    border-bottom-left-radius 0px
    background #3f64ce
    -webkit-transform rotate(40deg)
    transform rotate(40deg)
    .wizard-four-point-star
    position absolute
    width 12px
    height 12px
    &::after
    -webkit-transform rotate(156.66deg) skew(45deg)
    transform rotate(156.66deg) skew(45deg)
    &.--first
    bottom 28px
    left 46px
    &.--second
    bottom 40px
    left 80px
    &.--third
    bottom 15px
    left 108px

    .wizard-head .wizard-hat .wizard-four-point-star::after, .wizard-head .wizard-hat .wizard-four-point-star::before
    content ""
    position absolute
    background #ffffff
    display block
    left 0
    width 141.4213%
    top 0
    bottom 0
    border-radius 10%
    -webkit-transform rotate(66.66deg) skewX(45deg)
    transform rotate(66.66deg) skewX(45deg)

    .wizard-objects
    position relative
    width 200px
    height 240px

    .wizard-square
    position absolute
    bottom -60px
    left -5px
    width 120px
    height 120px
    border-radius 50%
    -webkit-transform rotate(-360deg)
    transform rotate(-360deg)
    -webkit-animation path_square 10s ease-in-out infinite
    animation path_square 10s ease-in-out infinite
    &::after
    content ""
    position absolute
    top 10px
    left 0
    width 50px
    height 50px
    background #9ab3f5

    .wizard-circle
    position absolute
    bottom 10px
    left 0
    width 100px
    height 100px
    border-radius 50%
    -webkit-transform rotate(-360deg)
    transform rotate(-360deg)
    -webkit-animation path_circle 10s ease-in-out infinite
    animation path_circle 10s ease-in-out infinite
    &::after
    content ""
    position absolute
    bottom -10px
    left 25px
    width 50px
    height 50px
    border-radius 50%
    background #c56183

    .wizard-triangle
    position absolute
    bottom -62px
    left -10px
    width 110px
    height 110px
    border-radius 50%
    -webkit-transform rotate(-360deg)
    transform rotate(-360deg)
    -webkit-animation path_triangle 10s ease-in-out infinite
    animation path_triangle 10s ease-in-out infinite
    &::after
    content ""
    position absolute
    top 0
    right -10px
    width 0
    height 0
    border-style solid
    border-width 0 28px 48px 28px
    border-color transparent transparent #89beb3 transparent


    /** 10s animation - 10% = 1s */
    @-webkit-keyframes right_arm
    0%
    -webkit-transform: rotate(70deg)
    transform: rotate(70deg)
    10%
    -webkit-transform: rotate(8deg)
    transform: rotate(8deg)
    15%
    -webkit-transform: rotate(20deg)
    transform: rotate(20deg)
    20%
    -webkit-transform: rotate(10deg)
    transform: rotate(10deg)
    25%
    -webkit-transform: rotate(26deg)
    transform: rotate(26deg)
    30%
    -webkit-transform: rotate(10deg)
    transform: rotate(10deg)
    35%
    -webkit-transform: rotate(28deg)
    transform: rotate(28deg)
    40%
    -webkit-transform: rotate(9deg)
    transform: rotate(9deg)
    45%
    -webkit-transform: rotate(28deg)
    transform: rotate(28deg)
    50%
    -webkit-transform: rotate(8deg)
    transform: rotate(8deg)
    58%
    -webkit-transform: rotate(74deg)
    transform: rotate(74deg)
    62%
    -webkit-transform: rotate(70deg)
    transform: rotate(70deg)

    @keyframes right_arm
    0%
    -webkit-transform: rotate(70deg)
    transform: rotate(70deg)
    10%
    -webkit-transform: rotate(8deg)
    transform: rotate(8deg)
    15%
    -webkit-transform: rotate(20deg)
    transform: rotate(20deg)
    20%
    -webkit-transform: rotate(10deg)
    transform: rotate(10deg)
    25%
    -webkit-transform: rotate(26deg)
    transform: rotate(26deg)
    30%
    -webkit-transform: rotate(10deg)
    transform: rotate(10deg)
    35%
    -webkit-transform: rotate(28deg)
    transform: rotate(28deg)
    40%
    -webkit-transform: rotate(9deg)
    transform: rotate(9deg)
    45%
    -webkit-transform: rotate(28deg)
    transform: rotate(28deg)
    50%
    -webkit-transform: rotate(8deg)
    transform: rotate(8deg)
    58%
    -webkit-transform: rotate(74deg)
    transform: rotate(74deg)
    62%
    -webkit-transform: rotate(70deg)
    transform: rotate(70deg)

    @-webkit-keyframes left_arm
    0%
    -webkit-transform: rotate(-70deg)
    transform: rotate(-70deg)
    10%
    -webkit-transform: rotate(6deg)
    transform: rotate(6deg)
    15%
    -webkit-transform: rotate(-18deg)
    transform: rotate(-18deg)
    20%
    -webkit-transform: rotate(5deg)
    transform: rotate(5deg)
    25%
    -webkit-transform: rotate(-18deg)
    transform: rotate(-18deg)
    30%
    -webkit-transform: rotate(5deg)
    transform: rotate(5deg)
    35%
    -webkit-transform: rotate(-17deg)
    transform: rotate(-17deg)
    40%
    -webkit-transform: rotate(5deg)
    transform: rotate(5deg)
    45%
    -webkit-transform: rotate(-18deg)
    transform: rotate(-18deg)
    50%
    -webkit-transform: rotate(6deg)
    transform: rotate(6deg)
    58%
    -webkit-transform: rotate(-74deg)
    transform: rotate(-74deg)
    62%
    -webkit-transform: rotate(-70deg)
    transform: rotate(-70deg)

    @keyframes left_arm
    0%
    -webkit-transform: rotate(-70deg)
    transform: rotate(-70deg)
    10%
    -webkit-transform: rotate(6deg)
    transform: rotate(6deg)
    15%
    -webkit-transform: rotate(-18deg)
    transform: rotate(-18deg)
    20%
    -webkit-transform: rotate(5deg)
    transform: rotate(5deg)
    25%
    -webkit-transform: rotate(-18deg)
    transform: rotate(-18deg)
    30%
    -webkit-transform: rotate(5deg)
    transform: rotate(5deg)
    35%
    -webkit-transform: rotate(-17deg)
    transform: rotate(-17deg)
    40%
    -webkit-transform: rotate(5deg)
    transform: rotate(5deg)
    45%
    -webkit-transform: rotate(-18deg)
    transform: rotate(-18deg)
    50%
    -webkit-transform: rotate(6deg)
    transform: rotate(6deg)
    58%
    -webkit-transform: rotate(-74deg)
    transform: rotate(-74deg)
    62%
    -webkit-transform: rotate(-70deg)
    transform: rotate(-70deg)

    @-webkit-keyframes right_hand
    0%
    -webkit-transform: rotate(-40deg)
    transform: rotate(-40deg)
    10%
    -webkit-transform: rotate(-20deg)
    transform: rotate(-20deg)
    15%
    -webkit-transform: rotate(-5deg)
    transform: rotate(-5deg)
    20%
    -webkit-transform: rotate(-60deg)
    transform: rotate(-60deg)
    25%
    -webkit-transform: rotate(0deg)
    transform: rotate(0deg)
    30%
    -webkit-transform: rotate(-60deg)
    transform: rotate(-60deg)
    35%
    -webkit-transform: rotate(0deg)
    transform: rotate(0deg)
    40%
    -webkit-transform: rotate(-40deg)
    transform: rotate(-40deg)
    45%
    -webkit-transform: rotate(-60deg)
    transform: rotate(-60deg)
    50%
    -webkit-transform: rotate(10deg)
    transform: rotate(10deg)
    60%
    -webkit-transform: rotate(-40deg)
    transform: rotate(-40deg)


    @keyframes right_hand
    0%
    -webkit-transform: rotate(-40deg)
    transform: rotate(-40deg)
    10%
    -webkit-transform: rotate(-20deg)
    transform: rotate(-20deg)
    15%
    -webkit-transform: rotate(-5deg)
    transform: rotate(-5deg)
    20%
    -webkit-transform: rotate(-60deg)
    transform: rotate(-60deg)
    25%
    -webkit-transform: rotate(0deg)
    transform: rotate(0deg)
    30%
    -webkit-transform: rotate(-60deg)
    transform: rotate(-60deg)
    35%
    -webkit-transform: rotate(0deg)
    transform: rotate(0deg)
    40%
    -webkit-transform: rotate(-40deg)
    transform: rotate(-40deg)
    45%
    -webkit-transform: rotate(-60deg)
    transform: rotate(-60deg)
    50%
    -webkit-transform: rotate(10deg)
    transform: rotate(10deg)
    60%
    -webkit-transform: rotate(-40deg)
    transform: rotate(-40deg)

    @-webkit-keyframes right_finger
    0%
    -webkit-transform: translateY(16px)
    transform: translateY(16px)
    10%
    -webkit-transform: none
    transform: none
    50%
    -webkit-transform: none
    transform: none
    60%
    -webkit-transform: translateY(16px)
    transform: translateY(16px)

    @keyframes right_finger
    0%
    -webkit-transform: translateY(16px)
    transform: translateY(16px)
    10%
    -webkit-transform: none
    transform: none
    50%
    -webkit-transform: none
    transform: none
    60%
    -webkit-transform: translateY(16px)
    transform: translateY(16px)

    @-webkit-keyframes left_finger
    0%
    -webkit-transform: scaleX(0)
    transform: scaleX(0)
    10%
    -webkit-transform: scaleX(1) rotate(6deg)
    transform: scaleX(1) rotate(6deg)
    15%
    -webkit-transform: scaleX(1) rotate(0deg)
    transform: scaleX(1) rotate(0deg)
    20%
    -webkit-transform: scaleX(1) rotate(8deg)
    transform: scaleX(1) rotate(8deg)
    25%
    -webkit-transform: scaleX(1) rotate(0deg)
    transform: scaleX(1) rotate(0deg)
    30%
    -webkit-transform: scaleX(1) rotate(7deg)
    transform: scaleX(1) rotate(7deg)
    35%
    -webkit-transform: scaleX(1) rotate(0deg)
    transform: scaleX(1) rotate(0deg)
    40%
    -webkit-transform: scaleX(1) rotate(5deg)
    transform: scaleX(1) rotate(5deg)
    45%
    -webkit-transform: scaleX(1) rotate(0deg)
    transform: scaleX(1) rotate(0deg)
    50%
    -webkit-transform: scaleX(1) rotate(6deg)
    transform: scaleX(1) rotate(6deg)
    58%
    -webkit-transform: scaleX(0)
    transform: scaleX(0)

    @keyframes left_finger
    0%
    -webkit-transform: scaleX(0)
    transform: scaleX(0)
    10%
    -webkit-transform: scaleX(1) rotate(6deg)
    transform: scaleX(1) rotate(6deg)
    15%
    -webkit-transform: scaleX(1) rotate(0deg)
    transform: scaleX(1) rotate(0deg)
    20%
    -webkit-transform: scaleX(1) rotate(8deg)
    transform: scaleX(1) rotate(8deg)
    25%
    -webkit-transform: scaleX(1) rotate(0deg)
    transform: scaleX(1) rotate(0deg)
    30%
    -webkit-transform: scaleX(1) rotate(7deg)
    transform: scaleX(1) rotate(7deg)
    35%
    -webkit-transform: scaleX(1) rotate(0deg)
    transform: scaleX(1) rotate(0deg)
    40%
    -webkit-transform: scaleX(1) rotate(5deg)
    transform: scaleX(1) rotate(5deg)
    45%
    -webkit-transform: scaleX(1) rotate(0deg)
    transform: scaleX(1) rotate(0deg)
    50%
    -webkit-transform: scaleX(1) rotate(6deg)
    transform: scaleX(1) rotate(6deg)
    58%
    -webkit-transform: scaleX(0)
    transform: scaleX(0)

    @-webkit-keyframes head
    0%
    -webkit-transform: rotate(-3deg)
    transform: rotate(-3deg)
    10%
    -webkit-transform: translatex(10px) rotate(7deg)
    transform: translatex(10px) rotate(7deg)
    50%
    -webkit-transform: translatex(0px) rotate(0deg)
    transform: translatex(0px) rotate(0deg)
    56%
    -webkit-transform: rotate(-3deg)
    transform: rotate(-3deg)

    @keyframes head
    0%
    -webkit-transform: rotate(-3deg)
    transform: rotate(-3deg)
    10%
    -webkit-transform: translatex(10px) rotate(7deg)
    transform: translatex(10px) rotate(7deg)
    50%
    -webkit-transform: translatex(0px) rotate(0deg)
    transform: translatex(0px) rotate(0deg)
    56%
    -webkit-transform: rotate(-3deg)
    transform: rotate(-3deg)
    /** 10s animation - 10% = 1s */
    @-webkit-keyframes path_circle
    0%
    -webkit-transform: translateY(0)
    transform: translateY(0)
    10%
    -webkit-transform: translateY(-100px) rotate(-5deg)
    transform: translateY(-100px) rotate(-5deg)
    55%
    -webkit-transform: translateY(-100px) rotate(-360deg)
    transform: translateY(-100px) rotate(-360deg)
    58%
    -webkit-transform: translateY(-100px) rotate(-360deg)
    transform: translateY(-100px) rotate(-360deg)
    63%
    -webkit-transform: rotate(-360deg)
    transform: rotate(-360deg)

    @keyframes path_circle
    0%
    -webkit-transform: translateY(0)
    transform: translateY(0)
    10%
    -webkit-transform: translateY(-100px) rotate(-5deg)
    transform: translateY(-100px) rotate(-5deg)
    55%
    -webkit-transform: translateY(-100px) rotate(-360deg)
    transform: translateY(-100px) rotate(-360deg)
    58%
    -webkit-transform: translateY(-100px) rotate(-360deg)
    transform: translateY(-100px) rotate(-360deg)
    63%
    -webkit-transform: rotate(-360deg)
    transform: rotate(-360deg)

    @-webkit-keyframes path_square
    0%
    -webkit-transform: translateY(0)
    transform: translateY(0)
    10%
    -webkit-transform: translateY(-155px) translatex(-15px) rotate(10deg)
    transform: translateY(-155px) translatex(-15px) rotate(10deg)
    55%
    -webkit-transform: translateY(-155px) translatex(-15px) rotate(-350deg)
    transform: translateY(-155px) translatex(-15px) rotate(-350deg)
    57%
    -webkit-transform: translateY(-155px) translatex(-15px) rotate(-350deg)
    transform: translateY(-155px) translatex(-15px) rotate(-350deg)
    63%
    -webkit-transform: rotate(-360deg)
    transform: rotate(-360deg)

    @keyframes path_square
    0%
    -webkit-transform: translateY(0)
    transform: translateY(0)
    10%
    -webkit-transform: translateY(-155px) translatex(-15px) rotate(10deg)
    transform: translateY(-155px) translatex(-15px) rotate(10deg)
    55%
    -webkit-transform: translateY(-155px) translatex(-15px) rotate(-350deg)
    transform: translateY(-155px) translatex(-15px) rotate(-350deg)
    57%
    -webkit-transform: translateY(-155px) translatex(-15px) rotate(-350deg)
    transform: translateY(-155px) translatex(-15px) rotate(-350deg)
    63%
    -webkit-transform: rotate(-360deg)
    transform: rotate(-360deg)

    @-webkit-keyframes path_triangle
    0%
    -webkit-transform: translateY(0)
    transform: translateY(0)
    10%
    -webkit-transform: translateY(-172px) translatex(10px) rotate(-10deg)
    transform: translateY(-172px) translatex(10px) rotate(-10deg)
    55%
    -webkit-transform: translateY(-172px) translatex(10px) rotate(-365deg)
    transform: translateY(-172px) translatex(10px) rotate(-365deg)
    58%
    -webkit-transform: translateY(-172px) translatex(10px) rotate(-365deg)
    transform: translateY(-172px) translatex(10px) rotate(-365deg)
    63%
    -webkit-transform: rotate(-360deg)
    transform: rotate(-360deg)

    @keyframes path_triangle
    0%
    -webkit-transform: translateY(0)
    transform: translateY(0)
    10%
    -webkit-transform: translateY(-172px) translatex(10px) rotate(-10deg)
    transform: translateY(-172px) translatex(10px) rotate(-10deg)
    55%
    -webkit-transform: translateY(-172px) translatex(10px) rotate(-365deg)
    transform: translateY(-172px) translatex(10px) rotate(-365deg)
    58%
    -webkit-transform: translateY(-172px) translatex(10px) rotate(-365deg)
    transform: translateY(-172px) translatex(10px) rotate(-365deg)
    63%
    -webkit-transform: rotate(-360deg)
    transform: rotate(-360deg)

    else if hexo-config('preloader.enable') && hexo-config('preloader.load_style') == 'image'
    .loading-bg
    position: fixed
    z-index: 1000
    width: 50%
    height: 100%
    background-color: var(--preloader-bg)

    #loading-box
    position fixed
    z-index 1000
    display -webkit-box
    display flex
    -webkit-box-align center
    align-items center
    -webkit-box-pack center
    justify-content center
    -webkit-box-orient vertical
    -webkit-box-direction normal
    flex-direction column
    flex-wrap wrap
    width 100vw
    height 100vh
    overflow hidden

    .load-image
    position fixed
    z-index 1001
    display flex

    .loading-left-bg
    @extend .loading-bg
    left 0

    .loading-right-bg
    @extend .loading-bg
    right 0

    &.loaded
    z-index -1000
    .load-image
    display none
    .loading-left-bg
    transition all 1.0s
    transform translate(-100%, 0)
    .loading-right-bg
    transition all 1.0s
    transform translate(100%, 0)

    三个if的判断机制与loading.pug类似,都是根据配置项来决定加载的样式。

  3. 修改[Blogroot]\themes\butterfly\layout\includes\layout.pug,以适配接下来需要添加的配置项。

        body
    - if theme.preloader
    + if theme.preloader.enable
    !=partial('includes/loading/loading', {}, {cache:theme.fragment_cache})
  4. 修改[Blogroot]\themes\butterfly\source\css\var.styl,添加自定义修改背景色的配置项。(98行的位置)

          // preloader
    - $preloader-bg = #37474f
    + $preloader-bg = hexo-config('preloader.enable') && hexo-config('preloader.load_color') ? convert(hexo-config('preloader.load_color')) : #37474f
    $preloader-word-color = #fff
  5. 修改[Blogroot]\_config.butterfly.ymlpreloader配置项。

        # Loading Animation (加載動畫)
    - preloader: true
    + preloader:
    + enable: true # true|false
    + load_color: '#000000' # '#37474f'
    + load_style: wizard # spinner-box|wizard|image
    + load_image: # url

    配置项参数说明:

    1. enable:控制加载动画的开关,取值有truefalsetrue开启,false关闭。
    2. load_color:该配置项为自定义加载动画背景颜色。默认值为#37474f,使用时注意用’’包起来,不然会被识别成注释符。
      这个配置项最大的作用是配合load_image使用的图片的背景色,可以用取色器提取自定义图片的主要色调,以达到图片和背景融为一体的效果。
    3. load_style:控制加载动画的样式,目前提供三种类型。
      • spinner-box是主题原版的盒子加载动画
      • wizard是与本站同款的巫师加载动画
      • image为自定义添加静态图片或gif作为加载动画。
    4. load_image:该配置项的生效前提是load_style设置为image,内容填写图床链接或者本地相对地址。

    熟悉魔改思路以后可以自定义添加更多更多样式,按照本教程的思路,在编译时只会加载选择的加载动画的对应样式,所以不用担心资源占用过多的问题。

  6. 此项为非必要修改项,主要是为了避免使用image主题时,切换夜间模式后,背景色被强制覆盖为黑色,说白了就是治疗强迫症。修改[Blogroot]\themes\butterfly\source\css\_mode\darkmode.styl第10行的--preloader-bg: darken(#121212, 2)

        --search-input-color: alpha(#FFFFFF, .7)
    --search-result-title: alpha(#FFFFFF, .9)
    - --preloader-bg: darken(#121212, 2)
    + --preloader-bg: darken(#ca3b3e, -2)
    --preloader-color: alpha(#FFFFFF, .7)
    --tab-border-color: #2c2c2c

    其中#ca3b3e是设置为image主题时,切换为夜间模式后,自定义图片的背景色值。(切换夜间模式时,整个页面会降低色调,所以连带着自定义图片的色值也变暗,需要重新取值。)

补充内容

很多同学表示添加了加载动画以后加载半天,只能看动画却进不了站我的加载动画还被Heo说成是无限施法2333。这点主要是因为加载动画的关闭与否是与网站加载状态的load的返回值决定的,而网站加载完成与否这个概念是很暧昧的,如果加装了pwa,清空缓存后再次加载的内容可能比想象的要多。
所以可以给加载动画设置一个settimeout()的函数来达到伪·加载完毕的效果,即超时了自动关闭加载动画,即使页面还在加载。
得益于loading-js使用的是原生js,所以可以给script添加async属性实现异步加载,以免阻塞后续HTML渲染。
仅仅需要给控制加载动画开关的loading-js.pug添加两行代码即可。

-   script.
+ script(async).
var preloader = {
endLoading: () => {
document.body.style.overflow = 'auto';
document.getElementById('loading-box').classList.add("loaded")
},
initLoading: () => {
document.body.style.overflow = '';
document.getElementById('loading-box').classList.remove("loaded")

}
}
window.addEventListener('load',()=> {preloader.endLoading()})
+ setTimeout(function(){preloader.endLoading();}, 5000);

其中5000的单位是ms,代表你设置的最大容忍时间。可以自行修改。
这样一来,如果网站在五秒内加载完成,则优先执行window.addEventListener(‘load’,()=> {preloader.endLoading()}),如果超过5秒,则执行 setTimeout(function(){preloader.endLoading();}, 5000);,两者互不干扰。可喜可贺,可喜可贺。

思路分享

理论上你可以任意更改加载动画的内容,放置gif,放置静态图片,添加html,甚至是放置一个html5小游戏,只要是能够写在静态页面里的内容,都可以放在这里。当然,过于复杂的加载动画肯定是要牺牲掉网页加载速度的。

  1. 首先我们必须了解加载动画涉及到哪几个文件的修改。

    • [Blogroot]\themes\butterfly\layout\includes\layout.pug
      这个负责读取配置文件中关于preloader的true or false 取值来确定是否加载loading-box。
    • [Blogroot]\themes\butterfly\source\css\_layout\loading.styl
      这个控制加载动画的样式,这里我的建议是尽量不要动它原有的内容,相反还能利用它已有的样式添加动态帷幕背景。也就是加载完成后背景向两边拉开的特效。
    • [Blogroot]\themes\butterfly\layout\includes\loading\loading-js.pug
      这个会根据页面的加载完成事件给loading-box下的元素添加一个loaded的class,可以利用它来控制页面加载完成后,加载动画内元素的隐藏。
    • [Blogroot]\themes\butterfly\layout\includes\loading\loading.pug
      加载动画布局的主要内容。需要用到pug语法。不懂的可以直接利用在线网站将html转为pug。
      html to pug互转在线网站。
  2. 如示例一样,如果想要保留背景拉开帷幕的效果,我们可以保留loading.pug的前三行,在第四行与.loading-right-bg保持相同缩进来添加新的页面元素。

  3. 样式不建议修改loading.styl,直接引入相应的css文件即可。
    之后,为了保证加载完成,我们需要给自己添加的元素新增一个隐藏的属性。
    例如示例中,巫师动画的顶层元素是.wizard-scene,所以需要添加

    #loading-box.loaded .wizard-scene{
    display: none;
    }

    个别情况可能会遇到画布三维层级混乱,就需要定义loading-box的z-index属性。

    /* 加载前 */
    #loading-box {
    position: fixed;
    z-index: 1000;
    /* 此处设为1000是因为loading.styl中给loading-bg定义的z-index:就是1000 */

    /* 加载后 */
    #loading-box.loaded{
    z-index: -1000;
    }

欢迎在评论区留下你的设想。或者是托我帮忙做加载动画的样式适配(好看的话还是会帮忙的),或者是添加新的配置项构思(啊,我就客套一下,不要真的提太麻烦的需求)