amtoaer

晓风残月

叹息似的渺茫,你仍要保存着那真!
github
x
telegram
steam
nintendo switch
email

本站更換主題啦!

故事要從四天前說起...

那天,我像往常一樣刷著網站,偶然發現了DIYgod大佬的博客,看著這精美的主題,再回頭審視一下自己使用的簡陋到爆的next,不禁萌生了更換主題的想法。

根據footer裡的信息,我找到了這個主題Sagiri的托管地址,將其下載了下來,配置好_config.yml文件並hexo s,本以為事情就這樣結束了。然並卵,我發現有很多功能都無法正常使用,正如他本人在這篇文章中寫的一樣:

主題雖然開源了,但是屬於自用性質的項目,很多應該做成可定制化的地方都沒有做,從開源項目的視角來看做得並不好,而我目前又對製作主題並沒有太高的興致,所以使用之前還請慎重考慮

然而這是後話了,當時的我並沒有看到這些,於是頭鐵地開始了主題文件的增刪改查之路(此處省略一萬字)。


四天過去了,通過對文件的深度剖析(指刪除很多本來就有的模塊然後重新添加),我深刻地了解了csshtmljavascript,明白了hexo主題的組織形式(並沒有),於是準備記錄一下這個主題部分特性的實現方式:

  1. 網頁無刷新跳轉 / 自動滾動到正文

    使用pjax實現,主要參考這篇文章

  2. 根據網頁狀態動態修改標題

    // cheat.js
    var OriginTitle = document.title;
    var titleTime;
    document.addEventListener('visibilitychange', function () {
        if (document.hidden) {
            $('[rel="icon"]').attr('href', "/images/failure.ico");
            document.title = '╭(°A°`)╮ 頁面崩潰啦 ~';
            clearTimeout(titleTime);
        }
        else {
            $('[rel="icon"]').attr('href', "/images/favicon.ico");
            document.title = '(ฅ>ω<*ฅ) 噫又好了~' + OriginTitle;
            titleTime = setTimeout(function () {
                document.title = OriginTitle;
            }, 2000);
        }
    });
    
  3. 隨機的絲帶背景

    // evan-you.js
    /*<canvas id="evanyou"></canvas>*/
    if (document.getElementById('evanyou')) {
      var c = document.getElementById('evanyou'),
        x = c.getContext('2d'),
        pr = window.devicePixelRatio || 1,
        w = window.innerWidth,
        h = window.innerHeight,
        f = 90,
        q,
        m = Math,
        r = 0,
        u = m.PI * 2,
        v = m.cos,
        z = m.random
      c.width = w * pr
      c.height = h * pr
      x.scale(pr, pr)
      x.globalAlpha = 0.6
      function evanyou () {
        x.clearRect(0, 0, w, h)
        q = [{ x: 0, y: h * .7 + f }, { x: 0, y: h * .7 - f }]
        while (q[1].x < w + f) d(q[0], q[1])
      }
      function d (i, j) {
        x.beginPath()
        x.moveTo(i.x, i.y)
        x.lineTo(j.x, j.y)
        var k = j.x + (z() * 2 - 0.25) * f,
          n = y(j.y)
        x.lineTo(k, n)
        x.closePath()
        r -= u / -50
        x.fillStyle = '#' + (v(r) * 127 + 128 << 16 | v(r + u / 3) * 127 + 128 << 8 | v(r + u / 3 * 2) * 127 + 128).toString(16)
        x.fill()
        q[0] = q[1]
        q[1] = { x: k, y: n }
      }
      function y (p) {
        var t = p + (z() * 2 - 1.1) * f
        return (t > h || t < 0) ? y(p) : t
      }
      document.onclick = evanyou
      document.ontouchstart = evanyou
      evanyou()
    }
    
  4. 點擊的煙花效果

    // fireworks.js
    class Circle {
      constructor({ origin, speed, color, angle, context }) {
        this.origin = origin
        this.position = { ...this.origin }
        this.color = color
        this.speed = speed
        this.angle = angle
        this.context = context
        this.renderCount = 0
      }
    
      draw() {
        this.context.fillStyle = this.color
        this.context.beginPath()
        this.context.arc(this.position.x, this.position.y, 2, 0, Math.PI * 2)
        this.context.fill()
      }
    
      move() {
        this.position.x = (Math.sin(this.angle) * this.speed) + this.position.x
        this.position.y = (Math.cos(this.angle) * this.speed) + this.position.y + (this.renderCount * 0.3)
        this.renderCount++
      }
    }
    
    class Boom {
      constructor ({ origin, context, circleCount = 16, area }) {
        this.origin = origin
        this.context = context
        this.circleCount = circleCount
        this.area = area
        this.stop = false
        this.circles = []
      }
    
      randomArray(range) {
        const length = range.length
        const randomIndex = Math.floor(length * Math.random())
        return range[randomIndex]
      }
    
      randomColor() {
        const range = ['8', '9', 'A', 'B', 'C', 'D', 'E', 'F']
        return '#' + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range)
      }
    
      randomRange(start, end) {
        return (end - start) * Math.random() + start
      }
    
      init() {
        for(let i = 0; i < this.circleCount; i++) {
          const circle = new Circle({
            context: this.context,
            origin: this.origin,
            color: this.randomColor(),
            angle: this.randomRange(Math.PI - 1, Math.PI + 1),
            speed: this.randomRange(1, 6)
          })
          this.circles.push(circle)
        }
      }
    
      move() {
        this.circles.forEach((circle, index) => {
          if (circle.position.x > this.area.width || circle.position.y > this.area.height) {
            return this.circles.splice(index, 1)
          }
          circle.move()
        })
        if (this.circles.length == 0) {
          this.stop = true
        }
      }
    
      draw() {
        this.circles.forEach(circle => circle.draw())
      }
    }
    
    class CursorSpecialEffects {
      constructor() {
        this.computerCanvas = document.createElement('canvas')
        this.renderCanvas = document.createElement('canvas')
    
        this.computerContext = this.computerCanvas.getContext('2d')
        this.renderContext = this.renderCanvas.getContext('2d')
    
        this.globalWidth = window.innerWidth
        this.globalHeight = window.innerHeight
    
        this.booms = []
        this.running = false
      }
    
      handleMouseDown(e) {
        const boom = new Boom({
          origin: { x: e.clientX, y: e.clientY },
          context: this.computerContext,
          area: {
            width: this.globalWidth,
            height: this.globalHeight
          }
        })
        boom.init()
        this.booms.push(boom)
        this.running || this.run()
      }
    
      handlePageHide() {
        this.booms = []
        this.running = false
      }
    
      init() {
        const style = this.renderCanvas.style
        style.position = 'fixed'
        style.top = style.left = 0
        style.zIndex = '999999999999999999999999999999999999999999'
        style.pointerEvents = 'none'
    
        style.width = this.renderCanvas.width = this.computerCanvas.width = this.globalWidth
        style.height = this.renderCanvas.height = this.computerCanvas.height = this.globalHeight
    
        document.body.append(this.renderCanvas)
    
        window.addEventListener('mousedown', this.handleMouseDown.bind(this))
        window.addEventListener('pagehide', this.handlePageHide.bind(this))
      }
    
      run() {
        this.running = true
        if (this.booms.length == 0) {
          return this.running = false
        }
    
        requestAnimationFrame(this.run.bind(this))
    
        this.computerContext.clearRect(0, 0, this.globalWidth, this.globalHeight)
        this.renderContext.clearRect(0, 0, this.globalWidth, this.globalHeight)
    
        this.booms.forEach((boom, index) => {
          if (boom.stop) {
            return this.booms.splice(index, 1)
          }
          boom.move()
          boom.draw()
        })
        this.renderContext.drawImage(this.computerCanvas, 0, 0, this.globalWidth, this.globalHeight)
      }
    }
    
    const cursorSpecialEffects = new CursorSpecialEffects()
    cursorSpecialEffects.init()
    
  5. 側欄的固定

    使用affix實現,主要參考這篇文章

  6. valine評論系統支持pjax

    參考這個 issue


害,換個主題真的太難了,一年之內不打算再換了!

好了,寫完去睡覺啦 XD!


2020.1.30 23:12:33

全站由github遷移到coding,國內瀏覽速度得到大幅提升。(香港伺服器就是香啊!)

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。