amtoaer

晓风残月

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

本站のテーマを変更しました!

話は 4 日前に遡ります...

その日、私はいつものようにウェブサイトをブラウジングしていて、偶然DIYgodさんのブログを見つけました。この美しいテーマを見て、自分が使っている簡素すぎるnextを振り返り、テーマを変更したいという思いが芽生えました。

footerの情報をもとに、このテーマSagiriのホスティングアドレスを見つけてダウンロードし、_config.ymlファイルを設定してhexo sを実行しました。これで終わりだと思っていました。しかし、残念ながら、多くの機能が正常に動作しないことに気づきました。彼自身がこの記事で書いているように:

テーマはオープンソースですが、自己使用の性質のプロジェクトであり、カスタマイズ可能な部分が多く作られていません。オープンソースプロジェクトの視点から見ると、あまり良くできていません。そして、私は現在テーマを作ることにあまり興味がないので、使用する前に慎重に考えてください。

しかし、これは後の話です。当時の私はこれらを見ていなかったので、頭を固くしてテーマファイルの増減改修の道を歩み始めました(ここでは 1 万字省略)。


4 日が経ち、ファイルの深い分析を通じて(本来あったモジュールを削除して再追加することを指します)、私はcsshtml、およびjavascriptを深く理解し、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に移行され、国内のブラウジング速度が大幅に向上しました。(香港サーバーは最高です!)

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。