話は 4 日前に遡ります...
その日、私はいつものようにウェブサイトをブラウジングしていて、偶然DIYgodさんのブログを見つけました。この美しいテーマを見て、自分が使っている簡素すぎるnext
を振り返り、テーマを変更したいという思いが芽生えました。
footer
の情報をもとに、このテーマSagiri
のホスティングアドレスを見つけてダウンロードし、_config.yml
ファイルを設定してhexo s
を実行しました。これで終わりだと思っていました。しかし、残念ながら、多くの機能が正常に動作しないことに気づきました。彼自身がこの記事で書いているように:
テーマはオープンソースですが、自己使用の性質のプロジェクトであり、カスタマイズ可能な部分が多く作られていません。オープンソースプロジェクトの視点から見ると、あまり良くできていません。そして、私は現在テーマを作ることにあまり興味がないので、使用する前に慎重に考えてください。
しかし、これは後の話です。当時の私はこれらを見ていなかったので、頭を固くしてテーマファイルの増減改修の道を歩み始めました(ここでは 1 万字省略)。
4 日が経ち、ファイルの深い分析を通じて(本来あったモジュールを削除して再追加することを指します)、私はcss
、html
、およびjavascript
を深く理解し、hexo
テーマの組織形式(実際にはありません)を理解しました。それで、このテーマの特性の実装方法を記録することにしました:
-
ページの無刷新遷移 / 自動スクロール
pjax
を使用して実現し、主にこの記事を参考にしました。 -
ページの状態に応じてタイトルを動的に変更
// 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); } });
-
ランダムなリボン背景
// 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() }
-
クリック時の花火効果
// 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()
-
サイドバーの固定
affix
を使用して実現し、主にこの記事を参考にしました。 -
valine
コメントシステムがpjax
をサポートこの issueを参考にしました。
ああ、テーマを変更するのは本当に難しいですね。一年以内には再度変更するつもりはありません!
さて、書き終えたので寝ます XD!
2020.1.30 23:12:33
全サイトがgithub
からcoding
に移行され、国内のブラウジング速度が大幅に向上しました。(香港サーバーは最高です!)