hexo+yilia添加背景特效


添加多種頁面背景特效,參考:Hexo 博客優化之博客美化系列(持續更新),需要注意的是:添加背景特效是很消耗瀏覽器內容的,建議只選擇其中的一兩個。

套路說明

爲防止後面的代碼遺漏了什麼東西,在這裏統一說明:添加背景動畫的套路(適用於各種hexo主題):

  1. 新建生成動畫的JS文件,或者引入現成的JS文件的CDN文件(我這裏爲了備份,基本是新建文件;比較有名的特效一般都會上傳到GitHub,而且有引入CDN的相關介紹)。我的文件放再H:\Hexo\themes\yilia\source\js\目錄下。
  2. 因爲背景特效屬於陪襯類,也就是說不是很重要的,所以一般都是在加載完頁面之後再引入的。因此我們在頁面的</body>標籤前引入即可。yilia主題是在H:\Hexo\themes\yilia\layout\layout.ejs中,其他主題類似。
  3. 在2中引入需要設置成配置時,即當配置文件中開啓設置時,纔會開啓這個特效。因此最後一步是在主題的配置文件中開啓配置。yilia主題是在H:\Hexo\themes\yilia\_config.yml中,其他主題類似。

鼠標點擊出現愛心特效

新建H:\Hexo\themes\yilia\source\js\love.js:

(function (window, document, undefined) {
    var hearts = [];
    window.requestAnimationFrame = (function () {
        return window.requestAnimationFrame ||
            window.webkitRequestAnimationFrame ||
            window.mozRequestAnimationFrame ||
            window.oRequestAnimationFrame ||
            window.msRequestAnimationFrame ||
            function (callback) {
                setTimeout(callback, 1000 / 60);
            }
    })();
    init();

    function init() {
        css(
            ".heart{width: 10px;height: 10px;position: fixed;background: #f00;transform: rotate(45deg);-webkit-transform: rotate(45deg);-moz-transform: rotate(45deg);}.heart:after,.heart:before{content: '';width: inherit;height: inherit;background: inherit;border-radius: 50%;-webkit-border-radius: 50%;-moz-border-radius: 50%;position: absolute;}.heart:after{top: -5px;}.heart:before{left: -5px;}"
        );
        attachEvent();
        gameloop();
    }

    function gameloop() {
        for (var i = 0; i < hearts.length; i++) {
            if (hearts[i].alpha <= 0) {
                document.body.removeChild(hearts[i].el);
                hearts.splice(i, 1);
                continue;
            }
            hearts[i].y--;
            hearts[i].scale += 0.004;
            hearts[i].alpha -= 0.013;
            hearts[i].el.style.cssText = "left:" + hearts[i].x + "px;top:" + hearts[i].y + "px;opacity:" + hearts[i]
                .alpha + ";transform:scale(" + hearts[i].scale + "," + hearts[i].scale +
                ") rotate(45deg);background:" + hearts[i].color;
        }
        requestAnimationFrame(gameloop);
    }

    function attachEvent() {
        var old = typeof window.onclick === "function" && window.onclick;
        window.onclick = function (event) {
            old && old();
            createHeart(event);
        }
    }

    function createHeart(event) {
        var d = document.createElement("div");
        d.className = "heart";
        hearts.push({
            el: d,
            x: event.clientX - 5,
            y: event.clientY - 5,
            scale: 1,
            alpha: 1,
            color: randomColor()
        });
        document.body.appendChild(d);
    }

    function css(css) {
        var style = document.createElement("style");
        style.type = "text/css";
        try {
            style.appendChild(document.createTextNode(css));
        } catch (ex) {
            style.styleSheet.cssText = css;
        }
        document.getElementsByTagName('head')[0].appendChild(style);
    }

    function randomColor() {
        return "rgb(" + (~~(Math.random() * 255)) + "," + (~~(Math.random() * 255)) + "," + (~~(Math.random() * 255)) +
            ")";
    }
})(window, document);

添加到H:\Hexo\themes\yilia\layout\layout.ejs</body>

<!-- 《頁面點擊小紅心 -->
<% if (theme.love){ %>
    <script type="text/javascript" src="/js/love.js"></script>
<% } %>
<!-- 頁面點擊小紅心》 -->

開啓配置H:\Hexo\themes\yilia\_config.yml

# 頁面點擊小紅心
love: true

file

鼠標點擊顯示文字–需要引入jQuery

H:\Hexo\themes\yilia\source\js\click_show_text.js

var a_idx = 0;
jQuery(document).ready(function($) {
    $("body").click(function(e) {
        var a = new Array
        ("富強", "民主", "文明", "和諧", "自由", "平等", "公正", "法治", "愛國", "敬業", "誠信", "友善");
        var $i = $("<span/>").text(a[a_idx]);
        a_idx = (a_idx + 1) % a.length;
        var x = e.pageX,
        y = e.pageY;
        $i.css({
            "z-index": 5,
            "top": y - 20,
            "left": x,
            "position": "absolute",
            "font-weight": "bold",
            "color": "#FF0000"
        });
        $("body").append($i);
        $i.animate({
            "top": y - 180,
            "opacity": 0
        },
			3000,
			function() {
			    $i.remove();
			});
    });
    setTimeout('delay()', 2000);
});

function delay() {
    $(".buryit").removeAttr("onclick");
}

H:\Hexo\themes\yilia\layout\layout.ejs

<!--單擊顯示文字-->
<% if (theme.click_show_text){ %>
    <script type="text/javascript" src="/js/click_show_text.js"></script>
<% } %>

H:\Hexo\themes\yilia\_config.yml

# 鼠標點擊顯示文字
click_show_text: true

file

鼠標點擊煙花爆炸效果

H:\Hexo\themes\yilia\source\js\fireworks.js

"use strict";

function updateCoords(e) {
    pointerX = (e.clientX || e.touches[0].clientX) - canvasEl.getBoundingClientRect().left, pointerY = e.clientY || e.touches[
        0].clientY - canvasEl.getBoundingClientRect().top
}

function setParticuleDirection(e) {
    var t = anime.random(0, 360) * Math.PI / 180,
        a = anime.random(50, 180),
        n = [-1, 1][anime.random(0, 1)] * a;
    return {
        x: e.x + n * Math.cos(t),
        y: e.y + n * Math.sin(t)
    }
}

function createParticule(e, t) {
    var a = {};
    return a.x = e, a.y = t, a.color = colors[anime.random(0, colors.length - 1)], a.radius = anime.random(16, 32), a.endPos =
        setParticuleDirection(a), a.draw = function () {
            ctx.beginPath(), ctx.arc(a.x, a.y, a.radius, 0, 2 * Math.PI, !0), ctx.fillStyle = a.color, ctx.fill()
        }, a
}

function createCircle(e, t) {
    var a = {};
    return a.x = e, a.y = t, a.color = "#F00", a.radius = 0.1, a.alpha = 0.5, a.lineWidth = 6, a.draw = function () {
        ctx.globalAlpha = a.alpha, ctx.beginPath(), ctx.arc(a.x, a.y, a.radius, 0, 2 * Math.PI, !0), ctx.lineWidth =
            a.lineWidth, ctx.strokeStyle = a.color, ctx.stroke(), ctx.globalAlpha = 1
    }, a
}

function renderParticule(e) {
    for (var t = 0; t < e.animatables.length; t++) {
        e.animatables[t].target.draw()
    }
}

function animateParticules(e, t) {
    for (var a = createCircle(e, t), n = [], i = 0; i < numberOfParticules; i++) {
        n.push(createParticule(e, t))
    }
    anime.timeline().add({
        targets: n,
        x: function (e) {
            return e.endPos.x
        },
        y: function (e) {
            return e.endPos.y
        },
        radius: 0.1,
        duration: anime.random(1200, 1800),
        easing: "easeOutExpo",
        update: renderParticule
    }).add({
        targets: a,
        radius: anime.random(80, 160),
        lineWidth: 0,
        alpha: {
            value: 0,
            easing: "linear",
            duration: anime.random(600, 800)
        },
        duration: anime.random(1200, 1800),
        easing: "easeOutExpo",
        update: renderParticule,
        offset: 0
    })
}

function debounce(e, t) {
    var a;
    return function () {
        var n = this,
            i = arguments;
        clearTimeout(a), a = setTimeout(function () {
            e.apply(n, i)
        }, t)
    }
}
var canvasEl = document.querySelector(".fireworks");
if (canvasEl) {
    var ctx = canvasEl.getContext("2d"),
        numberOfParticules = 30,
        pointerX = 0,
        pointerY = 0,
        tap = "mousedown",
        colors = ["#FF1461", "#18FF92", "#5A87FF", "#FBF38C"],
        setCanvasSize = debounce(function () {
            canvasEl.width = 2 * window.innerWidth, canvasEl.height = 2 * window.innerHeight, canvasEl.style.width =
                window.innerWidth + "px", canvasEl.style.height = window.innerHeight + "px", canvasEl.getContext(
                    "2d").scale(2, 2)
        }, 500),
        render = anime({
            duration: 1 / 0,
            update: function () {
                ctx.clearRect(0, 0, canvasEl.width, canvasEl.height)
            }
        });
    document.addEventListener(tap, function (e) {
        "sidebar" !== e.target.id && "toggle-sidebar" !== e.target.id && "A" !== e.target.nodeName && "IMG" !==
            e.target.nodeName && (render.play(), updateCoords(e), animateParticules(pointerX, pointerY))
    }, !1), setCanvasSize(), window.addEventListener("resize", setCanvasSize, !1)
}
"use strict";

function updateCoords(e) {
    pointerX = (e.clientX || e.touches[0].clientX) - canvasEl.getBoundingClientRect().left, pointerY = e.clientY || e.touches[
        0].clientY - canvasEl.getBoundingClientRect().top
}

function setParticuleDirection(e) {
    var t = anime.random(0, 360) * Math.PI / 180,
        a = anime.random(50, 180),
        n = [-1, 1][anime.random(0, 1)] * a;
    return {
        x: e.x + n * Math.cos(t),
        y: e.y + n * Math.sin(t)
    }
}

function createParticule(e, t) {
    var a = {};
    return a.x = e, a.y = t, a.color = colors[anime.random(0, colors.length - 1)], a.radius = anime.random(16, 32), a.endPos =
        setParticuleDirection(a), a.draw = function () {
            ctx.beginPath(), ctx.arc(a.x, a.y, a.radius, 0, 2 * Math.PI, !0), ctx.fillStyle = a.color, ctx.fill()
        }, a
}

function createCircle(e, t) {
    var a = {};
    return a.x = e, a.y = t, a.color = "#F00", a.radius = 0.1, a.alpha = 0.5, a.lineWidth = 6, a.draw = function () {
        ctx.globalAlpha = a.alpha, ctx.beginPath(), ctx.arc(a.x, a.y, a.radius, 0, 2 * Math.PI, !0), ctx.lineWidth =
            a.lineWidth, ctx.strokeStyle = a.color, ctx.stroke(), ctx.globalAlpha = 1
    }, a
}

function renderParticule(e) {
    for (var t = 0; t < e.animatables.length; t++) {
        e.animatables[t].target.draw()
    }
}

function animateParticules(e, t) {
    for (var a = createCircle(e, t), n = [], i = 0; i < numberOfParticules; i++) {
        n.push(createParticule(e, t))
    }
    anime.timeline().add({
        targets: n,
        x: function (e) {
            return e.endPos.x
        },
        y: function (e) {
            return e.endPos.y
        },
        radius: 0.1,
        duration: anime.random(1200, 1800),
        easing: "easeOutExpo",
        update: renderParticule
    }).add({
        targets: a,
        radius: anime.random(80, 160),
        lineWidth: 0,
        alpha: {
            value: 0,
            easing: "linear",
            duration: anime.random(600, 800)
        },
        duration: anime.random(1200, 1800),
        easing: "easeOutExpo",
        update: renderParticule,
        offset: 0
    })
}

function debounce(e, t) {
    var a;
    return function () {
        var n = this,
            i = arguments;
        clearTimeout(a), a = setTimeout(function () {
            e.apply(n, i)
        }, t)
    }
}
var canvasEl = document.querySelector(".fireworks");
if (canvasEl) {
    var ctx = canvasEl.getContext("2d"),
        numberOfParticules = 30,
        pointerX = 0,
        pointerY = 0,
        tap = "mousedown",
        colors = ["#FF1461", "#18FF92", "#5A87FF", "#FBF38C"],
        setCanvasSize = debounce(function () {
            canvasEl.width = 2 * window.innerWidth, canvasEl.height = 2 * window.innerHeight, canvasEl.style.width =
                window.innerWidth + "px", canvasEl.style.height = window.innerHeight + "px", canvasEl.getContext(
                    "2d").scale(2, 2)
        }, 500),
        render = anime({
            duration: 1 / 0,
            update: function () {
                ctx.clearRect(0, 0, canvasEl.width, canvasEl.height)
            }
        });
    document.addEventListener(tap, function (e) {
        "sidebar" !== e.target.id && "toggle-sidebar" !== e.target.id && "A" !== e.target.nodeName && "IMG" !==
            e.target.nodeName && (render.play(), updateCoords(e), animateParticules(pointerX, pointerY))
    }, !1), setCanvasSize(), window.addEventListener("resize", setCanvasSize, !1)
};

H:\Hexo\themes\yilia\layout\layout.ejs

<!--鼠標點擊煙花爆炸效果,需要引入jQuery-->
<% if (theme.fireworks){ %>
    <canvas class="fireworks" style="position: fixed;left: 0;top: 0;z-index: 1; pointer-events: none;" ></canvas> 
    <script type="text/javascript" src="//cdn.bootcss.com/animejs/2.2.0/anime.min.js"></script> 
    <script type="text/javascript" src="/js/fireworks.js"></script>
<% } %>

H:\Hexo\themes\yilia\_config.yml

# 鼠標點擊煙花爆炸效果
fireworks: true

file

動態線條背景

https://github.com/hustcc/canvas-nest.js

H:\Hexo\themes\yilia\layout\layout.ejs

直接方法

<!--動態線條背景-->
<script type="text/javascript"
color="220,220,220" opacity='0.7' zIndex="-2" count="200" src="//cdn.bootcss.com/canvas-nest.js/1.0.0/canvas-nest.min.js">
</script>

配置式:

<!--動態線條背景-->
<% if (theme.canvas_nest.enable){ %>
    <script type="text/javascript" color="<%=theme.canvas_nest.color %>" opacity="<%=theme.canvas_nest.opacity %>" 
        zIndex="<%=theme.canvas_nest.zIndex %>" count="<%=theme.canvas_nest.count %>" 
        src="//cdn.bootcss.com/canvas-nest.js/1.0.0/canvas-nest.min.js">
    </script>
<% } %>

H:\Hexo\themes\yilia\_config.yml

# https://github.com/hustcc/canvas-nest.js
# 配置詳見: https://github.com/hustcc/canvas-nest.js#configuration
# 動態線條效果,會向鼠標集中
canvas_nest:
  enable: true
  color: '255, 235, 59'        # color of lines, default: '0,0,0'; RGB values: (R,G,B).(note: use ',' to separate.)
  pointColor: '156,39,176'     # color of points, default: '0,0,0'; RGB values: (R,G,B).(note: use ',' to separate.)
  opacity: '0.8'               # the opacity of line (0~1), default: 0.5.
  count: '99'                  # the number of lines, default: 99.
  zIndex: '-1'                 # z-index property of the background, default: -1.

file

雪花特效2.大雪花(有齒輪)

H:\Hexo\themes\yilia\source\js\snow2.js

/*樣式一*/
(function ($) {
    $.fn.snow = function (options) {
        var $flake = $('<div id="snowbox" />').css({
                'position': 'absolute',
                'z-index': '9999',
                'top': '-50px'
            }).html('❄'),
            documentHeight = $(document).height(),
            documentWidth = $(document).width(),
            defaults = {
                minSize: 10,
                maxSize: 20,
                newOn: 1000,
                flakeColor: "#AFDAEF" /* 此處可以定義雪花顏色,若要白色可以改爲#FFFFFF */
            },
            options = $.extend({}, defaults, options);
        var interval = setInterval(function () {
            var startPositionLeft = Math.random() * documentWidth - 100,
                startOpacity = 0.5 + Math.random(),
                sizeFlake = options.minSize + Math.random() * options.maxSize,
                endPositionTop = documentHeight - 200,
                endPositionLeft = startPositionLeft - 500 + Math.random() * 500,
                durationFall = documentHeight * 10 + Math.random() * 5000;
            $flake.clone().appendTo('body').css({
                left: startPositionLeft,
                opacity: startOpacity,
                'font-size': sizeFlake,
                color: options.flakeColor
            }).animate({
                top: endPositionTop,
                left: endPositionLeft,
                opacity: 0.2
            }, durationFall, 'linear', function () {
                $(this).remove()
            });
        }, options.newOn);
    };
})(jQuery);
$(function () {
    $.fn.snow({
        minSize: 5,
        /* 定義雪花最小尺寸 */
        maxSize: 50,
        /* 定義雪花最大尺寸 */
        newOn: 300 /* 定義密集程度,數字越小越密集 */
    });
});

H:\Hexo\themes\yilia\layout\layout.ejs

<!-- 雪花特效2 -->
<% if (theme.snow2){ %>
  <script type="text/javascript" src="/js/snow2.js"></script>
<% } %>

H:\Hexo\themes\yilia\_config.yml

# 雪花特效2
snow2: true

file

雪花特效3.小雪花(無齒輪)

H:\Hexo\themes\yilia\source\js\snow3.js

/*樣式二*/
/* 控制下雪 */
function snowFall(snow) {
    /* 可配置屬性 */
    snow = snow || {};
    this.maxFlake = snow.maxFlake || 200; /* 最多片數 */
    this.flakeSize = snow.flakeSize || 10; /* 雪花形狀 */
    this.fallSpeed = snow.fallSpeed || 1; /* 墜落速度 */
}
/* 兼容寫法 */
requestAnimationFrame = window.requestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    window.oRequestAnimationFrame ||
    function (callback) {
        setTimeout(callback, 1000 / 60);
    };

cancelAnimationFrame = window.cancelAnimationFrame ||
    window.mozCancelAnimationFrame ||
    window.webkitCancelAnimationFrame ||
    window.msCancelAnimationFrame ||
    window.oCancelAnimationFrame;
/* 開始下雪 */
snowFall.prototype.start = function () {
    /* 創建畫布 */
    snowCanvas.apply(this);
    /* 創建雪花形狀 */
    createFlakes.apply(this);
    /* 畫雪 */
    drawSnow.apply(this)
}
/* 創建畫布 */
function snowCanvas() {
    /* 添加Dom結點 */
    var snowcanvas = document.createElement("canvas");
    snowcanvas.id = "snowfall";
    snowcanvas.width = window.innerWidth;
    snowcanvas.height = document.body.clientHeight;
    snowcanvas.setAttribute("style", "position:absolute; top: 0; left: 0; z-index: 1; pointer-events: none;");
    document.getElementsByTagName("body")[0].appendChild(snowcanvas);
    this.canvas = snowcanvas;
    this.ctx = snowcanvas.getContext("2d");
    /* 窗口大小改變的處理 */
    window.onresize = function () {
        snowcanvas.width = window.innerWidth;
        /* snowcanvas.height = window.innerHeight */
    }
}
/* 雪運動對象 */
function flakeMove(canvasWidth, canvasHeight, flakeSize, fallSpeed) {
    this.x = Math.floor(Math.random() * canvasWidth); /* x座標 */
    this.y = Math.floor(Math.random() * canvasHeight); /* y座標 */
    this.size = Math.random() * flakeSize + 2; /* 形狀 */
    this.maxSize = flakeSize; /* 最大形狀 */
    this.speed = Math.random() * 1 + fallSpeed; /* 墜落速度 */
    this.fallSpeed = fallSpeed; /* 墜落速度 */
    this.velY = this.speed; /* Y方向速度 */
    this.velX = 0; /* X方向速度 */
    this.stepSize = Math.random() / 30; /* 步長 */
    this.step = 0 /* 步數 */
}
flakeMove.prototype.update = function () {
    var x = this.x,
        y = this.y;
    /* 左右擺動(餘弦) */
    this.velX *= 0.98;
    if (this.velY <= this.speed) {
        this.velY = this.speed
    }
    this.velX += Math.cos(this.step += .05) * this.stepSize;

    this.y += this.velY;
    this.x += this.velX;
    /* 飛出邊界的處理 */
    if (this.x >= canvas.width || this.x <= 0 || this.y >= canvas.height || this.y <= 0) {
        this.reset(canvas.width, canvas.height)
    }
};
/* 飛出邊界-放置最頂端繼續墜落 */
flakeMove.prototype.reset = function (width, height) {
    this.x = Math.floor(Math.random() * width);
    this.y = 0;
    this.size = Math.random() * this.maxSize + 2;
    this.speed = Math.random() * 1 + this.fallSpeed;
    this.velY = this.speed;
    this.velX = 0;
};
// 渲染雪花-隨機形狀(此處可修改雪花顏色!!!)
flakeMove.prototype.render = function (ctx) {
    var snowFlake = ctx.createRadialGradient(this.x, this.y, 0, this.x, this.y, this.size);
    snowFlake.addColorStop(0, "rgba(255, 255, 255, 0.9)"); /* 此處是雪花顏色,默認是白色 */
    snowFlake.addColorStop(.5, "rgba(255, 255, 255, 0.5)"); /* 若要改爲其他顏色,請自行查 */
    snowFlake.addColorStop(1, "rgba(255, 255, 255, 0)"); /* 找16進制的RGB 顏色代碼。 */
    ctx.save();
    ctx.fillStyle = snowFlake;
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
    ctx.fill();
    ctx.restore();
};
/* 創建雪花-定義形狀 */
function createFlakes() {
    var maxFlake = this.maxFlake,
        flakes = this.flakes = [],
        canvas = this.canvas;
    for (var i = 0; i < maxFlake; i++) {
        flakes.push(new flakeMove(canvas.width, canvas.height, this.flakeSize, this.fallSpeed))
    }
}
/* 畫雪 */
function drawSnow() {
    var maxFlake = this.maxFlake,
        flakes = this.flakes;
    ctx = this.ctx, canvas = this.canvas, that = this;
    /* 清空雪花 */
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    for (var e = 0; e < maxFlake; e++) {
        flakes[e].update();
        flakes[e].render(ctx);
    }
    /*  一幀一幀的畫 */
    this.loop = requestAnimationFrame(function () {
        drawSnow.apply(that);
    });
}
/* 調用及控制方法 */
var snow = new snowFall({
    maxFlake: 60
});
snow.start();

H:\Hexo\themes\yilia\layout\layout.ejs

<!-- 雪花特效3 -->
<% if (theme.snow3){ %>
  <script type="text/javascript" src="/js/snow3.js"></script>
<% } %>

H:\Hexo\themes\yilia\_config.yml

# 雪花特效3
snow3: false

file

綵帶1.鼠標點擊自動替換綵帶

H:\Hexo\themes\yilia\source\js\ribbon.js

/**
 * Copyright (c) 2016 hustcc
 * License: MIT
 * Version: v1.0.1
 * GitHub: https://github.com/hustcc/ribbon.js
**/
/*jshint -W030 */
! function() {
  function attr(node, attr, default_value) {
    return Number(node.getAttribute(attr)) || default_value;
  }

  // get user config
  var scripts = document.getElementsByTagName('script'),
    script = scripts[scripts.length - 1]; // 當前加載的script
  config = {
    z: attr(script, "zIndex", -1), // z-index
    a: attr(script, "alpha", 0.6), // alpha
    s: attr(script, "size", 90), // size
  };

  var canvas = document.createElement('canvas'),
    g2d = canvas.getContext('2d'),
    pr = window.devicePixelRatio || 1,
    width = window.innerWidth,
    height = window.innerHeight,
    f = config.s,
    q, t,
    m = Math,
    r = 0,
    pi = m.PI*2,
    cos = m.cos,
    random = m.random;
  canvas.width = width * pr;
  canvas.height = height * pr;
  g2d.scale(pr, pr);
  g2d.globalAlpha = config.a;
  canvas.style.cssText = 'opacity: ' + config.a + ';position:fixed;top:0;left:0;z-index: ' + config.z + ';width:100%;height:100%;pointer-events:none;';
  // create canvas
  document.getElementsByTagName('body')[0].appendChild(canvas);

  function redraw() {
    g2d.clearRect(0, 0, width, height);
    q = [{x: 0, y: height * 0.7 + f}, {x: 0, y: height * 0.7 - f}];
    while(q[1].x < width + f) draw(q[0], q[1]);
  }
  function draw(i, j) {
    g2d.beginPath();
    g2d.moveTo(i.x, i.y);
    g2d.lineTo(j.x, j.y);
    var k = j.x + (random()*2-0.25)*f, n = line(j.y);
    g2d.lineTo(k, n);
    g2d.closePath();
    r -= pi / -50;
    g2d.fillStyle = '#'+(cos(r)*127+128<<16 | cos(r+pi/3)*127+128<<8 | cos(r+pi/3*2)*127+128).toString(16);
    g2d.fill();
    q[0] = q[1];
    q[1] = {x: k, y: n};
  }
  function line(p){
    t = p + (random() * 2 - 1.1) * f;
    return (t > height || t < 0) ? line(p) : t;
  }

  document.onclick = redraw;
  document.ontouchstart = redraw;
  redraw();
}();

H:\Hexo\themes\yilia\layout\layout.ejs

<!--綵帶1.點擊自動替換綵帶-->
<% if (theme.ribbon){ %>
    <!-- <script src="https://g.joyinshare.com/hc/ribbon.min.js" type="text/javascript"></script> -->
    <script type="text/javascript" src="/js/ribbon.js"></script>
<% } %>

H:\Hexo\themes\yilia\_config.yml

# https://github.com/hustcc/ribbon.js
# 綵帶1.點擊自動替換綵帶
ribbon: false

file

綵帶2.自動飄動

H:\Hexo\themes\yilia\source\js\ribbon_flow.js

(function (name, factory) {
    if (typeof window === "object") {
        window[name] = factory()
    }
})("Ribbons", function () {
    var _w = window,
        _b = document.body,
        _d = document.documentElement;
    var random = function () {
        if (arguments.length === 1) {
            if (Array.isArray(arguments[0])) {
                var index = Math.round(random(0, arguments[0].length - 1));
                return arguments[0][index]
            }
            return random(0, arguments[0])
        } else if (arguments.length === 2) {
            return Math.random() * (arguments[1] - arguments[0]) + arguments[0]
        }
        return 0
    };
    var screenInfo = function (e) {
        var width = Math.max(0, _w.innerWidth || _d.clientWidth || _b.clientWidth || 0),
            height = Math.max(0, _w.innerHeight || _d.clientHeight || _b.clientHeight || 0),
            scrollx = Math.max(0, _w.pageXOffset || _d.scrollLeft || _b.scrollLeft || 0) - (_d.clientLeft || 0),
            scrolly = Math.max(0, _w.pageYOffset || _d.scrollTop || _b.scrollTop || 0) - (_d.clientTop || 0);
        return {
            width: width,
            height: height,
            ratio: width / height,
            centerx: width / 2,
            centery: height / 2,
            scrollx: scrollx,
            scrolly: scrolly
        }
    };
    var mouseInfo = function (e) {
        var screen = screenInfo(e),
            mousex = e ? Math.max(0, e.pageX || e.clientX || 0) : 0,
            mousey = e ? Math.max(0, e.pageY || e.clientY || 0) : 0;
        return {
            mousex: mousex,
            mousey: mousey,
            centerx: mousex - screen.width / 2,
            centery: mousey - screen.height / 2
        }
    };
    var Point = function (x, y) {
        this.x = 0;
        this.y = 0;
        this.set(x, y)
    };
    Point.prototype = {
        constructor: Point,
        set: function (x, y) {
            this.x = x || 0;
            this.y = y || 0
        },
        copy: function (point) {
            this.x = point.x || 0;
            this.y = point.y || 0;
            return this
        },
        multiply: function (x, y) {
            this.x *= x || 1;
            this.y *= y || 1;
            return this
        },
        divide: function (x, y) {
            this.x /= x || 1;
            this.y /= y || 1;
            return this
        },
        add: function (x, y) {
            this.x += x || 0;
            this.y += y || 0;
            return this
        },
        subtract: function (x, y) {
            this.x -= x || 0;
            this.y -= y || 0;
            return this
        },
        clampX: function (min, max) {
            this.x = Math.max(min, Math.min(this.x, max));
            return this
        },
        clampY: function (min, max) {
            this.y = Math.max(min, Math.min(this.y, max));
            return this
        },
        flipX: function () {
            this.x *= -1;
            return this
        },
        flipY: function () {
            this.y *= -1;
            return this
        }
    };
    var Factory = function (options) {
        this._canvas = null;
        this._context = null;
        this._sto = null;
        this._width = 0;
        this._height = 0;
        this._scroll = 0;
        this._ribbons = [];
        this._options = {
            colorSaturation: "80%",
            colorBrightness: "60%",
            colorAlpha: 0.65,
            colorCycleSpeed: 6,
            verticalPosition: "center",
            horizontalSpeed: 150,
            ribbonCount: 5,
            strokeSize: 5,
            parallaxAmount: -0.5,
            animateSections: true
        };
        this._onDraw = this._onDraw.bind(this);
        this._onResize = this._onResize.bind(this);
        this._onScroll = this._onScroll.bind(this);
        this.setOptions(options);
        this.init()
    };
    Factory.prototype = {
        constructor: Factory,
        setOptions: function (options) {
            if (typeof options === "object") {
                for (var key in options) {
                    if (options.hasOwnProperty(key)) {
                        this._options[key] = options[key]
                    }
                }
            }
        },
        init: function () {
            try {
                this._canvas = document.createElement("canvas");
                this._canvas.style["display"] = "block";
                this._canvas.style["position"] = "fixed";
                this._canvas.style["margin"] = "0";
                this._canvas.style["padding"] = "0";
                this._canvas.style["border"] = "0";
                this._canvas.style["outline"] = "0";
                this._canvas.style["left"] = "0";
                this._canvas.style["top"] = "0";
                this._canvas.style["width"] = "100%";
                this._canvas.style["height"] = "100%";
                this._canvas.style["z-index"] = "-1";
                this._onResize();
                this._context = this._canvas.getContext("2d");
                this._context.clearRect(0, 0, this._width, this._height);
                this._context.globalAlpha = this._options.colorAlpha;
                window.addEventListener("resize", this._onResize);
                window.addEventListener("scroll", this._onScroll);
                document.body.appendChild(this._canvas)
            } catch (e) {
                console.warn("Canvas Context Error: " + e.toString());
                return
            }
            this._onDraw()
        },
        addRibbon: function () {
            var dir = Math.round(random(1, 9)) > 5 ? "right" : "left",
                stop = 1000,
                hide = 200,
                min = 0 - hide,
                max = this._width + hide,
                movex = 0,
                movey = 0,
                startx = dir === "right" ? min : max,
                starty = Math.round(random(0, this._height));
            if (/^(top|min)$/i.test(this._options.verticalPosition)) {
                starty = 0 + hide
            } else if (/^(middle|center)$/i.test(this._options.verticalPosition)) {
                starty = this._height / 2
            } else if (/^(bottom|max)$/i.test(this._options.verticalPosition)) {
                starty = this._height - hide
            }
            var ribbon = [],
                point1 = new Point(startx, starty),
                point2 = new Point(startx, starty),
                point3 = null,
                color = Math.round(random(0, 360)),
                delay = 0;
            while (true) {
                if (stop <= 0) break;
                stop--;
                movex = Math.round((Math.random() * 1 - 0.2) * this._options.horizontalSpeed);
                movey = Math.round((Math.random() * 1 - 0.5) * (this._height * 0.25));
                point3 = new Point();
                point3.copy(point2);
                if (dir === "right") {
                    point3.add(movex, movey);
                    if (point2.x >= max) break
                } else if (dir === "left") {
                    point3.subtract(movex, movey);
                    if (point2.x <= min) break
                }
                ribbon.push({
                    point1: new Point(point1.x, point1.y),
                    point2: new Point(point2.x, point2.y),
                    point3: point3,
                    color: color,
                    delay: delay,
                    dir: dir,
                    alpha: 0,
                    phase: 0
                });
                point1.copy(point2);
                point2.copy(point3);
                delay += 4;
                color += this._options.colorCycleSpeed
            }
            this._ribbons.push(ribbon)
        },
        _drawRibbonSection: function (section) {
            if (section) {
                if (section.phase >= 1 && section.alpha <= 0) {
                    return true
                }
                if (section.delay <= 0) {
                    section.phase += 0.02;
                    section.alpha = Math.sin(section.phase) * 1;
                    section.alpha = section.alpha <= 0 ? 0 : section.alpha;
                    section.alpha = section.alpha >= 1 ? 1 : section.alpha;
                    if (this._options.animateSections) {
                        var mod = Math.sin(1 + section.phase * Math.PI / 2) * 0.1;
                        if (section.dir === "right") {
                            section.point1.add(mod, 0);
                            section.point2.add(mod, 0);
                            section.point3.add(mod, 0)
                        } else {
                            section.point1.subtract(mod, 0);
                            section.point2.subtract(mod, 0);
                            section.point3.subtract(mod, 0)
                        }
                        section.point1.add(0, mod);
                        section.point2.add(0, mod);
                        section.point3.add(0, mod)
                    }
                } else {
                    section.delay -= 0.5
                }
                var s = this._options.colorSaturation,
                    l = this._options.colorBrightness,
                    c = "hsla(" + section.color + ", " + s + ", " + l + ", " + section.alpha + " )";
                this._context.save();
                if (this._options.parallaxAmount !== 0) {
                    this._context.translate(0, this._scroll * this._options.parallaxAmount)
                }
                this._context.beginPath();
                this._context.moveTo(section.point1.x, section.point1.y);
                this._context.lineTo(section.point2.x, section.point2.y);
                this._context.lineTo(section.point3.x, section.point3.y);
                this._context.fillStyle = c;
                this._context.fill();
                if (this._options.strokeSize > 0) {
                    this._context.lineWidth = this._options.strokeSize;
                    this._context.strokeStyle = c;
                    this._context.lineCap = "round";
                    this._context.stroke()
                }
                this._context.restore()
            }
            return false
        },
        _onDraw: function () {
            for (var i = 0, t = this._ribbons.length; i < t; ++i) {
                if (!this._ribbons[i]) {
                    this._ribbons.splice(i, 1)
                }
            }
            this._context.clearRect(0, 0, this._width, this._height);
            for (var a = 0; a < this._ribbons.length; ++a) {
                var ribbon = this._ribbons[a],
                    numSections = ribbon.length,
                    numDone = 0;
                for (var b = 0; b < numSections; ++b) {
                    if (this._drawRibbonSection(ribbon[b])) {
                        numDone++
                    }
                }
                if (numDone >= numSections) {
                    this._ribbons[a] = null
                }
            }
            if (this._ribbons.length < this._options.ribbonCount) {
                this.addRibbon()
            }
            requestAnimationFrame(this._onDraw)
        },
        _onResize: function (e) {
            var screen = screenInfo(e);
            this._width = screen.width;
            this._height = screen.height;
            if (this._canvas) {
                this._canvas.width = this._width;
                this._canvas.height = this._height;
                if (this._context) {
                    this._context.globalAlpha = this._options.colorAlpha
                }
            }
        },
        _onScroll: function (e) {
            var screen = screenInfo(e);
            this._scroll = screen.scrolly
        }
    };
    return Factory
});
new Ribbons({
    colorSaturation: "60%",
    colorBrightness: "50%",
    colorAlpha: 0.5,
    colorCycleSpeed: 5,
    verticalPosition: "random",
    horizontalSpeed: 200,
    ribbonCount: 3,
    strokeSize: 0,
    parallaxAmount: -0.2,
    animateSections: true
});

H:\Hexo\themes\yilia\layout\layout.ejs

<!--綵帶2.自動飄動-->
<% if (theme.ribbon_flow){ %>
    <!-- <script src="https://g.joyinshare.com/hc/piao.js" type="text/javascript"></script> -->
    <script type="text/javascript" src="/js/ribbon_flow.js"></script>
<% } %>

H:\Hexo\themes\yilia\_config.yml

# 綵帶2.自動飄動
ribbon_flow: false

代碼雨

存在問題:位置不對

H:\Hexo\themes\yilia\source\js\code_rain.js

window.onload = function(){
    //獲取畫布對象
    var canvas = document.getElementById("code_rain_canvas");
    //獲取畫布的上下文
    var context =canvas.getContext("2d");
    var s = window.screen;
    var W = canvas.width = s.width;
    var H = canvas.height;
    //獲取瀏覽器屏幕的寬度和高度
    //var W = window.innerWidth;
    //var H = window.innerHeight;
    //設置canvas的寬度和高度
    canvas.width = W;
    canvas.height = H;
    //每個文字的字體大小
    var fontSize = 12;
    //計算列
    var colunms = Math.floor(W /fontSize);	
    //記錄每列文字的y軸座標
    var drops = [];
    //給每一個文字初始化一個起始點的位置
    for(var i=0;i<colunms;i++){
        drops.push(0);
    }
    //運動的文字
    var str ="WELCOME TO WWW.ITRHX.COM";
    //4:fillText(str,x,y);原理就是去更改y的座標位置
    //繪畫的函數
    function draw(){
        context.fillStyle = "rgba(238,238,238,.08)";//遮蓋層
        context.fillRect(0,0,W,H);
        //給字體設置樣式
        context.font = "600 "+fontSize+"px  Georgia";
        //給字體添加顏色
        context.fillStyle = ["#33B5E5", "#0099CC", "#AA66CC", "#9933CC", "#99CC00", "#669900", "#FFBB33", "#FF8800", "#FF4444", "#CC0000"][parseInt(Math.random() * 10)];//randColor();可以rgb,hsl, 標準色,十六進制顏色
        //寫入畫布中
        for(var i=0;i<colunms;i++){
            var index = Math.floor(Math.random() * str.length);
            var x = i*fontSize;
            var y = drops[i] *fontSize;
            context.fillText(str[index],x,y);
            //如果要改變時間,肯定就是改變每次他的起點
            if(y >= canvas.height && Math.random() > 0.99){
                drops[i] = 0;
            }
            drops[i]++;
        }
    };
    function randColor(){//隨機顏色
        var r = Math.floor(Math.random() * 256);
        var g = Math.floor(Math.random() * 256);
        var b = Math.floor(Math.random() * 256);
        return "rgb("+r+","+g+","+b+")";
    }
    draw();
    setInterval(draw,35);
};

H:\Hexo\themes\yilia\layout\layout.ejs

<!--代碼雨-->
<% if (theme.code_rain){ %>
      <!-- 數字雨 -->
      <canvas id="code_rain_canvas" width="1440" height="900"></canvas>
      <script type="text/javascript" src="/js/code_rain.js">
        <style>
            #code_rain_canvas {
              position: fixed;
              right: 0px;
              bottom: 0px;
              min-width: 100%;
              min-height: 100%;
              height: auto;
              width: auto;
              z-index: 4;
            }
        </style>
    </script>
<% } %>


H:\Hexo\themes\yilia\_config.yml

# 代碼雨
code_rain: true

file


文章首發於:hexo+yilia添加背景特效

發佈了132 篇原創文章 · 獲贊 149 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章