Atom
本站架站紀錄_第一篇

本站架站紀錄_第一篇

紀錄我架站後修改了什麼東西,部分內容從原本鐵人賽那邊複製過來的。

套用主題

本網站套用主題: KIRA

安裝KIRA主題
打開你的終端機運行:

1
yarn create kira-hexo <放網站用的資料夾>

等待安裝完成後

1
hexo s

前往http://localhost:4000就能查看安裝完的網頁了。

修改背景

打開資料夾中的_config.kira.yml

  • 你的大頭貼,直接修改圖片網址就行
    avatar: <圖片路徑或是網址>
  • 背景圖與文章默認圖,直接修改圖片網址就行
    background:
    path: <圖片路徑或是網址>
    width: 1280
    height: 720

可以用記事本或是各種編輯器(我是Notepad++愛好者)打開編輯,記得存檔。

修改文章圖片大小

由於1999的圖片大小與原主題的不同裁切到LOGO,所以我另外寫固定大小樣式。
可以直接依照你圖片大小下去修改。

  • 自訂義樣式
    1
    2
    customStyles:
    - style
    source底下新增style.css這個檔案
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#維持 1669:770 比例,但顯示整張圖
.kira-post-cover {
width: 100% !important;
max-width: 1669px;
aspect-ratio: 1669 / 770 !important;
overflow: hidden;
margin: 0 auto;
background: transparent;
}
.kira-post-cover img {
width: 100% !important;
height: 100% !important;
object-fit: contain !important;
object-position: center !important;
display: block;
}

#文章頁內文圖片:顯示整張圖、不超出版面
.post .kira-article img,
.kira-image img {
display: block;
max-width: 100% !important;
height: auto !important;
object-fit: contain !important;
object-position: center !important;
}

這樣就能顯示整張圖了,可以依照你圖片的大小去修改kira-post-cover的數值。

加入首頁特效

我個人很喜歡Butterfly主題一進去後就是一張大圖片很有震撼感,加上會出現打字特效顯示名言金句,所以打算將這個效果也套過來我的網站。
_config.kira.yml中入以下設定

1
2
3
4
5
6
7
8
9
10
hero:
enable: true
image: /images/<圖片名稱> # 首屏大圖
title: <大標題> # 不填會用 site.title
typing: true # true=打字特效;false=淡入/淡出輪播
typingSpeed: 32 # 打字速度(毫秒/字;typing=true 才有效)
rotateInterval: 4000 # 每句停留毫秒(typing=false 用)
subtitles: # 你要輪播的句子(可放多句)
- 我最擅長的就是一蹶不振。
- 任何困難都能將我擊倒。

之後只改 subtitles 就能換輪播內容;想改速度、是否打字也都在這裡調。

也可以加入隨機句
butterfly是使用Hitokoto這個網站進行隨機產生句子的,類似的網站也有其他可以自己選擇。
Hitokoto
可以自己選擇要電影、動畫、詩詞等等句子

英文的一言網

1
2
3
4
5
6
7
8
9
10
11
12
13
 #加上Hitokoto舉例
hero:
enable: true
image: /images/<圖片名稱> # 首屏大圖
title: <大標題> # 不填會用 site.title
typing: true # true=打字特效;false=淡入/淡出輪播
typingSpeed: 32 # 打字速度(毫秒/字;typing=true 才有效)
rotateInterval: 4000 # 每句停留毫秒(typing=false 用)
subtitles: # 你要輪播的句子(可放多句)
- 我最擅長的就是一蹶不振。
- 任何困難都能將我擊倒。
hitokoto: # (可選)要的分類,留空代表全隨機
categories: [a, b, c] # a動畫 b漫畫 c遊戲 d文學 e原創 f網路 g其他 h影視 i詩詞 j諺語 k歌詞 l成語

將以上設定注入,以及加入特效
我加的效果有:模擬打字效果文字輪播
然後在中下的地方放了一個按鈕,按下去後就會直接到網站頁面

  • 建立資料夾與檔案:
    1
    2
    mkdir -p scripts
    touch scripts/home-hero.js
  • 寫入設定檔
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    /* global hexo */
    // 讀 hero 設定(優先 _config.kira.yml)
    function getHeroCfg(ctx) {
    return (ctx.theme && ctx.theme.config && ctx.theme.config.hero) ||
    (ctx.config && ctx.config.hero) || {};
    }
    function esc(s=''){return String(s).replace(/[&<>"']/g, m=>({ '&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;' }[m]));}

    hexo.extend.filter.register('after_render:html', function (html, data) {
    if (!data || !data.path) return html;
    const isHome = String(data.path).replace(/\\/g,'/') === 'index.html';
    if (!isHome) return html;

    const cfg = getHeroCfg(this);
    if (cfg.enable === false) return html;

    const img = esc(cfg.image || '/images/hero.jpg');
    const title = esc(cfg.title || this.config.title || 'Welcome');
    const typing = !!cfg.typing;
    const speed = Number(cfg.typingSpeed || 32);
    const hold = Number(cfg.rotateInterval || 4000);
    const list = Array.isArray(cfg.subtitles) && cfg.subtitles.length ? cfg.subtitles : ['Welcome.'];
    const json = JSON.stringify(list);

    const headInject = `
    <style id="home-hero-css">
    .hero-banner{
    position:relative;
    width:100vw;
    height:100svh;
    margin:0 0 28px;
    margin-left:calc(50% - 50vw);
    overflow:hidden;
    }
    .hero-bg{position:absolute;inset:0;background-size:cover;background-position:center;filter:brightness(.82)}
    .hero-bg::after{content:"";position:absolute;inset:0;background:rgba(0,0,0,.25)}
    .hero-inner{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;align-items:center;text-align:center;color:#fff;padding:0 1rem}
    .hero-title{font-weight:800;line-height:1.1;font-size:clamp(36px,5vw,64px);text-shadow:0 4px 24px rgba(0,0,0,.5)}
    .hero-sub-wrap{display:inline-flex;align-items:baseline;gap:.25rem;opacity:0;transition:opacity .6s ease}
    .hero-sub{margin-top:.75rem;font-size:clamp(14px,2vw,20px);opacity:.92;text-shadow:0 2px 12px rgba(0,0,0,.4);min-height:1.6em}
    .typed-cursor{display:${typing ? 'inline-block' : 'none'};margin-left:2px;opacity:1;animation:typed-cursor-blink .7s infinite}
    @keyframes typed-cursor-blink{0%,45%{opacity:1}46%,100%{opacity:0}}

    /* ↓ 向下箭頭按鈕(置底中) */
    .hero-down{
    position:absolute; left:50%; bottom:18px; transform:translateX(-50%);
    width:42px; height:42px; border-radius:9999px;
    border:2px solid rgba(255,255,255,.9);
    color:#fff; background:rgba(0,0,0,.18);
    display:flex; align-items:center; justify-content:center;
    cursor:pointer; transition:background .2s ease, transform .2s ease, opacity .2s ease;
    backdrop-filter:blur(2px);
    animation:hero-bounce 1.8s infinite;
    }
    .hero-down:hover{ background:rgba(0,0,0,.28); transform:translateX(-50%) translateY(2px); }
    @keyframes hero-bounce{ 0%,100%{ bottom:18px } 50%{ bottom:24px } }
    .hero-down svg{ display:block }
    </style>`;

    const bodyInject = `
    <div class="hero-banner" role="banner" aria-label="Site hero">
    <div class="hero-bg" style="background-image:url('${img}')"></div>
    <div class="hero-inner">
    <h1 class="hero-title">${title}</h1>
    <div class="hero-sub-wrap" id="hero-sub-wrap">
    <div class="hero-sub" id="hero-sub" aria-live="polite"></div>
    <span class="typed-cursor">|</span>
    </div>
    <!-- 向下箭頭 -->
    <button class="hero-down" id="hero-down" aria-label="捲動到內容">
    <svg width="20" height="20" viewBox="0 0 24 24" aria-hidden="true">
    <path fill="currentColor" d="M12 16.5L4.5 9l1.4-1.4L12 13.7l6.1-6.1L19.5 9z"/>
    </svg>
    </button>
    </div>
    </div>
    <script>
    (function(){
    var items = ${json};
    var el = document.getElementById('hero-sub');
    var wrap = document.getElementById('hero-sub-wrap');
    var typing = ${typing ? 'true' : 'false'};
    var speed = ${speed};
    var hold = ${hold};
    var i = 0;

    function setOpacity(v){ wrap.style.opacity = v; }
    function fadeIn(cb){ requestAnimationFrame(function(){ setOpacity(1); if(cb) setTimeout(cb, 600); }); }
    function fadeOut(cb){ setOpacity(0); if(cb) setTimeout(cb, 600); }

    function typeText(text, done){
    el.textContent = '';
    var j = 0;
    (function tick(){
    if (j < text.length){
    el.textContent += text.charAt(j++);
    setTimeout(tick, speed);
    } else { if (done) done(); }
    })();
    }

    function show(idx){
    var text = String(items[idx]);
    if (typing){
    setOpacity(1);
    typeText(text, function(){ setTimeout(next, hold); });
    } else {
    el.textContent = text;
    fadeIn(function(){ setTimeout(function(){ fadeOut(next); }, hold); });
    }
    }

    function next(){
    i = (i + 1) % items.length;
    if (typing){ fadeOut(function(){ show(i); }); }
    else { show(i); }
    }

    if (!items.length) items = ['Welcome.'];
    if (typing){ setOpacity(0); fadeOut(function(){ show(0); }); } else { show(0); }

    // ↓ 點擊向下箭頭,平滑捲到下一個區塊
    // ↓ 點擊向下箭頭,平滑捲到 Hero 底部(自動扣固定導覽列)
    var btn = document.getElementById('hero-down');
    if (btn){
    btn.addEventListener('click', function(){
    var hero = document.querySelector('.hero-banner');
    if (!hero) return;

    // Hero 底部的頁面座標
    var y = hero.getBoundingClientRect().bottom + window.pageYOffset;

    // 如果有固定 header,就扣掉高度(常見 class/元素都掃過)
    var header = document.querySelector('.kira-header, header, .navbar, .site-header');
    if (header && getComputedStyle(header).position === 'fixed') {
    y -= header.offsetHeight || 0;
    }

    window.scrollTo({ top: Math.max(0, Math.round(y)), behavior: 'smooth' });
    });
    }

    })();
    </script>`;

    html = html.replace('</head>', headInject + '\n</head>');
    html = html.replace('<body>', '<body>\n' + bodyInject);
    return html;
    });
    如果你是使用一言網或是其他網站的話需要額外加function
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #加上Hitokoto舉例
    // JSONP 取得 Hitokoto
    function jsonp(url, cb){
    var fn = 'jp_' + Math.random().toString(36).slice(2);
    window[fn] = function(d){ cb(d); delete window[fn]; s.remove(); };
    var s = document.createElement('script');
    s.src = url + (url.indexOf('?')>-1?'&':'?') + 'callback=' + fn;
    document.body.appendChild(s);
    }

    var toTW = (window.OpenCC && OpenCC.Converter) ? OpenCC.Converter({ from: 'cn', to: 'tw' }) : function(s){return s;};

    jsonp('${hitokotoUrl}', function(d){
    var s = (d && d.hitokoto) ? ('「' + d.hitokoto + '」 — ' + (d.from_who || d.from || '一言')) :
    (fallback.length ? rand(fallback) : 'Welcome.');
    s = toTW(s); // 轉繁體
    start(s);
    });
    })();

一些數值設定說明:

  • 改高度:把 height:100svh 換成 82vh 或 560px (依照你要的大小)
  • 遮罩深淺:改 .hero-bg::after 的 rgba(0,0,0,.25)(越大越暗)
  • 只要版心寬度、不要全幅:把 .hero-banner 的width:100vw 改成 width:100%,並刪掉 margin-left:calc(50% - 50vw)
  • 字幕只顯示一行:在 .hero-sub 補 white-space: nowrap; overflow: hidden; text-overflow: ellipsis;

之後更新在第二篇。


留言區從原本需要登入github才能留言的方式改成使用 Twikoo 不須登入即可留言
如果你要匿名的話姓名、郵箱、網址可以隨便打沒關係
留QQ郵箱的話可以自動偵測郵箱頭像
有想多交流的話可以留網址我看到會過去逛逛


本文作者:Atom
本文鏈接:https://d0ngd.github.io/2025/10/05/本站架站紀錄_第一篇/
版權聲明:本文採用 CC BY-NC-SA 3.0 CN 協議進行許可