前言 之前去看富婆妹(ハミダシクリエイティブ) 的 HP 的动效,感觉特别好看,就特别想整一个同款,于是在一月初花了点时间研究了一下,给博客换了个新主题,顺带做了个 Dark Mode 适配,这样晚上就看的舒服多了,不过做完之后基本上都在忙论文了,这两天论文答辩完等结果哩(应该比较乐观),所以来补档一下之前要写没写的内容(话说现在写这个标题真的好嘛,已经咕了快四个月才写)
ハミダシクリエイティブ 的 HP 动效长这个样子
主题
以下大量前端代码预警,不过没有前端知识也不要紧,我对前端也就只懂一点点,写 js 的时候还是靠着以前写爬虫的知识写的,不是很难,懂了核心思想就可以给自己的博客适配同款
效果可参照本博客,右下角两个按钮能切换主题
先来说主题怎么做,观察ハミダシクリエイティブ的前端代码,不难发现动效部分是用 css 实现的,代码位于 index.css?version=20191212
中,核心代码长下面这个样子
核心思想:在 index 里面给定一个 id 为 mv 的 section ,用 css 调整这个 section 的内容即可完成动效的制作
#mv .bg { position : absolute; top : -4000px ; left : -4000px ; width : 8000px ; height : 8000px ; background : url (/hamidashi/wp/wp-content/themes/hamidashi/img/common/bg.png ) left top repeat; z-index : 1 ; -webkit-animation : infinitescroll 10s linear infinite; -moz-animation : infinitescroll 10s linear infinite; -ms-animation : infinitescroll 10s linear infinite; -o-animation : infinitescroll 10s linear infinite; animation : infinitescroll 10s linear infinite; } @keyframes infinitescroll { 0% { transform : translate3d (0 , 0 , 0 ); } 100% { transform : translate3d (376px , 376px , 0 ); } } #mv .bg { -webkit-animation : infinitescroll 20s linear infinite; -moz-animation : infinitescroll 20s linear infinite; -ms-animation : infinitescroll 20s linear infinite; -o-animation : infinitescroll 20s linear infinite; animation : infinitescroll 20s linear infinite; background-size : 1.5% ; }
知道了原理,要仿照起来就很容易了,我们也在 index 给一个带 id 的 section ,用 css 调它就行了嘛,好说,来看实现
index.html
<section id ="bgScroll" > <div id ="changeAbleBackground" class ="bg1" > </div > </section >
bg.css
实现了两套主题,用 .bg1 和 .bg2 表示,要实现多个主题,只需要修改 background: url 的内容即可,另外注意在 plumemo 的情况下需要调整 z-index: -1
来保证背景图片置于最下方
@charset "UTF-8" ;#bgScroll { position : fixed; top : 0 ; left : 0 ; width : 100% ; min-height : 100vh ; overflow : hidden; text-align : right; z-index : -99999 ; } #bgScroll .bg1 { position : absolute; top : -4000px ; left : -4000px ; width : 8000px ; height : 8000px ; background : url (https://wdv2.cocoa.xin/api/v3/file/get/19729/hamidashi_bg.png?sign=JGTXN2brek0S9_vGAhCO4_6e2a09RMNTLA8y1p7bhkg%3D%3A0 ) left top repeat; z-index : -1 ; -webkit-animation : infinitescroll 10s linear infinite; -moz-animation : infinitescroll 10s linear infinite; -ms-animation : infinitescroll 10s linear infinite; -o-animation : infinitescroll 10s linear infinite; animation : infinitescroll 10s linear infinite; } #bgScroll .bg2 { position : absolute; top : -4000px ; left : -4000px ; width : 8000px ; height : 8000px ; background : url (https://wdv2.cocoa.xin/api/v3/file/get/15117/sakura.png?sign=L4UAr7oDiOlMqkYxSAgoxtCojgBUOY5jzlcbngpepoQ%3D%3A0 ) left top repeat; z-index : -1 ; -webkit-animation : infinitescroll 10s linear infinite; -moz-animation : infinitescroll 10s linear infinite; -ms-animation : infinitescroll 10s linear infinite; -o-animation : infinitescroll 10s linear infinite; animation : infinitescroll 10s linear infinite; } @keyframes infinitescroll { 0% { transform : translate3d (0 , 0 , 0 ); } 100% { transform : translate3d (376px , 376px , 0 ); } } @media (max-width : 1200px ) { @media (max-width : 750px ) { #bgScroll .bg1 { -webkit-animation : infinitescroll 20s linear infinite; -moz-animation : infinitescroll 20s linear infinite; -ms-animation : infinitescroll 20s linear infinite; -o-animation : infinitescroll 20s linear infinite; animation : infinitescroll 20s linear infinite; background-size : 1.5% ; }} #bgScroll .bg2 { -webkit-animation : infinitescroll 20s linear infinite; -moz-animation : infinitescroll 20s linear infinite; -ms-animation : infinitescroll 20s linear infinite; -o-animation : infinitescroll 20s linear infinite; animation : infinitescroll 20s linear infinite; background-size : 5% ; }}
做了多个主题,肯定需要做主题的切换,这个问题咱们等到下面 Dark Mode 部分讲完之后一起来讲
Dark Mode! 为了解决晚上看白色画面刺眼的问题,很早就想做 Dark Mode 了,既然主题做了,何不顺带把 Dark Mode 一起做了呢,仍然用 css 来做,非常简单,直接来看实现
index.html
最顶上加个 theme ,我们用这个来判断展示什么模式的主题,顾名思义,白天就是 day-mode
,晚上就是 dark-mode
<html lang ="zh-CN" theme ="day-mode" >
changeTheme.css
根据给定的 theme 切换模式
changeTheme.css
这里主要是在 theme="dark-mode"
的时候反转颜色,记得图片要在反色一次,live2d 也是,不然就显得很阴间了2333
html [theme="dark-mode" ] { filter : invert (1 ) hue-rotate (180deg ); } html [theme="dark-mode" ] img { filter : invert (1 ) hue-rotate (180deg ); } html [theme="dark-mode" ] .gWvPxa .blog-item .post-thumb a { filter : invert (1 ) hue-rotate (180deg ); } html [theme="dark-mode" ] canvas #live2d { filter : invert (1 ) hue-rotate (180deg ) !important ; } html [theme="dark-mode" ] .gJkinm { filter : invert (1 ) hue-rotate (180deg ) !important ; } html [theme="dark-mode" ] .player .Video { filter : invert (1 ) hue-rotate (180deg ) !important ; } html { transition : color 300ms , background-color 300ms ; }
主题切换 那么我们现在实现了两套主题,白天模式和 Dark Mode,加起来就是四种组合,怎样才能做到主题切换并且记住用户的选择呢?也不难,我们用 JavaScript 实现即可,核心思想是用 js 修改 html 里面的内容(主题 -> class bg1/bg2;DarkMode -> html theme),并且借助用户浏览器的存储,把用户的选择存储到用户电脑的硬盘里面,加载页面的时候进行切换即可,还是来看实现
index.html
调用 changeThemeButton()
方法切换主题并存储,这里放上两张图片做按钮
调用 readUserThemeSettingAndApply()
方法应用用户设定
<div id ="darkModeButton" > <div id ="RikuhachimaAru" onclick ="changeThemeButton()" style ="position: fixed; opacity: 1; right: 100px; bottom: -7px;cursor:pointer; z-index: 99999" > <img style ="width:160px; height:160px" src ="https://wdv2.cocoa.xin/api/v3/file/get/19730/darkmode.png?sign=IOIpjI0O7No_FLwsWyFsWvERgoL6Eg7O00CRKICLpWw%3D%3A0" > </div > </div > <div onclick ="changeBackgroundButton()" style ="position: fixed; opacity: 1; right: 0px; bottom: -7px;cursor:pointer; z-index: 99999" > <img style ="width:150px; height:150px" src ="https://wdv2.cocoa.xin/api/v3/file/get/19760/changeTheme.png?sign=mOvI4XF5_EmEXRKWAPW_o0FEblTktJndxQsK9NoLDTY%3D%3A0" > </div > <script type ="text/javascript" > readUserThemeSettingAndApply()</script >
changeTheme.js
切换主题,存储用户设定
var darkModeStatus = 0 ; var blogTheme = 1 function readUserThemeSettingAndApply ( ){ console .log ('Reading User Settings……' ) if (localStorage .getItem ('darkModeStatus' )) { if (Number (darkModeStatus) != Number (localStorage .getItem ('darkModeStatus' ))){ darkModeStatus = Number (localStorage .getItem ('darkModeStatus' )) console .log ('ChangeThemeFromClientHistory:' ,darkModeStatus) changeThemeFunc (darkModeStatus) } } if (localStorage .getItem ('blogTheme' )) { if (blogTheme != Number (localStorage .getItem ('blogTheme' ))){ blogTheme = Number (localStorage .getItem ('blogTheme' )) console .log ('ChangeBackgroundFromClientHistory:' ,blogTheme) changeBackgroundFunc (blogTheme) } } } function changeThemeButton ( ){ if (darkModeStatus==1 ){ darkModeStatus = 0 localStorage .setItem ('darkModeStatus' , darkModeStatus) }else { darkModeStatus = 1 localStorage .setItem ('darkModeStatus' , darkModeStatus) } changeThemeFunc (darkModeStatus) } function changeThemeFunc (darkModeStatus ) { if (darkModeStatus==1 ){ $("html" ).attr ("theme" ,"dark-mode" ); $("#RikuhachimaAru" ).remove () $("#darkModeButton" ).append ('<div id="AjitaniHifumi" onclick="changeThemeButton()" style="position: fixed; opacity: 1; right: 140px; bottom: -7px;cursor:pointer; z-index: 99999"><img style="width:160px; height:160px" src="https://wdv2.cocoa.xin/api/v3/file/get/19732/daymode.png?sign=MD-gBvM3uBwHELd3bi1bEeGdCl3R4bEd74fXe9kIktU%3D%3A0"> </div>' ); console .log ('黑暗模式:ON' ); }else { $("html" ).attr ("theme" ,"day-mode" ); $("#AjitaniHifumi" ).remove () $("#darkModeButton" ).append ('<div id="RikuhachimaAru" onclick="changeThemeButton()" style="position: fixed; opacity: 1; right: 100px; bottom: -7px;cursor:pointer; z-index: 99999"><img style="width:160px; height:160px" src="https://wdv2.cocoa.xin/api/v3/file/get/19730/darkmode.png?sign=IOIpjI0O7No_FLwsWyFsWvERgoL6Eg7O00CRKICLpWw%3D%3A0"> </div>' ); console .log ('黑暗模式:OFF' ); } } function changeBackgroundButton ( ){ switch (blogTheme){ case 2 : blogTheme = 1 localStorage .setItem ('blogTheme' , blogTheme) break ; default : blogTheme = blogTheme + 1 localStorage .setItem ('blogTheme' , blogTheme) break ; } changeBackgroundFunc (blogTheme) } function changeBackgroundFunc (blogTheme ){ switch (blogTheme){ case 1 : $("#changeAbleBackground" ).remove () $("#bgScroll" ).append ('<div id="changeAbleBackground" class="bg1"></div>' ); console .log ('当前主题:theme-react-hamidashi' ) break ; case 2 : $("#changeAbleBackground" ).remove () $("#bgScroll" ).append ('<div id="changeAbleBackground" class="bg2"></div>' ); console .log ('当前主题:theme-react-sakura' ) break ; } }
来整同款? 阅读以下文件,更换图片链接,即可快速给自己博客上同款~
index.html
bg.css
changeTheme.css
changeTheme.js