Interactions & Visual Effects
This page covers the interaction & visual features of the matery theme: code block enhancements, image lightbox, typewriter, page effects, simplified/traditional Chinese conversion, reading progress, back-to-top, rewards, print styles, audio/video players and charts. Each feature lists its config location and how to use it.
All config lives in the theme config
themes/matery/_config.yml(abbreviated “theme config” below). Note: in this project the theme config file is overwritten by theuserConfig/_config.tmp.ymltemplate during CI builds — sync your changes to the template (see the Installation chapter). Some features have no dedicated config key (back-to-top, print styles) — they are built into the theme and work out of the box.
1. Code Block Enhancements
Purpose: code blocks automatically get a language label, copy button, expand/collapse, fullscreen view; overly long code is height-limited.
Config (theme config code block):
code:
shrink: true # code block collapsible (fold arrow)
break: false # wrap long lines
show_full: true # show "expand all" button for long code
height_limit: "450px" # show_full height threshold (expand button above this)
show_expand: true # fullscreen view button
copy_btn: true # copy code button
language:
enable: true # show language label
default: "TEXT" # default label when no language givenExample (standard Markdown code blocks auto-enhanced, no extra markers):
```bash
echo "Hello Matery"
```Effect: language label in the top-right; copy/fullscreen buttons on hover; blocks over height_limit collapse with an “expand” button.
2. Image Lightbox (lightGallery)
Purpose: post images click to enlarge to fullscreen browsing, with zoom, paging, download and auto-generated captions.
Config (theme config, inside the post block):
post:
image_zoom:
enable: true # post images clickable to enlarge
img_url_replace: ['', ''] # link replacement rule when enlarging (e.g. ['-slim', ''] strips the compression suffix; use 're:' prefix for regex)Example (plain Markdown images work, auto-enhanced):
Effect: images are auto-wrapped as .img-item at render time (with data-src original link and caption); clicking opens the .lg-outer lightbox; hover shows a shadow border.
3. Typewriter (Typed)
Purpose: banner subtitle typewriter rotation, post title typing animation.
Config (theme config, two independent places):
# Banner subtitle typewriter (inside the subtitle block)
subtitle:
enable: true
typed:
loop: true # loop rotation
showCursor: true # show cursor
cursorChar: "_" # cursor character
startDelay: 100 # start delay (ms)
typeSpeed: 80 # typing speed (ms/char)
backSpeed: 50 # deleting speed (ms/char)
sub: # rotation sentence list (typed one by one)
- 真经一句话,假经传万卷!
# Subtitle typewriter switch/scope (inside the fun_features block, another entry)
fun_features:
typing:
enable: true
typeSpeed: 70
cursorChar: "_"
loop: false
scope: [] # pages to enable: home | post | tag | category | about | links | page | 404 (empty = all)
# Post page H2 title typewriter (inside the post block)
post:
typed:
enable: true
loop: false
showCursor: true
cursorChar: "_"
startDelay: 50
typeSpeed: 70
backSpeed: 50Effect: the homepage banner subtitle types out character by character and rotates; post page titles (H2) animate typing; cursor blinks.
4. Page Effects
Purpose: 13 decorative effects in two categories — page/background effects (auto-run) and mouse/click effects (interaction-triggered); switchable at runtime via the floating panel on the right.
Config (theme config effects block, single config source after the 2026-08-10 refactor):
effects:
enable: true # master switch: whether the "Page Effects" area shows in the floating panel
desktop_only: true # only inject on desktop (off on mobile for performance)
page: # page/background effects (mutually exclusive, pick one)
default: off # default: off | random | specific id
available:
sakura: { label: 樱花, lib: sakura }
ripples: { label: 水波, lib: ripples }
leaf: { label: 落叶, lib: leaf }
snowdown: { label: 飘雪, lib: snowdown }
snowflake: { label: 雪花, lib: snowflake }
buble: { label: 冒泡, lib: buble }
canvas_nest: { label: 网络, lib: canvas_nest }
ribbon: { label: 彩带, lib: ribbon }
ribbon_dynamic: { label: 动态彩带, lib: ribbon_dynamic }
mouse: # mouse/click effects (mutually exclusive, pick one)
default: off
available:
clicklove: { label: 爱心, lib: clicklove }
popupText: { label: 弹出文字, lib: popupText }
mouseStar: { label: 星星, lib: star }
fireworks: { label: 爆炸, lib: fireworks }Reader-side control: right floating panel → “Page Effects” area: choose Off / Random / a specific effect, no code changes needed.
Note: the legacy standalone
sakura/ripples/clickloveetc. enable config sections are removed and no longer participate in injection; add/remove effects by editing theavailablelists — the panel and runtime adapt automatically (libcorresponds to thetheme.libs.js.*path key).
Effect: sakura petals, ripples, snowflakes, ribbons and other background animations; heart/star/fireworks click feedback.
4.1 Festival Lanterns (dengbox)
Purpose: decorative lanterns on the left/right edges of the page (e.g. “新春/快乐”); lives in the fun_features block (distinct from the effects panel above).
Config (theme config, fun_features block):
fun_features:
dengbox:
enable: false # false | true
left: 新春 # left lantern text
right: 快乐 # right lantern textEffect: one lantern hangs on each side of the page with customizable text; hidden when disabled.
5. Simplified/Traditional Chinese Conversion
Purpose: one-click conversion between traditional and simplified Chinese, remembering the user’s choice in localStorage.
Config (theme config, consolidated into the preference section on 2026-08-16):
preference:
translate:
enable: true # conversion switchEffect: the footer “繁/简” toggle button (#translateLink) converts all text globally and remembers the choice. The legacy footer.translate config was removed on 2026-08-10 (confirmed by the footer.ejs comment); only preference.translate.enable is read.
6. Reading Progress Bar / Back to Top
Purpose: a reading progress bar at the top grows while scrolling; one-click back-to-top button at the bottom right.
Config (theme config; the progress bar lives in the fun_features block):
fun_features:
progressbar:
enable: false # loading progress bar (off by default)
height_px: 3
color: "#29d"
options: { showSpinner: false, trickleSpeed: 100 } # nprogress optionsBack to top: no dedicated config key — the #backTop button is built into the right floating panel (layout/_partial/common/right-floating.ejs), enabled by default.
Effect: the progress bar grows with page load/scroll; the round back-to-top button in the bottom-right scrolls smoothly and resizes on mobile.
7. Reward Popup
Purpose: a “tip” button at the bottom of posts; clicking pops up a WeChat/Alipay QR code dialog.
Config (theme config, inside the post block):
post:
reward:
enable: true
title: 码字辛苦,打赏作者!
wechat: /medias_webp/reward/wechat.webp
alipay: /medias_webp/reward/alipay.webpPer-post control (post front-matter):
reward: true # true enables tipping for this post / false disables (default follows global config)Effect: a “tip” button shows at the bottom of posts; clicking opens the QR code dialog (Alipay/WeChat tabs) with close button and overlay-click dismissal.
8. Print Styles
Purpose: print-optimized layout for posts (hide nav/sidebar/footer, center content, show link URLs).
Config: none needed — print styles are built into the theme CSS (source/css/_pages/_base/print.styl + the @media print rules in color-schema.styl), always active, auto-switching to light variables when printing.
Effect: Ctrl+P prints only the content, full URLs shown next to links, spacing and font sizes optimized for print.
9. Music Player (APlayer)
Purpose: bottom-fixed music player on the homepage/site-wide; MetingJS resolves NetEase and other platform playlists.
Config (theme config music block; there is also a musics block for the standalone music page):
music:
enable: false # enable (off by default)
server: netease # platform: netease | tencent | kugou | xiami | baidu
type: playlist # type: song | playlist | album | search | artist
id: 4965675848 # playlist/song ID
fixed: true # true = fixed mode (floating at the bottom of the page)
autoplay: false
theme: '#42b983'
loop: 'all' # loop: all | one | none
order: 'random' # order: list | random
preload: 'auto' # preload: none | metadata | auto
volume: 0.7 # default volume (player remembers user settings)
listFolded: true # list folded by default
hideLrc: true # hide lyricsEffect: music card (cover + playback controls + progress bar + playlist); floats at the bottom with fixed: true; dark mode adapts automatically.
10. Video Player (DPlayer)
Purpose: embed a DPlayer video player in posts, supporting local videos, HLS live streams and danmaku.
Config: no theme config needed — provided by the hexo-tag-mmedia plugin (DPlayer asset paths in the libs.js.dplayer config).
Example ({% mmedia %} tag, first argument selects the player type):
{% mmedia dplayer url=/medias_webp/video/demo.mp4 %}The example path is illustrative — replace it with your own video file (local path or remote URL).
Full form with cover, danmaku and HLS:
{% mmedia dplayer url=https://example.com/demo.mp4 pic=/medias_webp/featureimages/1.webp id=123456 api=https://api.prprpr.me/dplayer/v3/ %}Effect: play/pause/progress/volume/speed controls, danmaku and HLS live stream support.
11. Bilibili Video Card
Purpose: embed a Bilibili video info card (cover, title, uploader, view count, duration).
Config: no theme config needed — provided by the hexo-bilibili-card-new plugin.
Example ({% bilicard %} tag + BV id; the API is fetched at build time to render the card):
{% bilicard BV1oa4y1L7mw %}Effect: a Bilibili video card renders in the post; clicking jumps to the original video; the card includes cover, title, uploader and play stats.
12. ECharts
Purpose: embed ECharts interactive charts in posts (bar/line/pie etc.), with zoom and tooltip support.
Config (theme config echarts block, controls chart library loading):
echarts:
enable: true # load the ECharts library
version: "latest" # library version (default v6.1.0)Example ({% echarts %} tag; content is an ECharts option JSON; first arg is width, second is height):
{% echarts '81%' 400 %}
{
"title": {"text": "Sample chart"},
"xAxis": {"data": ["A", "B", "C"]},
"series": [{"data": [10, 20, 30], "type": "bar"}]
}
{% endecharts %}Effect: interactive ECharts render inside the post (echarts container marker), with hover tooltips, legend toggling etc.
13. Breathing Blink (blink)
Purpose: breathing/flashing decoration effect for page elements.
Config (theme config):
blink:
enable: true # false | trueNotes: when enabled, certain elements (e.g. hint text) get a breathing animation.
14. Online Customer Service (daovoice / tidio / tuxiaochao)
Purpose: three third-party online customer service/contact widgets — they don’t conflict and can run simultaneously.
DaoVoice (theme config):
daovoice:
enable: false
app_id: # DaoVoice app IDTidio (theme config):
tidio:
enable: false
public_key: ki6lsd8zq8isma7plzmwzuxgpnaihind # Tidio public keyTencent Tuxiaochao (theme config, see https://txc.qq.com/):
tuxiaochao:
enable: false
productId: 350806 # Tuxiaochao product IDNotes: all three are third-party services — register on the respective platform to get credentials; enable: true shows a customer-service entry in the bottom-right corner.
15. Scroll Top Arrow (scroll_top_arrow)
Purpose: a one-click back-to-top arrow button in the bottom-right corner.
Config (theme config):
scroll_top_arrow:
enable: trueNotes: this is a separate entry from the #backTop floating button in §6; this config controls the standalone top arrow, shown when enable: true.
16. Page Background (background)
Purpose: site-wide page background — image background (optionally random) or video background, plus a loading animation. This is a separate mechanism from the §4 effects page effects.
Config (theme config):
background:
enable: true # master switch: false disables both image/video backgrounds
default: off # default background when panel unset: image | video | off
# Image background (active when panel matery.bg = image)
image:
enable: true
url: "{mediaUrl}/medias_webp/sea.webp" # default background on first visit
random: true # random background: pick from light/dark libraries
lightNum: 45 # number of light random images (0-based)
lightPath: /medias_webp/featureimages/ # light library path
darkNum: 22 # number of dark random images (0-based)
darkPath: /medias_webp/featureimages/dark/ # dark library path
# Video background (active when panel matery.bg = video)
video:
enable: true
url: /video_url.json?v=1.0.0 # video list JSON (local static file)
# structure [{video: webmURL, cover: webpURL, brightness: bright|dark}]
# Loading animation (active when panel matery.loading = off|1|2|3)
loading:
enable: true
type: "off" # default type: off disabled | 1 pacman | 2 blocks | 3 circles
time: 350 # forced duration ms (1000=1s)Notes: switch hierarchy is background.enable (master) → each sub enable → panel selection; with random: true, images are picked from lightPath/darkPath libraries by light/dark theme; the video background’s brightness field is filtered by theme (cover grayscale ≥90 = bright / <90 = dark).
17. Preference Panel (right-floating)
Purpose: the gear button (#fp-toggle) in the bottom-right floating button group opens a “Preference Settings” panel, letting readers adjust reading preferences without touching code. The panel itself is always visible; the “effects” and “background” sections are shown/hidden by effects.enable / background.enable.
Feature sections:
- Font scaling:
A−/A+/Reset, step 0.1, range 0.85–1.3; works by setting CSS variable--font-scaleon<html>, root font-size =calc(--font-size-base × --font-scale)(default 16px × 1), so all rem-based sizes across the site scale proportionally, triggering a layout reflow. - Language / Trad-Simp: language dropdown (site-wide) and “Simp/Trad” segmented control on the same row; trad-simp uses
Matery.plugins.languageToggle(cookie + body conversion). - Display mode: Light / Auto / Dark, reusing
color-schema.js’sMatery_Color_Schemestorage and thedata-user-color-schemeattribute. - Page effects / Mouse effects: each offers Off / Random / specific effect (see §4 above).
- Page background / Loading animation: background off / image / video single-select; loading animation off / 1 / 2 / 3 single-select.
- All sections read/write
localStorage; preferences persist across pages.
Files involved: template themes/matery/layout/_partial/common/right-floating.ejs; font-size variables in themes/matery/source/css/_pages/_base/base.styl and color-schema.styl.
Appendix: Interaction & Visual Feature Quick Reference
| Feature | Config location | Key params | Description |
|---|---|---|---|
| Code block enhancement | theme code | shrink/break/show_full/copy_btn/language | language label + copy/expand/fullscreen |
| Image lightbox | theme post.image_zoom | enable/img_url_replace | post images auto-wrapped .img-item |
| Typewriter | theme subtitle.typed / fun_features.typing / post.typed | loop/showCursor/typeSpeed | subtitle rotation + post titles |
| Page effects | theme effects | page/mouse 9/4 items, default: off/random/id | runtime switching via floating panel |
| Trad/Simp conversion | theme preference.translate | enable | migrated here (old footer.translate removed) |
| Progress bar | theme fun_features.progressbar | height_px/color | off by default |
| Back to top | built-in (right floating panel) | no config key | #backTop enabled by default |
| Reward | theme post.reward | wechat/alipay QR images | per-post override via front-matter reward |
| Print styles | built-in CSS (print.styl) | no config key | @media print auto-applies |
| Music APlayer | theme music / musics | server/type/id/fixed | MetingJS parsing, bottom-fixed option |
| Video DPlayer | npm plugin hexo-tag-mmedia | url/pic/id/api | {% mmedia dplayer %} |
| Bilibili card | npm plugin hexo-bilibili-card-new | BV id | {% bilicard BV... %} |
| ECharts | theme built-in tag plugin | enable/version | {% echarts %} JSON config |