├── .github ├── FUNDING.yml └── workflows │ ├── docs-site-deploy.yml │ ├── node.js.yml │ └── npm-publish.yml ├── .gitignore ├── LICENSE ├── README.md ├── config ├── webpack.base.js ├── webpack.dev.js └── webpack.prod.js ├── dist ├── script │ ├── 508.cb5a76ce.js │ ├── 508.cb5a76ce.js.gz │ ├── background-particles.ec8cfbb7.js │ ├── background-ribbons.817d7cf1.js │ ├── background-season.5098f6ee.js │ ├── banner-images.58aa73ec.js │ ├── circle-magic.fbc978f0.js │ ├── com-after.d53abf1c.js │ ├── com-after.d53abf1c.js.gz │ ├── com-before.b5ccc189.js │ ├── com-before.b5ccc189.js.gz │ ├── day-night.da3c8326.js │ ├── gf-blink.466da4a4.js │ ├── google-fonts.93449ae7.js │ ├── iconfont.6bd2454d.js │ ├── mouse-bubble.8aec228a.js │ ├── mouse-click.e293f3fa.js │ ├── mouse-cursor.8baada8c.js │ ├── mouse-mo.b54f5304.js │ ├── mouse-mouse.94fa54d3.js │ ├── nh-banner-animation.1a1c6c54.js │ ├── page-article.d0172325.js │ ├── page-books.02a08fea.js │ ├── page-home.0a8a4a9c.js │ └── page-links.094c85e4.js ├── simple-memory.css ├── simple-memory.js ├── simple-memory.js.gz └── style │ ├── background-particles.457e1a14.css │ ├── com-before.623dd38a.css │ ├── com-before.623dd38a.css.gz │ ├── day-night.0a3de6b0.css │ ├── gf-blink.0cc7f6e2.css │ ├── gf-blink.0cc7f6e2.css.gz │ ├── google-fonts.66c39700.css │ ├── google-fonts.66c39700.css.gz │ ├── iconfont.cfd96386.css │ ├── mouse-mouse.5e68e4e5.css │ ├── nh-banner-animation.7ff7a955.css │ ├── page-article.de68d80d.css │ ├── page-article.de68d80d.css.gz │ ├── page-books.d2212f9a.css │ ├── page-books.d2212f9a.css.gz │ ├── page-common-com-article.de68d80d.css │ ├── page-common-com-article.de68d80d.css.gz │ ├── page-links.cb8ec4a1.css │ └── page-links.cb8ec4a1.css.gz ├── docs └── v2 │ ├── .vitepress │ ├── cache │ │ └── deps │ │ │ ├── _metadata.json │ │ │ ├── chunk-TQVJM66I.js │ │ │ ├── chunk-TQVJM66I.js.map │ │ │ ├── chunk-YZ3AHZKA.js │ │ │ ├── chunk-YZ3AHZKA.js.map │ │ │ ├── package.json │ │ │ ├── vitepress___@vue_devtools-api.js │ │ │ ├── vitepress___@vue_devtools-api.js.map │ │ │ ├── vitepress___@vueuse_core.js │ │ │ ├── vitepress___@vueuse_core.js.map │ │ │ ├── vitepress___@vueuse_integrations_useFocusTrap.js │ │ │ ├── vitepress___@vueuse_integrations_useFocusTrap.js.map │ │ │ ├── vitepress___mark__js_src_vanilla__js.js │ │ │ ├── vitepress___mark__js_src_vanilla__js.js.map │ │ │ ├── vitepress___minisearch.js │ │ │ ├── vitepress___minisearch.js.map │ │ │ ├── vue.js │ │ │ └── vue.js.map │ ├── config.mjs │ ├── locales │ │ └── zh.config.js │ └── theme │ │ ├── index.js │ │ └── style.css │ └── src │ ├── changelog │ └── index.md │ ├── guide │ ├── articleDirectory.md │ ├── codespaces.md │ ├── install.md │ ├── menuData.md │ ├── my.md │ ├── resourceCdn.md │ ├── versionSwitch.md │ └── writtenForm.md │ ├── index.md │ └── reference │ ├── bookList.md │ ├── configs.md │ ├── fonticon.md │ ├── hook.md │ ├── links.md │ ├── loading.md │ └── reprinted.md ├── package-lock.json ├── package.json ├── pnpm-lock.yaml ├── postcss.config.js └── src ├── components ├── articleDirectory │ └── articleDirectory.js ├── articleInfo │ └── articleInfo.js ├── articleSuffix │ └── articleSuffix.js ├── background │ ├── particles.js │ ├── ribbons.js │ └── season.js ├── banner │ └── banner.js ├── bannerImages │ └── bannerImages.js ├── blogIcon │ └── blogIcon.js ├── comment │ ├── comment.js │ └── commentTyping │ │ ├── commentTyping.js │ │ └── textareaCaretPosition.js ├── common │ ├── comAfter.js │ └── comBefore.js ├── config │ └── config.json5 ├── console │ └── console.js ├── dayNight │ └── dayNight.js ├── event │ └── event.js ├── footer │ └── footer.js ├── greenChannel │ └── greenChannel.js ├── imgBox │ └── imgBox.js ├── loading │ └── loading.js ├── mouse │ ├── bubble.js │ ├── click.js │ ├── cursor.js │ ├── mo.js │ └── mouse.js ├── progress │ └── progress.js ├── rtMenu │ └── rtMenu.js ├── sidebar │ ├── lib │ │ ├── classie.js │ │ └── main4.js │ └── sidebar.js ├── status │ └── status.js └── title │ └── title.js ├── main.js ├── page ├── article.js ├── books.js ├── common │ └── com-article.js ├── home.js └── links.js ├── style ├── articleDirectory.css ├── articleSuffix.css ├── base.dark.css ├── books.css ├── customBtn.css ├── gf-blink.css ├── google-fonts.css ├── iconfont.css ├── links.css ├── menu_bubble.css ├── mouse.css ├── nhBannerAnimation.css ├── particles.css └── simple-memory.css ├── template ├── articleDirectory.html ├── articleSuffix.html ├── banner.html ├── books.html ├── dayNight.html ├── footer.html ├── links.html ├── particles.html ├── rtMenu.html ├── sidebar.html └── sidebarNav.html ├── utils ├── request.js └── tools.js └── vendor ├── circleMagic └── circleMagic.js ├── consoleText └── consoleText.js └── loading └── loading.js /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: #目前不支持中国 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | #custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | 14 | custom: https://images.cnblogs.com/cnblogs_com/wangyang0210/1943283/o_210308061740wechat.png 15 | -------------------------------------------------------------------------------- /.github/workflows/docs-site-deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy VitePress Site 2 | on: 3 | push: 4 | branches: 5 | - v2 6 | jobs: 7 | build-and-deploy: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Checkout code 11 | uses: actions/checkout@v3 12 | - name: Setup Node.js 13 | uses: actions/setup-node@v3 14 | with: 15 | node-version: '20' 16 | - name: Install dependencies 17 | run: npm install 18 | - name: Build VitePress site 19 | run: npm run docs:build 20 | - name: Deploy to GitHub Pages 21 | uses: peaceiris/actions-gh-pages@v3 22 | with: 23 | github_token: ${{ secrets.GITHUB_TOKEN }} 24 | publish_dir: docs/v2/.vitepress/dist -------------------------------------------------------------------------------- /.github/workflows/node.js.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: cnblogs-theme-npm 5 | 6 | on: 7 | push: 8 | branches: [ "v2" ] 9 | pull_request: 10 | branches: [ "v2" ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | strategy: 18 | matrix: 19 | node-version: [16.x] 20 | # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ 21 | 22 | steps: 23 | - uses: actions/checkout@v3 24 | - name: Use Node.js ${{ matrix.node-version }} 25 | uses: actions/setup-node@v3 26 | with: 27 | node-version: ${{ matrix.node-version }} 28 | cache: 'npm' 29 | - run: npm ci 30 | - run: npm run build 31 | -------------------------------------------------------------------------------- /.github/workflows/npm-publish.yml: -------------------------------------------------------------------------------- 1 | # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages 3 | 4 | name: NPM-PUBLISH 5 | 6 | on: 7 | release: 8 | types: [created] 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v3 15 | - uses: actions/setup-node@v3 16 | with: 17 | node-version: 16 18 | - run: npm ci 19 | - run: npm run build 20 | 21 | publish-npm: 22 | needs: build 23 | runs-on: ubuntu-latest 24 | steps: 25 | - uses: actions/checkout@v3 26 | - uses: actions/setup-node@v3 27 | with: 28 | node-version: 16 29 | registry-url: https://registry.npmjs.org/ 30 | - run: npm ci 31 | - run: npm publish 32 | env: 33 | NODE_AUTH_TOKEN: ${{secrets.NPM_PUBLISH}} 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.iws 3 | *.iml 4 | *.ipr 5 | .DS_Store 6 | node_modules 7 | .vscode 8 | stats.json 9 | public 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ISC License (ISC) 2 | Copyright <2022> 3 | 4 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. 5 | 6 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 |
6 | 7 |
8 | 9 | [![GitHub release](https://img.shields.io/github/v/release/wangyang0210/cnblogs-theme.svg)](https://github.com/wangyang0210/cnblogs-theme/releases) 10 | [![GitHub stars](https://img.shields.io/github/stars/wangyang0210/cnblogs-theme.svg)](https://github.com/wangyang0210/cnblogs-theme/stargazers) 11 | [![GitHub forks](https://img.shields.io/github/forks/wangyang0210/cnblogs-theme.svg)](https://github.com/wangyang0210/cnblogs-theme/network) 12 | [![GitHub issues](https://img.shields.io/github/issues/wangyang0210/cnblogs-theme.svg)](https://github.com/wangyang0210/cnblogs-theme/issues) 13 | [![GitHub contributors](https://img.shields.io/github/contributors/wangyang0210/cnblogs-theme.svg)](https://github.com/wangyang0210/cnblogs-theme/graphs/contributors) 14 | [![](https://data.jsdelivr.com/v1/package/gh/wangyang0210/cnblogs-theme/badge?style=rounded)](https://www.jsdelivr.com/package/gh/wangyang0210/cnblogs-theme) 15 | [![GitHub last commit](https://img.shields.io/github/last-commit/wangyang0210/cnblogs-theme.svg)](https://github.com/wangyang0210/cnblogs-theme/commits/v2) 16 | [![GitHub license](https://img.shields.io/badge/license-ISC-brightgreen)](https://github.com/wangyang0210/cnblogs-theme/blob/v2/LICENSE) 17 | [![compatibility](https://camo.githubusercontent.com/31ac3f0ce805dc34a29b615131caa26cbf4dc127/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f62726f777365722d2532306368726f6d6525323025374325323066697265666f782532302537432532306f706572612532302537432532307361666172692532302537432532306965253230253345253344253230392d6c69676874677265792e737667)](https://github.com/wangyang0210/cnblogs-theme) 18 | [![Deploy VitePress Site](https://github.com/wangyang0210/cnblogs-theme/actions/workflows/docs-site-deploy.yml/badge.svg?branch=v2)](https://github.com/wangyang0210/cnblogs-theme/actions/workflows/docs-site-deploy.yml) 19 | 20 | # Silence 21 | 22 | 📖 本主题以阅读为核心,美化博客园的显示效果,提高用户体验。 23 | 24 | 🍰 基于博皮“SimpleMemory”进行的修改;[页面效果](https://www.cnblogs.com/wangyang0210/) 25 | 26 | 🧀 支持响应,尺寸分别为:(1200px,∞px),(960px,1200px],(720px,960px],(0px,720px] 27 | 28 | # Docs 29 | 30 | [永久地址](https://wangyang0210.github.io/cnblogs-theme/) 31 | 32 | > 推荐大家使用最新版本,新版本的发布往往代表着功能的完善和bug的修复! 33 | >
文档的源文件在 /docs 目录,大家有更完善的文档或建议可以 Pull Request 或 Issues 给我。 34 | >
文档我已经禁止浏览器缓存,但仍可能存在缓存,大家可以尝试强制刷新下(ctrl+f5 / command+shift+r) 35 | > 目前主要维护开发的是2.0版本,所以文档完善也是针对于2.x.x版本,请理解; 36 | 37 | # Author 38 | 39 | **Cnblogs-Theme** © [wangyang0210](https://github.com/wangyang0210), Released under the [ISC](./LICENSE) License.
40 | 41 | > Blog [@Blog](https://www.cnblogs.com/wangyang0210/) · GitHub [@GitHub](https://github.com/wangyang0210) · Email i@oyo.cool 42 | 43 | > **Cnblogs-Theme** from **Cnblogs-Theme-SimpleMemory** © [BNDong](https://github.com/BNDong) 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /config/webpack.base.js: -------------------------------------------------------------------------------- 1 | const json5 = require('json5') 2 | const miniCssExtractPlugin = require('mini-css-extract-plugin') 3 | 4 | 5 | module.exports = { 6 | entry: './src/main.js', 7 | output: { 8 | filename: 'simple-memory.js', 9 | chunkFilename:'script/[name].[contenthash:8].js', 10 | clean: true 11 | }, 12 | experiments: { 13 | topLevelAwait: true, 14 | }, 15 | // externals: { 16 | // moment: 'moment', 17 | // }, 18 | plugins: [ 19 | new miniCssExtractPlugin({ 20 | filename: 'style/[name].[contenthash:8].css', 21 | chunkFilename:'style/[name].[contenthash:8].css', 22 | ignoreOrder: true 23 | }), 24 | ], 25 | module: { 26 | rules: [ 27 | { 28 | test: /\.css$/i, 29 | use: [ 30 | { 31 | loader: miniCssExtractPlugin.loader, 32 | options: { 33 | publicPath: '../' 34 | } 35 | }, 36 | 'css-loader' 37 | ], 38 | }, 39 | { 40 | test: /\.(png|svg|jpg|jpeg|gif|webp)$/i, 41 | type: 'asset/resource', 42 | generator: { 43 | filename: 'images/[contenthash][ext][query]' 44 | } 45 | }, 46 | { 47 | test: /\.(eot|ttf|woff|woff2)$/, 48 | type: 'asset/resource', 49 | generator: { 50 | filename: 'iconfont/[contenthash][ext][query]' 51 | } 52 | }, 53 | { 54 | test: /\.json5$/i, 55 | type: 'json', 56 | parser: { 57 | parse: json5.parse, 58 | }, 59 | }, 60 | { 61 | test: /\.html$/i, 62 | loader: 'html-loader', 63 | options: { 64 | minimize: true, 65 | }, 66 | }, 67 | ], 68 | }, 69 | }; 70 | -------------------------------------------------------------------------------- /config/webpack.dev.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; 3 | const webpackMerge = require('webpack-merge'); 4 | const webpackBaseConfig = require('./webpack.base.js'); 5 | 6 | let webpackDevelopmentConfig = { 7 | mode: 'development', 8 | output: { 9 | path: path.resolve(__dirname, '../public'), 10 | }, 11 | plugins: [new BundleAnalyzerPlugin()], 12 | devtool: 'source-map', 13 | devServer: { 14 | static: { 15 | directory: path.join(__dirname, '../public'), 16 | }, 17 | compress: true, 18 | port: 9000, 19 | }, 20 | }; 21 | 22 | module.exports = webpackMerge.merge(webpackBaseConfig, webpackDevelopmentConfig); 23 | -------------------------------------------------------------------------------- /config/webpack.prod.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpackMerge = require('webpack-merge'); 3 | const webpackBaseConfig = require('./webpack.base.js'); 4 | const terserPlugin = require('terser-webpack-plugin'); 5 | const cssMinimizerPlugin = require('css-minimizer-webpack-plugin'); 6 | const CompressionPlugin = require('compression-webpack-plugin'); 7 | 8 | let webpackProdConfig = { 9 | mode: 'production', 10 | entry: './src/main.js', 11 | output: { 12 | filename: 'simple-memory.js', 13 | chunkFilename: 'script/[name].[contenthash:8].js', 14 | path: path.resolve(__dirname, '../dist'), 15 | clean: true, 16 | }, 17 | devtool: false, 18 | optimization: { 19 | minimize: true, 20 | minimizer: [ 21 | new terserPlugin({ 22 | parallel: true, 23 | extractComments: false, 24 | }), 25 | new cssMinimizerPlugin({ 26 | minimizerOptions: { 27 | preset: [ 28 | 'default', 29 | { 30 | discardComments: { removeAll: true }, 31 | }, 32 | ], 33 | }, 34 | parallel: true, 35 | }), 36 | new CompressionPlugin({ 37 | algorithm: 'gzip', 38 | test: /\.js$|\.html$|\.css$/, 39 | minRatio: 1, 40 | threshold: 10240, 41 | deleteOriginalAssets: false, 42 | }), 43 | ], 44 | }, 45 | }; 46 | 47 | module.exports = webpackMerge.merge(webpackBaseConfig, webpackProdConfig); 48 | -------------------------------------------------------------------------------- /dist/script/508.cb5a76ce.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangyang0210/cnblogs-theme/c555b87781d2264dce6c6d8b712d0010a7ea6517/dist/script/508.cb5a76ce.js.gz -------------------------------------------------------------------------------- /dist/script/background-particles.ec8cfbb7.js: -------------------------------------------------------------------------------- 1 | "use strict";(self.webpackChunkcnblogs_theme=self.webpackChunkcnblogs_theme||[]).push([[673],{953:function(e,a){a.A='
'},525:function(e,a,t){t.a(e,(async function(e,c){try{t.r(a),t.d(a,{default:function(){return l}});var i=t(953);function l(e){$("#footer").after(i.A);let a=document.getElementById("particles"),t=[{el:a.querySelector(".particles-layer--1"),opacity:.07,speed:.06},{el:a.querySelector(".particles-layer--2"),opacity:.07,speed:.04},{el:a.querySelector(".particles-layer--3"),opacity:.07,speed:.05}];t.forEach((e=>{gsap.to(e.el,.6,{delay:Math.random(),opacity:e.opacity})})),document.addEventListener("mousemove",(function(e){let a={x:window.innerWidth/2,y:window.innerHeight/2},c={x:e.clientX||e.pageX,y:e.clientY||e.pageY},i={x:a.x-c.x,y:a.y-c.y};t.forEach((e=>{gsap.to(e.el,1,{x:i.x*e.speed,y:i.y*e.speed})}))}))}await $.__tools.dynamicLoadingJs($.__config.default.gsap).catch((e=>console.error("gsap.js",e))),c()}catch(r){c(r)}}),1)}}]); -------------------------------------------------------------------------------- /dist/script/background-ribbons.817d7cf1.js: -------------------------------------------------------------------------------- 1 | "use strict";(self.webpackChunkcnblogs_theme=self.webpackChunkcnblogs_theme||[]).push([[667],{119:function(t,i,s){s.r(i),s.d(i,{default:function(){return h}});class o{constructor(t,i){this.x=0,this.y=0,this.set(t,i)}set(t,i){this.x=t||0,this.y=i||0}copy(t){return this.x=t.x||0,this.y=t.y||0,this}add(t,i){return this.x+=t||0,this.y+=i||0,this}subtract(t,i){return this.x-=t||0,this.y-=i||0,this}flipY(){return this.y*=-1,this}}class n{_w=window;_b=document.body;_d=document.documentElement;constructor(t){this._canvas=null,this._context=null,this._width=0,this._height=0,this._scroll=0,this._ribbons=[],this._options={colorSaturation:t.colorSaturation||"80%",colorBrightness:t.colorBrightness||"60%",colorAlpha:t.colorAlpha||.65,colorCycleSpeed:t.colorCycleSpeed||6,verticalPosition:t.verticalPosition||"center",horizontalSpeed:t.horizontalSpeed||150,ribbonCount:t.ribbonCount||3,strokeSize:t.strokeSize||0,parallaxAmount:t.parallaxAmount||-.5,animateSections:t.animateSections||!0},this._onDraw=this._onDraw.bind(this),this._onResize=this._onResize.bind(this),this._onScroll=this._onScroll.bind(this),this.init()}random(){if(1===arguments.length){if(Array.isArray(arguments[0])){let t=Math.round(this.random(0,arguments[0].length-1));return arguments[0][t]}return this.random(0,arguments[0])}return 2===arguments.length?Math.random()*(arguments[1]-arguments[0])+arguments[0]:0}screenInfo(t){let i=Math.max(0,this._w.innerWidth||this._d.clientWidth||this._b.clientWidth||0),s=Math.max(0,this._w.innerHeight||this._d.clientHeight||this._b.clientHeight||0);return{width:i,height:s,ratio:i/s,centerx:i/2,centery:s/2,scrollx:Math.max(0,this._w.pageXOffset||this._d.scrollLeft||this._b.scrollLeft||0)-(this._d.clientLeft||0),scrolly:Math.max(0,this._w.pageYOffset||this._d.scrollTop||this._b.scrollTop||0)-(this._d.clientTop||0)}}init(){try{this._canvas=document.createElement("canvas"),this._canvas.style.display="block",this._canvas.style.position="fixed",this._canvas.style.margin="0",this._canvas.style.padding="0",this._canvas.style.border="0",this._canvas.style.outline="0",this._canvas.style.left="0",this._canvas.style.top="0",this._canvas.style.width="100%",this._canvas.style.height="100%",this._canvas.style["z-index"]="-1",this._canvas.id="bgCanvas",this._onResize(),this._context=this._canvas.getContext("2d"),this._context.clearRect(0,0,this._width,this._height),this._context.globalAlpha=this._options.colorAlpha,window.addEventListener("resize",this._onResize),window.addEventListener("scroll",this._onScroll),document.body.appendChild(this._canvas)}catch(t){return}this._onDraw()}addRibbon(){let t=Math.round(this.random(1,9))>5?"right":"left",i=1e3,s=200,n=this._width+s,h=0,e=0,a="right"===t?-200:n,l=Math.round(this.random(0,this._height));/^(top|min)$/i.test(this._options.verticalPosition)&&(l=200),/^(middle|center)$/i.test(this._options.verticalPosition)&&(l=this._height/2),/^(bottom|max)$/i.test(this._options.verticalPosition)&&(l=this._height-s);let r=[],c=new o(a,l),_=new o(a,l),d=null,p=Math.round(this.random(0,360)),b=0;for(;!(i<=0||(i--,h=Math.round((1*Math.random()-.2)*this._options.horizontalSpeed),e=Math.round((1*Math.random()-.5)*(.25*this._height)),d=new o,d.copy(_),"right"===t&&(d.add(h,e),_.x>=n))||"left"===t&&(d.subtract(h,e),_.x<=-200));)r.push({point1:new o(c.x,c.y),point2:new o(_.x,_.y),point3:d,color:p,delay:b,dir:t,alpha:0,phase:0}),c.copy(_),_.copy(d),b+=4,p+=this._options.colorCycleSpeed;this._ribbons.push(r)}_drawRibbonSection(t){if(t){if(t.phase>=1&&t.alpha<=0)return!0;if(t.delay<=0){if(t.phase+=.02,t.alpha=1*Math.sin(t.phase),t.alpha=t.alpha<=0?0:t.alpha,t.alpha=t.alpha>=1?1:t.alpha,this._options.animateSections){let i=.1*Math.sin(1+t.phase*Math.PI/2);"right"===t.dir?(t.point1.add(i,0),t.point2.add(i,0),t.point3.add(i,0)):(t.point1.subtract(i,0),t.point2.subtract(i,0),t.point3.subtract(i,0)),t.point1.add(0,i),t.point2.add(0,i),t.point3.add(0,i)}}else t.delay-=.5;let i=this._options.colorSaturation,s=this._options.colorBrightness,o="hsla("+t.color+", "+i+", "+s+", "+t.alpha+" )";this._context.save(),0!==this._options.parallaxAmount&&this._context.translate(0,this._scroll*this._options.parallaxAmount),this._context.beginPath(),this._context.moveTo(t.point1.x,t.point1.y),this._context.lineTo(t.point2.x,t.point2.y),this._context.lineTo(t.point3.x,t.point3.y),this._context.fillStyle=o,this._context.fill(),this._options.strokeSize>0&&(this._context.lineWidth=this._options.strokeSize,this._context.strokeStyle=o,this._context.lineCap="round",this._context.stroke()),this._context.restore()}return!1}_onDraw(){for(let t=0,i=this._ribbons.length;t=s&&(this._ribbons[t]=null)}this._ribbons.lengthwindow.innerWidth||this.x<0||this.y>window.innerHeight||this.y<0)&&(this.r=r("fnr"),Math.random()>.4?(this.x=r("x"),this.y=0,this.s=r("s"),this.r=r("r")):(this.x=window.innerWidth,this.y=r("y"),this.s=r("s"),this.r=r("r")))},n=function(){this.list=[]},n.prototype.push=function(t){this.list.push(t)},n.prototype.update=function(){for(let t=0,n=this.list.length;t{(new Image).src=e}));for(let e=0;e{const s=document.createElement("div");s.className="section";const r=document.createElement("img");r.src=t[a],s.appendChild(r),(o-Math.max(0,e))%2==0?function(e,t,n){e.appendChild(t),gsap.to(e,{...i,y:-n}).then((()=>{e.children[0].remove(),gsap.to(e,{duration:0,y:0}),d=!1}))}(c,s,n):function(e,t,n){e.prepend(t),gsap.to(e,{duration:0,y:-n}),gsap.to(e,{...i,y:0}).then((()=>{e.children[1].remove(),d=!1}))}(c,s,n)}))}setInterval((()=>l(o)),c)}n.r(t),n.d(t,{default:function(){return o}}),await $.__tools.dynamicLoadingJs($.__config.default.gsap).catch((e=>console.error("gsap.js",e))),c()}catch(a){c(a)}}),1)}}]); -------------------------------------------------------------------------------- /dist/script/circle-magic.fbc978f0.js: -------------------------------------------------------------------------------- 1 | (self.webpackChunkcnblogs_theme=self.webpackChunkcnblogs_theme||[]).push([[261],{20:function(){var e;(e=jQuery).fn.circleMagic=function(t){let o,n,a,l,i=!0,r=[],s=e.extend({color:"rgba(255,255,255,.5)",radius:10,density:.3,clearOffset:.2},t),h=this[0];function c(){i=!(document.body.scrollTop>n)}function d(){o=h.clientWidth,n=h.clientHeight,h.height=n+"px",a.width=o,a.height=n}function f(){if(i){l.clearRect(0,0,o,n);for(let e in r)r[e].draw()}requestAnimationFrame(f)}function m(){let e=this;function t(){e.pos.x=Math.random()*o,e.pos.y=n+100*Math.random(),e.alpha=.1+Math.random()*s.clearOffset,e.scale=.1+.3*Math.random(),e.speed=Math.random(),"random"===s.color?e.color="rgba("+Math.floor(255*Math.random())+", "+Math.floor(255*Math.random())+", "+Math.floor(255*Math.random())+", "+Math.random().toPrecision(2)+")":e.color=s.color}e.pos={},t(),this.draw=function(){e.alpha<=0&&t(),e.pos.y-=e.speed,e.alpha-=5e-4,l.beginPath(),l.arc(e.pos.x,e.pos.y,e.scale*s.radius,0,2*Math.PI,!1),l.fillStyle=e.color,l.fill(),l.closePath()}}!function(){o=h.offsetWidth,n=h.offsetHeight,function(){let e=document.createElement("canvas");e.id="homeTopCanvas",h.appendChild(e),e.parentElement.style.overflow="hidden"}(),a=document.getElementById("homeTopCanvas"),a.width=o,a.height=n,a.style.position="absolute",a.style.left="0",a.style.bottom="0",a.style.zIndex="1",l=a.getContext("2d");for(let e=0;e{if(t.position.x>this.area.width||t.position.y>this.area.height)return this.circles.splice(i,1);t.move()})),0==this.circles.length&&(this.stop=!0)}draw(){this.circles.forEach((t=>t.draw()))}}(new class{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=!1}handleMouseDown(t){const n=new i({origin:{x:t.clientX,y:t.clientY},context:this.computerContext,area:{width:this.globalWidth,height:this.globalHeight}});n.init(),this.booms.push(n),this.running||this.run()}handlePageHide(){this.booms=[],this.running=!1}init(){const t=this.renderCanvas.style;t.position="fixed",t.top=t.left=0,t.zIndex="999999999999999999999999999999999999999999",t.pointerEvents="none",t.width=this.renderCanvas.width=this.computerCanvas.width=this.globalWidth,t.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=!0,0!=this.booms.length?(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(((t,i)=>{if(t.stop)return this.booms.splice(i,1);t.move(),t.draw()})),this.renderContext.drawImage(this.computerCanvas,0,0,this.globalWidth,this.globalHeight)):this.running=!1}}).init()}n.r(i),n.d(i,{default:function(){return e}})}}]); -------------------------------------------------------------------------------- /dist/script/mouse-cursor.8baada8c.js: -------------------------------------------------------------------------------- 1 | "use strict";(self.webpackChunkcnblogs_theme=self.webpackChunkcnblogs_theme||[]).push([[91],{971:function(e,n,t){function u(e){document.body.style.cursor=`url(${e.url||"https://files.cnblogs.com/files/wangyang0210/normal.gif?t=1681261712"}), default`}t.r(n),t.d(n,{default:function(){return u}})}}]); -------------------------------------------------------------------------------- /dist/script/mouse-mo.b54f5304.js: -------------------------------------------------------------------------------- 1 | "use strict";(self.webpackChunkcnblogs_theme=self.webpackChunkcnblogs_theme||[]).push([[677],{53:function(e,n,t){function o(e){$.__tools.dynamicLoadingJs($.__config.default.mojs).then((()=>{const n=new mojs.Burst({left:0,top:0,...e});n.el.style.zIndex=999999,document.addEventListener("click",(function(e){n.tune({x:e.pageX,y:e.pageY}).setSpeed(3).replay()}))})).catch((e=>console.error("mo.js: ",e)))}t.r(n),t.d(n,{default:function(){return o}})}}]); -------------------------------------------------------------------------------- /dist/script/mouse-mouse.94fa54d3.js: -------------------------------------------------------------------------------- 1 | "use strict";(self.webpackChunkcnblogs_theme=self.webpackChunkcnblogs_theme||[]).push([[74],{326:function(e,t,n){n.a(e,(async function(e,o){try{function s(e){const t=document.createElement("div");t.className="cursor";const n=document.createElement("div");n.className="cursor-f";let o,s,c=0,i=0,a=0,d=0,l=e.size,u=e.sizeF;function r(e,t,n){return(1-n)*e+n*t}document.body.appendChild(t),document.body.appendChild(n),"ontouchstart"in window&&(t.style.display="none",n.style.display="none"),t.style.setProperty("--size",l+"px"),n.style.setProperty("--size",u+"px"),window.addEventListener("mousemove",(function(e){a=e.pageX,d=e.pageY,t.style.top=d-l/2+"px";let n=a-l/2,o=document.body.offsetWidth;n=n<0?0:o-l=40&&(p=!1,o=null,s=null)}window.addEventListener("mousedown",f,!1),window.addEventListener("touchstart",f,!1),window.addEventListener("touchmove",(function(e){p&&(s=e.touches[0].clientY||e.targetTouches[0].clientY)}),!1),window.addEventListener("touchend",h,!1),window.addEventListener("mouseup",h,!1)}n.r(t),n.d(t,{default:function(){return s}}),await $.__tools.dynamicLoadingJs($.__config.default.gsap).catch((e=>console.error("gsap.js",e))),o()}catch(c){o(c)}}),1)}}]); -------------------------------------------------------------------------------- /dist/script/nh-banner-animation.1a1c6c54.js: -------------------------------------------------------------------------------- 1 | "use strict";(self.webpackChunkcnblogs_theme=self.webpackChunkcnblogs_theme||[]).push([[381],{448:function(e,s,c){c.r(s)}}]); -------------------------------------------------------------------------------- /dist/script/page-article.d0172325.js: -------------------------------------------------------------------------------- 1 | "use strict";(self.webpackChunkcnblogs_theme=self.webpackChunkcnblogs_theme||[]).push([[153,551],{928:function(t,a,n){n.a(t,(async function(t,e){try{function c(){setTimeout((()=>{let t=$("#cnblogs_post_body img").length-1;if(!t)return;let a=$("#cnblogs_post_body"),n=$(`#cnblogs_post_body img:lt(${t})`),e=$(".feedbackCon img"),c=[];$.each(n,(t=>c.push(n[t]))),$.each(e,(t=>c.push(e[t]))),a.length&&c.length&&$.each(c,(t=>{let a=$(c[t]);if(!a.hasClass("code_img_closed")&&!a.hasClass("code_img_opened")){let t=a.attr("width"),n=a.attr("height"),e=a.attr("alt")??"",c=a.attr("style")??"";a.after(`\n ${e}`),a.remove()}}))}),800)}n.d(a,{A:function(){return c}}),await $.__tools.dynamicLoadingCss($.__config.default.fancyboxcss),await $.__tools.dynamicLoadingJs($.__config.default.fancybox).catch((t=>console.error("fancybox.js",t))),e()}catch(o){e(o)}}),1)},684:function(t,a,n){n.a(t,(async function(t,e){try{n.r(a),n.d(a,{default:function(){return i}});var c=n(508),o=n(928),s=t([c,o]);function i(){(0,c.default)(),(0,o.A)()}[c,o]=s.then?(await s)():s,e()}catch(l){e(l)}}))}}]); -------------------------------------------------------------------------------- /dist/script/page-books.02a08fea.js: -------------------------------------------------------------------------------- 1 | "use strict";(self.webpackChunkcnblogs_theme=self.webpackChunkcnblogs_theme||[]).push([[111,153],{840:function(e,t){t.A='
##name##
##scoreHtml##
##infoHtml##
##readDate## ##readPercentage##
'},736:function(e,t,a){a.a(e,(async function(e,o){try{a.r(t),a.d(t,{default:function(){return r}});var n=a(840),i=a(650),c=a(508),s=e([i,c]);function r(){if((0,c.default)(),$.__config.bookList.length){a.e(489).then(a.bind(a,482));let e=$("#cnblogs_post_body"),t="";const o={formerName:"原 名:",author:"作 者:",translator:"译 者:",press:"出版社:",year:"出版年:",direct:"导 演: ",scenarist:"编 剧: ",star:"主 演: ",type:"类 型: ",productionCountry:"制片国家/地区: ",language:"语 言: ",releaseDate:"上映日期: ",filmLength:"片 长: ",alias:"别 名: "};$.__config.bookList.forEach((e=>{e.title&&(t+=`

${e.title}

`),t+='
',e.books.forEach((e=>{let a=n.A,i="",c="";if(e?.score>0){const t=Math.floor(e.score),a=e.score>t?'':"",o=''.repeat(5-t);i=''.repeat(t)+a+o}else i=''.repeat(5);Object.entries(o).forEach((([t,a])=>{e?.[t]&&(c+=`${a} ${e?.[t]}
`)})),a=$.__tools.batchTempReplacement(a,[["cover",e.cover||""],["name",e.name||""],["readDate",e?.readDate||""],["readDateStyle",e?.readDate?"initial;":"none"],["readPercentage",e?.readPercentage||""],["readPercentageStyle",e?.readPercentage?"initial;":"none"],["scoreHtml",i],["infoHtml",c]]),t+=a})),t+="
"}));let i=$(".articleSuffix-flg");i.length?i.before(t):e.append(t)}(0,i.A)()}[i,c]=s.then?(await s)():s,o()}catch(l){o(l)}}))}}]); -------------------------------------------------------------------------------- /dist/script/page-home.0a8a4a9c.js: -------------------------------------------------------------------------------- 1 | "use strict";(self.webpackChunkcnblogs_theme=self.webpackChunkcnblogs_theme||[]).push([[390],{819:function(t,n,e){e.r(n),e.d(n,{default:function(){return i}});var o=e(879);function i(){if($("#homeTopTitle span").text($.__config.info.name),$.__config.animate.homeBannerTitle.enable){const t=$("#homeTopTitle span");t.hover((()=>t.addClass("pageTitleText")),(()=>t.removeClass("pageTitleText")))}$.__config.animate.homeBanner.enable&&e.e(261).then(e.t.bind(e,20,23)).then((t=>{$(".main-header").circleMagic($.__config.animate.homeBanner.options)})),$(".scroll-down").click((function(){const t=$("#home").offset().top+10;$.__tools.actScroll(t,500)})),$("#main .c_b_p_desc_readmore").text("阅读全文 »");const t=$("#main .postTitle, #main .entrylistPosttitle");$.each(t,((t,n)=>{let e=$(n),o=e.text(),i=e.nextAll(".postDesc:eq(0), .entrylistItemPostDesc:eq(0)").text();e.after(function(t){const{date:n,vnum:e,cnum:o,tnum:i}=$.__tools.handlePostDesc(t);return` `}(i)),e.hasClass("postTitle")&&/\[置顶\]/.test(o)&&(e.append('置顶'),e.find("a").text(o.replace(/\[置顶\]/,"")))}));$(".c_b_p_desc").each(((t,n)=>{const e=$(n),o=e.find("img.desc_img");if(o.length){const t=o.attr("src");o.hide(),e.addClass("desc-width-60"),e.parent("div").addClass("desc-parent-minheight-150");const n=$('
');n.find("div").css({background:`url('${t}') center center / contain no-repeat`}),e.after(n)}}));let n=$("#hitokoto"),i=$.__config.banner.home.title;const s=["当你凝视深渊时,深渊也在凝视着你。","有的人25岁就死了,只是到75岁才埋葬"],c=t=>{n.html(t).css("display","-webkit-box"),$.__tools.setDomHomePosition()};function a(t){if("success"===t.status){const{note:n,content:e,data:o}=t,i=`《${o?.origin?.title}》 - ${o?.origin?.dynasty} - ${o?.origin?.author}`;c(n||o.content),$("#hitokotoAuthor").text(e||i).show()}}if(Array.isArray(i)&&i.length)return void c(i[$.__tools.randomNum(0,i.length-1)]);if("string"==typeof i)return void c(i);const l={one:"https://one.oyo.cool/",jinrishici:"https://v2.jinrishici.com/one.json"}[$.__config.banner.home.titleSource];if(l)r=l,(0,o.E)(r).then(a).catch((()=>{const t=$.__tools.randomNum(0,s.length-1);c(s[t])}));else{const t=$.__tools.randomNum(0,s.length-1);c(s[t])}var r}}}]); -------------------------------------------------------------------------------- /dist/script/page-links.094c85e4.js: -------------------------------------------------------------------------------- 1 | "use strict";(self.webpackChunkcnblogs_theme=self.webpackChunkcnblogs_theme||[]).push([[153,510],{415:function(n,i){i.A=''},775:function(n,i,t){t.a(n,(async function(n,a){try{t.r(i),t.d(i,{default:function(){return o}});var l=t(508),s=t(415),e=t(650),c=n([l,e]);function o(){if((0,l.default)(),$.__config.links.page.length){t.e(489).then(t.bind(t,482));const n=$("#cnblogs_post_body"),i=$(".articleSuffix-flg"),a=(n,i)=>{const{avatar:t="",name:a="",introduction:l="",url:e=""}=n,c=["icon-zhifeiji","icon-like-fill","icon-flashlight-fill"],o=c[i%c.length];return $.__tools.batchTempReplacement(s.A,[["avatar",t],["name",a],["introduction",l],["url",e],["icon",o]])},l=n=>{const{title:i,icon:t,style:l,links:s}=n;return`${i?`

${i}

`:""}`},e=$.__config.links.page.map(l).join("");i.length?i.before(e):n.append(e)}(0,e.A)()}[l,e]=c.then?(await c)():c,a()}catch(f){a(f)}}))}}]); -------------------------------------------------------------------------------- /dist/simple-memory.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangyang0210/cnblogs-theme/c555b87781d2264dce6c6d8b712d0010a7ea6517/dist/simple-memory.js.gz -------------------------------------------------------------------------------- /dist/style/background-particles.457e1a14.css: -------------------------------------------------------------------------------- 1 | #particles{height:100vh;left:0;opacity:.6;overflow:hidden;pointer-events:none;position:fixed;top:0;width:100vw;z-index:-2}#particles .particles-layer{background-position:50%;background-repeat:repeat;display:block;height:110%;left:-5%;opacity:0;position:absolute;top:-5%;width:110%}#particles .particles-layer--1{background-image:url(https://cdn.jsdelivr.net/gh/wangyang0210/pic/imgs/project/cnblogs/bg-pattern-1.svg)}#particles .particles-layer--2{background-image:url(https://cdn.jsdelivr.net/gh/wangyang0210/pic/imgs/project/cnblogs/bg-pattern-2.svg)}#particles .particles-layer--3{background-image:url(https://cdn.jsdelivr.net/gh/wangyang0210/pic/imgs/project/cnblogs/bg-pattern-3.svg)}@media (max-width:767px){#particles{display:none}} -------------------------------------------------------------------------------- /dist/style/com-before.623dd38a.css.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangyang0210/cnblogs-theme/c555b87781d2264dce6c6d8b712d0010a7ea6517/dist/style/com-before.623dd38a.css.gz -------------------------------------------------------------------------------- /dist/style/day-night.0a3de6b0.css: -------------------------------------------------------------------------------- 1 | .feedbackCon table,.feedbackCon table th,body{background-color:#333}.feedbackCon table td,.feedbackCon table th{border-bottom:1px solid #555;border-right:1px solid #555}.feedbackCon table tr:nth-child(2n){background-color:rgba(0,0,0,.1)}.feedbackCon table tr:hover{background-color:#55555570}.feedbackCon table{border:1px solid #555;color:#ddd}body{color:#ddd}#home{background-color:rgba(51,51,51,.9);box-shadow:0 0 20px 10px rgba(0,0,0,.3)}#links-box .links-item{background:#2a2a2a;box-shadow:0 1px 7px 2px #2a2a2a}#links-box .links-item:hover{box-shadow:0 4px 11px 0 rgb(0 0 0/30%),0 1px 3px 0 rgb(0 0 0/20%)}#links-box .links-item .links-info .links-info-name{color:#999}#links-box .links-item .links-icon{opacity:.8}.blogpost-body blockquote{background:#2a2a2a!important;box-shadow:0 4px 11px 0 rgb(0 0 0/20%),0 1px 3px 0 rgb(0 0 0/20%)!important;color:#ddd!important}.blogpost-body p.tip{background-color:rgba(66,185,131,.1)!important;color:#ddd!important}.blogpost-body p.warn{background-color:hsla(0,100%,70%,.1)!important;color:#ddd!important}#div_digg .diggit{background:#333;border:1px solid #365e4a;color:#44916a;float:left}#div_digg .diggit .diggnum{color:#44916a;font-size:16px}#div_digg .buryit{background:#333;border:1px solid #777;color:#999;float:right}#div_digg .buryit .burynum{color:#999;font-size:16px}.postBody{color:#ddd}.header__dev{color:#ddd!important}.dev__fe i,.dev__ux i{color:#ddd}#green_channel{border-top:1px dashed #555}#commentform_title:after,#green_channel,.entrylistTitle:after,.feedback_area_title:after{border-bottom:1px dashed #555}.comment_textarea,textarea{background-color:#333}#comment_form_container .comment_textarea{border:1px solid #555}.commentbox_title{border-bottom:1px dashed #555}footer-background{display:none}#articleSuffix{background:#2a2a2a!important;border-color:#555!important;box-shadow:0 4px 11px 0 rgba(0,0,0,.2),0 1px 3px 0 rgba(0,0,0,.2)!important;color:#ddd!important}#articleSuffix .articleSuffix-left img{border:1px solid #555}#articleDirectory a,#attention .rightMenuSpan:before,#rightBuryit .rightMenuSpan:before,#rightDiggit .rightMenuSpan:before,#rightMenu i,#rightMenuHome .rightMenuSpan:before,#rightMenuSite .rightMenuSpan:before,#rtaDirectory .rightMenuSpan:before,#toUpDown .rightMenuSpan:before,#topics .postDesc,#update .rightMenuSpan:before,.catalog-btn i,.commentbox_tab{color:#999!important}#attention .rightMenuSpan,#attention .rightMenuSpan:before,#rightBuryit .rightMenuSpan,#rightBuryit .rightMenuSpan:before,#rightDiggit .rightMenuSpan,#rightDiggit .rightMenuSpan:before,#rightMenuHome .rightMenuSpan,#rightMenuHome .rightMenuSpan:before,#rightMenuSite .rightMenuSpan,#rightMenuSite .rightMenuSpan:before,#rtaDirectory .rightMenuSpan,#rtaDirectory .rightMenuSpan:before,#toUpDown .rightMenuSpan,#toUpDown .rightMenuSpan:before,#update .rightMenuSpan,#update .rightMenuSpan:before,.catalog-btn-shadow,div#rightMenu .rightMenuItem{-webkit-box-shadow:0 1px 20px 0 rgba(0,0,0,.5),inset 0 0 0 0 rgba(0,0,0,.5)!important;box-shadow:0 1px 20px 0 rgba(0,0,0,.5),inset 0 0 0 0 rgba(0,0,0,.5)!important}div#rightMenu .rightMenuItem{background:#333!important}#articleDirectory{background:rgba(51,51,51,.9)!important;box-shadow:0 0 20px 10px rgba(0,0,0,.3)!important}#author_profile_info img.author_avatar{border:3px solid #3a3a3a}.menu-button{border:1px solid hsla(0,0%,100%,.6)!important;color:#f9f9f9!important}.menu-button:before{background:linear-gradient(#f9f9f9 20%,transparent 0,transparent 40%,#f9f9f9 0,#f9f9f9 60%,transparent 0,transparent 80%,#f9f9f9 0)!important}.sb-title{color:#f9f9f9}.menu-button-scroll{background:#222!important;border:0!important;box-shadow:0 1px 20px 0 rgba(0,0,0,.5),inset 0 0 0 0 rgba(0,0,0,.5)!important}.introduce-box{opacity:.85}.entrylistPosttitle a:active,.entrylistPosttitle a:link,.entrylistPosttitle a:visited,.postTitle a:active,.postTitle a:link,.postTitle a:visited{color:#ddd}.entrylistPosttitle a:hover,.postTitle a:hover{color:#eee}.entrylistPostSummary,.postCon{color:#ddd}.c_b_p_desc_readmore{color:#999!important}.postMeta{color:#999}.day,.entrylistItem:not(:last-of-type){border-bottom:1px solid #555}.day:after,.entrylistItem:not(:last-of-type):after{background:#333;border:1px solid #555;box-shadow:0 0 0 5px rgba(51,51,51,.7)}.PostList{border-bottom:1px dashed #555}.list .inc .bottom,.list .inc .bottomleft,.list .inc .bottomright,.list .inc .left,.list .inc .right,.list .inc .top,.list .inc .topleft,.list .inc .topright,.list .out .bottom,.list .out .bottomleft,.list .out .bottomright,.list .out .conmts,.list .out .left,.list .out .right,.list .out .top,.list .out .topleft,.list .out .topright{background:unset}.main-header{box-shadow:0 1px 2px rgba(0,0,0,.5)}#nav_next_page a:hover,.pager a:hover{background:#555}.postBody h1,.postBody h2,.postBody h3,.postBody h4,.postBody h5,.postBody h6{color:#ddd!important}#articleDirectory ul li a.active,#articleDirectory ul li a:hover{background:rgba(0,0,0,.1)!important;color:#567fb5!important}#articleDirectory ul li a.active:after,#articleDirectory ul li a:hover:after{border-left:3px solid #567fb5!important}.book-card{background:#2a2a2a;box-shadow:0 1px 20px 0 rgba(0,0,0,.5),inset 0 0 0 0 rgba(0,0,0,.5)!important}.book-cards .book-name{color:#999}.book-cards .book-by{color:#777}.book-cards .book-rate i{color:#cb7310}.book-cards .book-card-img{border-bottom:1px solid #2a2a2a;box-shadow:0 1px 7px 2px #222}#EntryTag,#btn_comment_submit,#cnblogs_post_body img,#div_digg,#green_channel,.feedbackItem pre,.main-header{filter:brightness(.8)}.list .inc .conmts{background:unset;color:#ddd}.feedbackListSubtitle{background-color:#2a2a2a;border:1px solid #555;color:#999}.feedbackCon{background:#333;border:1px solid #555}.feedbackListSubtitle-louzhu{background-color:#25282d!important;border-bottom-color:#444!important}.feedbackListSubtitle-louzhu:after{border-right-color:#25282d!important}.feedbackAvatar img{border:1px solid #555}.feedbackItem:before{background-color:#555}.feedbackListSubtitle:before{border-right-color:#555}.feedbackListSubtitle:after{border-right-color:#2a2a2a}#tbCommentBody,#tbCommentBodyPreview{color:#ddd}.cnblogs_code_collapse{background-color:#333}.aplayer{color:#666}details{border:1px solid #0877ef66}@media only screen and (max-width:720px){.menu-button{border:none!important;margin:0!important}#home{box-shadow:unset}.menu-button-scroll{background:#444!important}} -------------------------------------------------------------------------------- /dist/style/gf-blink.0cc7f6e2.css.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangyang0210/cnblogs-theme/c555b87781d2264dce6c6d8b712d0010a7ea6517/dist/style/gf-blink.0cc7f6e2.css.gz -------------------------------------------------------------------------------- /dist/style/google-fonts.66c39700.css.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangyang0210/cnblogs-theme/c555b87781d2264dce6c6d8b712d0010a7ea6517/dist/style/google-fonts.66c39700.css.gz -------------------------------------------------------------------------------- /dist/style/iconfont.cfd96386.css: -------------------------------------------------------------------------------- 1 | @font-face{font-family:iconfont;src:url(//at.alicdn.com/t/c/font_3634484_hos8l5ffkw7.woff2?t=1671345294162) format("woff2"),url(//at.alicdn.com/t/c/font_3634484_hos8l5ffkw7.woff?t=1671345294162) format("woff"),url(//at.alicdn.com/t/c/font_3634484_hos8l5ffkw7.ttf?t=1671345294162) format("truetype")}.iconfont{font-family:iconfont!important;font-size:16px;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon{height:1em;vertical-align:-.15em;width:1em;fill:currentColor;margin-right:5px;overflow:hidden}.icon-update-2:before{content:"\e621"}.icon-update-1:before{content:"\e823"}.icon-update:before{content:"\e7d2"}.icon-fuzhi:before{content:"\e60d"}.icon-browse-fill:before{content:"\e6e4"}.icon-brush-fill:before{content:"\e6e5"}.icon-document-fill:before{content:"\e6f3"}.icon-label-fill:before{content:"\e706"}.icon-right:before{content:"\e721"}.icon-task-fill:before{content:"\e732"}.icon-marketing-fill:before{content:"\e74b"}.icon-comments:before{content:"\e617"}.icon-interactive:before{content:"\e63b"}.icon-code:before{content:"\e6f2"}.icon-browse:before{content:"\e745"}.icon-collection-fill:before{content:"\e79d"}.icon-flashlight-fill:before{content:"\efa3"}.icon-dianzan:before{content:"\e674"}.icon-time-fill:before{content:"\e632"}.icon-buzan:before{content:"\fa78"}.icon-unfollower:before{content:"\e616"}.icon-fanhui:before{content:"\e60e"}.icon-zhiding:before{content:"\e739"}.icon-follower:before{content:"\e841"}.icon-lianjie:before{content:"\e60f"}.icon-website:before{content:"\e61a"}.icon-cnblogs:before{content:"\e607"}.icon-mulu:before{content:"\e609"}.icon-fenxiang:after{content:"\e614"}.icon-dashang:before{content:"\e691"}.icon-close:before{content:"\e73e"}.icon-youjiantou:before{content:"\e68c"}.icon-fenleicur:before{content:"\e629"}.icon-sousuo:before{content:"\e62f"}.icon-shezhi-fill:before{content:"\e8b8"}.icon-article:before{content:"\e612"}.icon-guangbo:before{content:"\e6ae"}.icon-yuan:before{content:"\eb99"}.icon-xinlv:before{content:"\e610"}.icon-blog:before{content:"\e633"}.icon-fenlei:before{content:"\e613"}.icon-yongyan:before{content:"\e600"}.icon-facebook:before{content:"\e601"}.icon-dingyue:before{content:"\e602"}.icon-qq-fill:before{content:"\e603"}.icon-github:before{content:"\e604"}.icon-weiruan:before{content:"\e605"}.icon-schedule:before{content:"\ecec"}.icon-home:before{content:"\e65c"}.icon-csdn:before{content:"\e60a"}.icon-book:before{content:"\e67c"}.icon-shezhi:before{content:"\e611"}.icon-kafei:before{content:"\e60b"}.icon-zhifeiji:before{content:"\e6a0"}.icon-home-fill:before{content:"\e702"}.icon-twitter:before{content:"\e7a6"}.icon-markdown:before{content:"\e6f5"}.icon-google:before{content:"\e6b2"}.icon-instagram:before{content:"\e6b6"}.icon-youtube:before{content:"\e6b7"}.icon-wordpress:before{content:"\e72f"}.icon-pinterest:before{content:"\e658"}.icon-tux:before{content:"\e65d"}.icon-npm:before{content:"\e74e"}.icon-erweima:before{content:"\e631"}.icon-gitee-fill:before{content:"\e686"}.icon-apple:before{content:"\e681"}.icon-aliyun:before{content:"\e62a"}.icon-gitlab:before{content:"\e62c"}.icon-dingding:before{content:"\e62d"}.icon-baidu:before{content:"\e62b"}.icon-qq:before{content:"\e676"}.icon-weibo:before{content:"\e6b0"}.icon-wechat:before{content:"\e6b1"}.icon-star-full:before{content:"\e9a1"}.icon-star:before{content:"\e9a2"}.icon-star-half:before{content:"\e9a3"}.icon-gmail:before{content:"\e606"}.icon-linkedin:before{content:"\e608"}.icon-html5:before{content:"\e8b6"}.icon-wechat-fill:before{content:"\e9e6"}.icon-tengxunyun:before{content:"\ee49"}.icon-bilibili:before{content:"\e7d6"}.icon-hot:before{content:"\e618"}.icon-keaide:before{content:"\e60c"}.icon-like-fill:before{content:"\e668"} -------------------------------------------------------------------------------- /dist/style/mouse-mouse.5e68e4e5.css: -------------------------------------------------------------------------------- 1 | .cursor{background:#333;border-radius:50%}.cursor-f{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='47' height='47' fill='none'%3E%3Cpath stroke='%23000' d='M42.42 42.42C38.84 46 33.36 46 23.5 46S8.16 46 4.58 42.42 1 33.36 1 23.5 1 8.16 4.58 4.58 13.64 1 23.5 1s15.34 0 18.92 3.58S46 13.64 46 23.5s0 15.34-3.58 18.92Z'/%3E%3C/svg%3E");background-size:cover;left:0;opacity:.7;top:0}.cursor,.cursor-f{height:var(--size);pointer-events:none;position:absolute;width:var(--size);z-index:999} -------------------------------------------------------------------------------- /dist/style/nh-banner-animation.7ff7a955.css: -------------------------------------------------------------------------------- 1 | #nhBannerAnimation{height:100%;position:absolute;width:100%;z-index:1}#nhBannerAnimation .circles{height:100%;left:0;overflow:hidden;position:absolute;top:0;width:100%}#nhBannerAnimation .circles li{animation:nhBannerAnimation 25s linear infinite;background:hsla(0,0%,100%,.2);bottom:-150px;display:block;height:20px;list-style:none;position:absolute;width:20px}#nhBannerAnimation .circles li:first-child{animation-delay:0s;height:80px;left:25%;width:80px}#nhBannerAnimation .circles li:nth-child(2){animation-delay:2s;animation-duration:12s;height:20px;left:10%;width:20px}#nhBannerAnimation .circles li:nth-child(3){animation-delay:4s;height:20px;left:70%;width:20px}#nhBannerAnimation .circles li:nth-child(4){animation-delay:0s;animation-duration:18s;height:60px;left:40%;width:60px}#nhBannerAnimation .circles li:nth-child(5){animation-delay:0s;height:20px;left:65%;width:20px}#nhBannerAnimation .circles li:nth-child(6){animation-delay:3s;height:110px;left:75%;width:110px}#nhBannerAnimation .circles li:nth-child(7){animation-delay:7s;height:150px;left:35%;width:150px}#nhBannerAnimation .circles li:nth-child(8){animation-delay:15s;animation-duration:45s;height:25px;left:50%;width:25px}#nhBannerAnimation .circles li:nth-child(9){animation-delay:2s;animation-duration:35s;height:15px;left:20%;width:15px}#nhBannerAnimation .circles li:nth-child(10){animation-delay:0s;animation-duration:11s;height:150px;left:85%;width:150px}@keyframes nhBannerAnimation{0%{border-radius:0;opacity:1;transform:translateY(0) rotate(0deg)}to{border-radius:50%;opacity:0;transform:translateY(-1000px) rotate(2turn)}} -------------------------------------------------------------------------------- /dist/style/page-article.de68d80d.css.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangyang0210/cnblogs-theme/c555b87781d2264dce6c6d8b712d0010a7ea6517/dist/style/page-article.de68d80d.css.gz -------------------------------------------------------------------------------- /dist/style/page-books.d2212f9a.css.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangyang0210/cnblogs-theme/c555b87781d2264dce6c6d8b712d0010a7ea6517/dist/style/page-books.d2212f9a.css.gz -------------------------------------------------------------------------------- /dist/style/page-common-com-article.de68d80d.css.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangyang0210/cnblogs-theme/c555b87781d2264dce6c6d8b712d0010a7ea6517/dist/style/page-common-com-article.de68d80d.css.gz -------------------------------------------------------------------------------- /dist/style/page-links.cb8ec4a1.css.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangyang0210/cnblogs-theme/c555b87781d2264dce6c6d8b712d0010a7ea6517/dist/style/page-links.cb8ec4a1.css.gz -------------------------------------------------------------------------------- /docs/v2/.vitepress/cache/deps/_metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "hash": "86fbf3a9", 3 | "configHash": "aa705015", 4 | "lockfileHash": "21ffe7a2", 5 | "browserHash": "5400aca9", 6 | "optimized": { 7 | "vue": { 8 | "src": "../../../../../node_modules/vue/dist/vue.runtime.esm-bundler.js", 9 | "file": "vue.js", 10 | "fileHash": "56e96765", 11 | "needsInterop": false 12 | }, 13 | "vitepress > @vue/devtools-api": { 14 | "src": "../../../../../node_modules/@vue/devtools-api/dist/index.js", 15 | "file": "vitepress___@vue_devtools-api.js", 16 | "fileHash": "c641a156", 17 | "needsInterop": false 18 | }, 19 | "vitepress > @vueuse/core": { 20 | "src": "../../../../../node_modules/@vueuse/core/index.mjs", 21 | "file": "vitepress___@vueuse_core.js", 22 | "fileHash": "10e9d424", 23 | "needsInterop": false 24 | }, 25 | "vitepress > @vueuse/integrations/useFocusTrap": { 26 | "src": "../../../../../node_modules/@vueuse/integrations/useFocusTrap.mjs", 27 | "file": "vitepress___@vueuse_integrations_useFocusTrap.js", 28 | "fileHash": "8923d2b8", 29 | "needsInterop": false 30 | }, 31 | "vitepress > mark.js/src/vanilla.js": { 32 | "src": "../../../../../node_modules/mark.js/src/vanilla.js", 33 | "file": "vitepress___mark__js_src_vanilla__js.js", 34 | "fileHash": "e457b1f8", 35 | "needsInterop": false 36 | }, 37 | "vitepress > minisearch": { 38 | "src": "../../../../../node_modules/minisearch/dist/es/index.js", 39 | "file": "vitepress___minisearch.js", 40 | "fileHash": "9ab29add", 41 | "needsInterop": false 42 | } 43 | }, 44 | "chunks": { 45 | "chunk-YZ3AHZKA": { 46 | "file": "chunk-YZ3AHZKA.js" 47 | }, 48 | "chunk-TQVJM66I": { 49 | "file": "chunk-TQVJM66I.js" 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /docs/v2/.vitepress/cache/deps/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module" 3 | } 4 | -------------------------------------------------------------------------------- /docs/v2/.vitepress/cache/deps/vitepress___@vueuse_core.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "sources": [], 4 | "sourcesContent": [], 5 | "mappings": "", 6 | "names": [] 7 | } 8 | -------------------------------------------------------------------------------- /docs/v2/.vitepress/cache/deps/vue.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "sources": [], 4 | "sourcesContent": [], 5 | "mappings": "", 6 | "names": [] 7 | } 8 | -------------------------------------------------------------------------------- /docs/v2/.vitepress/config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitepress'; 2 | import zhConfig from './locales/zh.config.js'; 3 | import markdownItTaskLists from 'markdown-it-task-lists'; 4 | 5 | // https://vitepress.dev/reference/site-config 6 | export default defineConfig({ 7 | base: '/cnblogs-theme/', 8 | title: 'SMemory', 9 | description: 'Documents', 10 | lastUpdated: true, 11 | srcDir: './src', 12 | locales: { 13 | root: zhConfig, 14 | }, 15 | head: [['link', { rel: 'icon', href: 'https://pic.imgdb.cn/item/676dfbe9d0e0a243d4eb1a0c.png' }]], 16 | themeConfig: { 17 | logo: 'https://pic.imgdb.cn/item/676ba098d0e0a243d4e9d23d.png', 18 | search: { 19 | provider: 'local', 20 | }, 21 | socialLinks: [ 22 | { icon: 'refinedgithub', link: 'https://github.com/wangyang0210/cnblogs-theme' }, 23 | { icon: 'github', link: 'https://github.com/BNDong/Cnblogs-Theme-SimpleMemory' }, 24 | ], 25 | }, 26 | markdown: { 27 | lineNumbers: true, 28 | config: (md) => { 29 | md.use(markdownItTaskLists); 30 | }, 31 | }, 32 | }); 33 | -------------------------------------------------------------------------------- /docs/v2/.vitepress/locales/zh.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | label: "简体中文", 3 | lang: "zh", 4 | link: "/", 5 | themeConfig: { 6 | nav: [ 7 | { text: "首页", link: "/" }, 8 | { text: "指南", link: "/guide/install", activeMatch: "/guide/" }, 9 | { text: "参考", link: "/reference/configs", activeMatch: "/reference/" }, 10 | { text: "更新历史", link: "/changelog/", activeMatch: "/changelog/" }, 11 | ], 12 | sidebar: { 13 | '/guide/': [ 14 | { 15 | "text": "入门", 16 | "collapsed": false, 17 | "items": [ 18 | { 19 | "text": "安装配置", 20 | "link": "/guide/install" 21 | } 22 | ] 23 | }, 24 | { 25 | "text": "写作", 26 | "collapsed": false, 27 | "items": [ 28 | { 29 | "text": "书写规范", 30 | "link": "/guide/writtenForm" 31 | }, 32 | { 33 | "text": "菜单数据", 34 | "link": "/guide/menuData" 35 | }, 36 | { 37 | "text": "标题/目录", 38 | "link": "/guide/articleDirectory" 39 | }, 40 | ] 41 | }, 42 | { 43 | "text": "其它", 44 | "collapsed": false, 45 | "items": [ 46 | { 47 | "text": "资源托管", 48 | "link": "/guide/resourceCdn" 49 | }, 50 | { 51 | "text": "版本切换", 52 | "link": "/guide/versionSwitch" 53 | }, 54 | { 55 | "text": "调试开发", 56 | "link": "/guide/codespaces" 57 | }, 58 | { 59 | "text": "关于项目", 60 | "link": "/guide/my" 61 | }, 62 | ] 63 | } 64 | ], 65 | "/reference/": [ 66 | { 67 | "text": "参考", 68 | // "collapsed": false, 69 | "items": [ 70 | { 71 | "text": "配置项", 72 | "link": "/reference/configs" 73 | }, 74 | { 75 | "text": "转载文章", 76 | "link": "/reference/reprinted" 77 | }, 78 | { 79 | "text": "字体图标", 80 | "link": "/reference/fonticon" 81 | }, 82 | { 83 | "text": "Loading", 84 | "link": "/reference/loading" 85 | }, 86 | { 87 | "text": "书单页", 88 | "link": "/reference/bookList" 89 | }, 90 | { 91 | "text": "友链页", 92 | "link": "/reference/links" 93 | }, 94 | { 95 | "text": "钩子", 96 | "link": "/reference/hook" 97 | }, 98 | ] 99 | } 100 | ] 101 | }, 102 | docFooter: { 103 | prev: "上一页", 104 | next: "下一页", 105 | }, 106 | lastUpdated: { 107 | text: "上次更新时间" 108 | }, 109 | darkModeSwitchLabel: "日/夜间模式", 110 | sidebarMenuLabel: "菜单", 111 | returnToTopLabel: "返回顶部", 112 | editLink: { 113 | pattern: 'https://github.com/BNDong/Cnblogs-Theme-SimpleMemory/edit/v2/docs/v2.1/docs/src/:path', 114 | text: "编辑此页面" 115 | }, 116 | outline: "deep", 117 | outlineTitle: "文档导读", 118 | search: { 119 | provider: "local", 120 | options: { 121 | locales: { 122 | root: { 123 | translations: { 124 | button: { 125 | buttonText: "搜索文档", 126 | buttonAriaLabel: "搜索文档", 127 | }, 128 | modal: { 129 | searchBox: { 130 | resetButtonTitle: "清除查询条件", 131 | resetButtonAriaLabel: "清除查询条件", 132 | cancelButtonText: "取消", 133 | cancelButtonAriaLabel: "取消", 134 | }, 135 | startScreen: { 136 | recentSearchesTitle: "搜索历史", 137 | noRecentSearchesText: "没有搜索历史", 138 | saveRecentSearchButtonTitle: "保存至搜索历史", 139 | removeRecentSearchButtonTitle: "从搜索历史中移除", 140 | favoriteSearchesTitle: "收藏", 141 | removeFavoriteSearchButtonTitle: "从收藏中移除", 142 | }, 143 | errorScreen: { 144 | titleText: "无法获取结果", 145 | helpText: "你可能需要检查你的网络连接", 146 | }, 147 | footer: { 148 | selectText: "选择", 149 | navigateText: "切换", 150 | closeText: "关闭", 151 | searchByText: "搜索提供者", 152 | }, 153 | noResultsScreen: { 154 | noResultsText: "无法找到相关结果", 155 | suggestedQueryText: "你可以尝试查询", 156 | reportMissingResultsText: "你认为该查询应该有结果?", 157 | reportMissingResultsLinkText: "点击反馈", 158 | }, 159 | }, 160 | }, 161 | }, 162 | }, 163 | }, 164 | }, 165 | footer: { 166 | copyright: " ☘️ SimpleMemory © 2018-2024", 167 | }, 168 | }, 169 | }; 170 | -------------------------------------------------------------------------------- /docs/v2/.vitepress/theme/index.js: -------------------------------------------------------------------------------- 1 | // https://vitepress.dev/guide/custom-theme 2 | import DefaultTheme from 'vitepress/theme' 3 | import './style.css' 4 | 5 | export default DefaultTheme 6 | -------------------------------------------------------------------------------- /docs/v2/.vitepress/theme/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --vp-home-hero-name-color: transparent; 3 | --vp-home-hero-name-background: -webkit-linear-gradient(120deg, #8722f2 30%, rgba(190, 34, 242, 0.45)); 4 | --vp-home-hero-image-background-image: linear-gradient(-45deg, rgba(240, 76, 252, 0.38) 50%, rgba(32, 253, 182, 0.47) 50%); 5 | --vp-home-hero-image-filter: blur(40px); 6 | 7 | --vp-c-brand: #8a4bea; 8 | --vp-c-brand-1: #8a4bea; 9 | --vp-c-brand-dark: #8a4bea; 10 | 11 | --vp-c-brand-light: #8a4bea; 12 | --vp-button-brand-hover-bg: #8a4bea; 13 | 14 | 15 | --vp-button-brand-border: #9600bf; 16 | --vp-button-brand-bg: #8a4bea; 17 | } 18 | 19 | .image-src { 20 | max-width: 300px !important; 21 | max-height: 300px !important; 22 | } 23 | 24 | @media (min-width: 640px) { 25 | :root { 26 | --vp-home-hero-image-filter: blur(56px); 27 | } 28 | } 29 | 30 | @media (min-width: 960px) { 31 | :root { 32 | --vp-home-hero-image-filter: blur(72px); 33 | } 34 | 35 | .image-src { 36 | max-width: 300px !important; 37 | max-height: 300px !important; 38 | } 39 | } 40 | 41 | .task-list-item-checkbox:not(:checked) { 42 | appearance: none; 43 | width: 16px; 44 | height: 16px; 45 | border: 1px solid #8a4bea; 46 | border-radius: 3px; 47 | margin-right: 5px; 48 | vertical-align: middle; 49 | } 50 | -------------------------------------------------------------------------------- /docs/v2/src/changelog/index.md: -------------------------------------------------------------------------------- 1 | # 待做事项 2 | 3 | - [ ] 支持在测试博客园页面预览各种配置设置 4 | 5 | 6 | # 更新历史 7 | 8 | ## 2024.12.31 - v2.1.8 9 | - 博客园评论排序兼容及样式调整 10 | - 代码优化和配置项调整 11 | - 修复部分已知问题 12 | - 支持设置鼠标样式 -------------------------------------------------------------------------------- /docs/v2/src/guide/articleDirectory.md: -------------------------------------------------------------------------------- 1 | # 文章标题/目录 2 | 3 | ::: tip 提示 4 | v2 版本中移除了对标题样式的渲染。 5 | ::: 6 | 7 | ## 关于文章标题 8 | 9 | 支持标题级别的识别。 10 | 11 | 例如我的文章: 12 | 13 | ``` 14 | ## 我是 makdown 二级标题 15 | 16 | #### 我是 makdown 四级标题 17 | 18 | ### 我是 makdown 三级标题 19 | 20 | #### 我是 makdown 四级标题 21 | ``` 22 | 23 | 主题会自动识别 `##` 为文章的一级标题, `###` 为文章的二级标题,依此类推。 24 | 25 | ::: warning 注意 26 | 当最高级标题为 `##` 时,即使文章中没有 `###` 级标题,主题仍会认为 `###` 为二级标题。 27 | ::: 28 | 29 | ## 关于文章目录 30 | 31 | 支持多级目录自动生成,支持标题级别1~6。 -------------------------------------------------------------------------------- /docs/v2/src/guide/codespaces.md: -------------------------------------------------------------------------------- 1 | # 调试开发 2 | 3 | ## 使用 DevTools 调试开发 4 | 如果是简单的一些调试,可以使用 DevTools 进行调试。直接基于`源代码/来源->替换`,可直接调试当前网页的js代码。 5 | 6 | ## 使用 jsDelivr 调试开发 7 | 8 | fork 仓库后,你依然可以使用 jsDelivr 加载自己仓库的插件,支持针对某个 commits 进行加载。 9 | 10 | ```html 11 | 12 | 13 | ``` 14 | 15 | jsDelivr 的 URL 详细规则参考[官方网站](https://www.jsdelivr.com/)。 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /docs/v2/src/guide/install.md: -------------------------------------------------------------------------------- 1 | # 安装配置 2 | 3 | ::: danger 注意 4 | 1. 本文档为 v2 版本的安装配置教程,请核对使用版本。 5 | 2. 应用插件需要 JS 权限,没有的请先申请权限。 6 | 3. 当前插件版本为Canary版本!!! 7 | ::: 8 | 9 | ## 获取插件 10 | 11 | ::: tip 提示 12 | 建议使用最新版本,历史版本随着博客园不断迭代,会出现兼容性问题。 13 | ::: 14 | 15 | 进入插件仓库:[点击进入](https://github.com/wangyang0210/cnblogs-theme) 16 | 17 | 18 | ## 博客园后台配置 19 | 20 | ### 进入管理后台 21 | 22 | 首先进入管理后台:[点击访问](https://i.cnblogs.com/Configure.aspx) 23 | 24 | ### 选项页 25 | 26 | 进入管理后台/选项页。 27 | 28 | ![img](https://pic.imgdb.cn/item/676ba138d0e0a243d4e9d277.png) 29 | 30 | #### 控件确认 31 | 32 | 确认博客需要开启/关闭哪些控件: 33 | 34 | ![img](https://pic.imgdb.cn/item/676b9f15d0e0a243d4e9d1d4.png) 35 | 36 | ### 设置页 37 | 38 | 进入管理后台/设置页。 39 | ![img](https://pic.imgdb.cn/item/676ba052d0e0a243d4e9d22b.png) 40 | 41 | #### 设置博客皮肤 42 | 43 | 博客皮肤:```SimpleMemory``` 44 | 45 | #### 代码高亮配置 46 | 47 | ::: tip 提示 48 | 当前插件版本为Canary版本,直接兼容博客园本身的代码高亮设置,不再提供独立代码高亮配置。 49 | ::: 50 | 51 | ![img](https://pic.imgdb.cn/item/676b9da5d0e0a243d4e9d177.png) 52 | 53 | #### 页面定制 CSS 代码 54 | 55 | * 勾选`禁用模板默认CSS` 56 | 57 | * 拷贝插件的 CSS 代码 58 | * CSS 代码在插件仓库目录位置:`/dist/simpleMemory.css` 59 | * 拷贝此文件代码至页面定制 CSS 代码文本框处。 60 | 61 | ![img](https://pic.imgdb.cn/item/676ba1abd0e0a243d4e9d296.png) 62 | 63 | #### 博客侧边栏公告 64 | 65 | 在侧边栏HTML代码中设置以下代码: 66 | 67 | ```html 68 | 77 | 78 | 79 | 80 | ``` 81 | 82 | **关于插件文件的说明** 83 | 84 | - `cdnjs`: cdnjs 是一个免费的、开源的内容分发网络(CDN)。插件文件引入的地址目的是引入插件库上的 JS 文件,如果有其它合适的 CDN 亦可根据规则进行替换。 85 | - `VERSION`: 插件文件引入地址中的 `{VERSION}`,代表了插件版本的占位,可以根据使用版本进行修改。示例:`2.1.8` 86 | 87 | ## 配置完成 88 | 89 | 配置完成,保存即可成功应用插件! -------------------------------------------------------------------------------- /docs/v2/src/guide/menuData.md: -------------------------------------------------------------------------------- 1 | # 菜单数据 2 | 3 | 如果遇到菜单数据不显示,请以下面的方式进行排查处理。 4 | 5 | ## 支持的菜单数据不显示的调试方法 6 | 7 | ### 开启对应显示设置 8 | 9 | 『博客设置』--->『选项』--->『控件显示设置』--->『SAVE』 10 | 11 | ::: tip 提示 12 | 由于博客园有缓存机制,设置后稍等几分钟才会生效。 13 | ::: 14 | 15 | ## 设置对应数据 16 | 17 | 如果没有相应的数据,即使设置了显示,博客园也不会返回对应的栏目的数据,这样也会造成不显示的问题。 18 | 19 | * 随笔分类:『博客设置』--->『随笔』--->『分类』 20 | * 推荐排行:如果没有推荐,此类别不会显示,解决办法只能是别人给你点个推荐。 21 | 22 | ### 利用工具调试 23 | 24 | 如果以上两种方式都不能解决问题,使用此方法进行尝试。 25 | 26 | 使用浏览器的『开发者工具』搜索HTML代码: 27 | 28 | ```html 29 |

30 | ``` 31 | 32 | 注释掉 class `catListTitle` 的 CSS 设置 `display: none!important` 33 | 34 | 这时你会发现在页面右下方,默认样式的侧边数据栏显示了出来,找一找有没有菜单没显示那栏数据。 35 | 36 | * 如果这里没有,那可能是官方问题,检查下自己的设置。 37 | * 如果这里有,(;´д`)ゞ,可能是插件处理逻辑有问题,请 [issues](https://github.com/wangyang0210/cnblogs-theme/issues) 提交问题,无意外的情况下,都会在当天进行修复! -------------------------------------------------------------------------------- /docs/v2/src/guide/my.md: -------------------------------------------------------------------------------- 1 | # 关于项目 2 | 3 | 目前大家正在使用的这个版本属于 Canary 版本。Canary 版本的特点在于它是我进行自我验证和优化的一个先行版本,这意味着它可能存在较多的问题,但相应地,其更新迭代的速度也会很快。 4 | 5 | 如果大家更注重稳定性,追求平稳可靠的使用体验,我强烈推荐使用 [Cnblogs-Theme-SimpleMemory](https://github.com/BNDong/Cnblogs-Theme-SimpleMemory) 这个稳定版本。一旦某些功能或优化在 Canary 版本中经过充分验证,确认其稳定性和实用性后,我会将这些经过考验的功能和优化逐步整合到稳定版本中。 6 | 7 | 此外,在使用 Canary 版本时,如果大家遇到任何问题或者有相关的建议,欢迎随时向我反馈。您的反馈对于我进一步完善这个版本至关重要,能够帮助我更快地发现问题并找到解决方案,从而推动整个项目朝着更加成熟、稳定的方向发展。 8 | 9 | --- 10 | 11 |

2024.12.25 WangYang

-------------------------------------------------------------------------------- /docs/v2/src/guide/resourceCdn.md: -------------------------------------------------------------------------------- 1 | # 资源托管 2 | 3 | ## 云资源 4 | 可以将插件托管到自己的云资源或其它 CDN 加速节点上。 5 | 6 | 例如:我的网站为 `www.oyo.com`(实际根据情况可以是 IP 或其它 host) 7 | 8 | 然后我将编译后的文件夹 `dist` 放到了网站的根目录。 9 | 10 | 这样我可以通过加载 `https://www.oyo.com/dist/simple-memory.min.js` 来安装插件: 11 | 12 | ```html 13 | 18 | 19 | ``` 20 | 21 | ## Vercel 22 | 如果你是基于 jsDelivr 加载的资源文件且拥有自己的域名, 那么你可以尝试访问[jsDelivr-mirror-site](https://github.com/wangyang0210/jsDelivr-mirror-site),通过 Vercel 部署,轻松实现一个属于自己的镜像加速。 23 | 24 | ## 国内镜像 25 | 国内有很多镜像站会定时同步cdnjs,普通用户,可以尝试使用国内的加速镜像站。 26 | -------------------------------------------------------------------------------- /docs/v2/src/guide/versionSwitch.md: -------------------------------------------------------------------------------- 1 | # 版本切换 2 | 3 | ::: danger 注意 4 | 任何版本的切换,最好都更新一下对应版本的 CSS 样式,不然可能会发生兼容性问题! 5 | ::: 6 | 7 | ### 使用 cdnjs 加载资源 8 | 9 | 只需要更改 `simple-memory.min.js` 文件引入的版本。 10 | 11 | 例如: 12 | 13 | ```html{6} 14 | 19 | 20 | 21 | ``` 22 | 23 | 变为 24 | 25 | ```html{6} 26 | 31 | 32 | ``` 33 | 34 | 版本变更: `v2.1.7` >>> `v2.1.8` 35 | 36 | ### 使用自己的云资源 37 | 38 | 如果你的资源是托管到自己的云资源上, 建议使用随机参方式更新加载资源。 39 | 40 | 例如: 41 | 42 | ```html 43 | 44 | ``` 45 | 46 | 变为 47 | 48 | ```html 49 | 50 | ``` 51 | 52 | 这样浏览器就会加载最新的代码。 53 | -------------------------------------------------------------------------------- /docs/v2/src/guide/writtenForm.md: -------------------------------------------------------------------------------- 1 | # 书写规范 2 | 3 | ### 编辑器 4 | 5 | * 富文本编辑器建议:`TinyMCE` 6 | * MD 编辑器建议:`Markdown` 7 | 8 | ### 规范 9 | 10 | | **类型** | **TinyMCE** | **Markdown** | 11 | | :----------------------------------------------------------------------------: | :------------: | :----------: | 12 | | **一级标题** | `

` | `#` | 13 | | **二级标题** | `

` | `##` | 14 | | **引用文字** | `引用 or

` | `>` | 15 | | **行内代码** | `行内代码` | ` | 16 | | [代码折叠](https://github.com/BNDong/Cnblogs-Theme-SimpleMemory/pull/381) | 见下方示例 | 见下方示例 | 17 | | [重要/警告引用](https://github.com/BNDong/Cnblogs-Theme-SimpleMemory/pull/380) | `!>` | `!>` | 18 | | [普通/信息引用](https://github.com/BNDong/Cnblogs-Theme-SimpleMemory/pull/380) | `?>` | `?>` | 19 | 20 | **代码折叠示例** 21 | 22 | ```html 23 |
24 | 代码 25 | 代码块内容 26 |
27 | ``` -------------------------------------------------------------------------------- /docs/v2/src/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: home 3 | 4 | hero: 5 | name: "SimpleMemory" 6 | text: "Theme Extension" 7 | tagline: 基于博客园 SimpleMemory 主题的扩展美化插件(Canary版本) 8 | image: 9 | src: https://pic.imgdb.cn/item/676ba098d0e0a243d4e9d23d.png 10 | alt: SimpleMemory 11 | actions: 12 | - theme: brand 13 | text: 示例博客 14 | link: https://www.cnblogs.com/wangyang0210 15 | - theme: alt 16 | text: 快速开始 17 | link: /guide/install 18 | 19 | features: 20 | - title: 🍡 开箱即用 21 | details: 简单配置即可成功使用 22 | - title: 🍭 高灵活性 23 | details: 界面配置化,可自定义调整显示内容 24 | - title: 🍬 多端兼容 25 | details: 兼容 PC 端、平板和移动端 26 | --- -------------------------------------------------------------------------------- /docs/v2/src/reference/bookList.md: -------------------------------------------------------------------------------- 1 | # 书单/影单页 2 | 3 | 样式参考:[书单/影单](https://www.cnblogs.com/wangyang0210/p/16535755.html) 4 | 5 | ## 配置方式 6 | 7 | ### 标识页面为书单页面 8 | 9 | 首先需要在页面源码中加入以下代码,来标识该页面为书单页面: 10 | 11 | ```html 12 | 13 | ``` 14 | 15 | ::: danger 注意 16 | 是添加到 HTML 源码中,博客园文章的富文本编辑器和 Markdown 都有添加 HTML 代码的方式! 17 | ::: 18 | 19 | #### 富文本编辑器 20 | 21 | ![img](https://pic.imgdb.cn/item/676df60dd0e0a243d4eb1989.png) 22 | 23 | #### Markdown 24 | 25 | 直接拷贝到文本即可。 26 | 27 | ### 配置书单数据 28 | 29 | 书单的配置,可以参考其他[配置](/reference/configs)的方式。例如: 30 | 31 | ```javascript 32 | window.cnblogsConfig = { 33 | bookList: [], 34 | } 35 | ``` 36 | 37 | 但是一般书单的数据比较多,所以建议将此配置单独出来。例如: 38 | 39 | ```javascript 40 | 41 | // 正常配置 42 | window.cnblogsConfig = { 43 | ... 44 | }; 45 | 46 | // 书单配置 47 | window.cnblogsConfig.bookList = [ 48 | { 49 | title: '已看', 50 | books: [ 51 | { 52 | cover: 'https://images.cnblogs.com/cnblogs_com/wangyang0210/2205307/o_230302124618_s3078482.jpg', 53 | name: '三体Ⅱ', 54 | formerName: '', 55 | author: '刘慈欣', 56 | translator: '', 57 | press: '重庆出版社', 58 | year: '2008-5', 59 | score: 4.5 60 | }, 61 | ] 62 | }, 63 | { 64 | title: '已观', 65 | books: [ 66 | { 67 | cover: 'https://images.cnblogs.com/cnblogs_com/wangyang0210/2205307/o_230317160847_p480747492.webp', 68 | name: '肖申克的救赎 The Shawshank Redemption', 69 | direct: '弗兰克·德拉邦特', 70 | scenarist: '弗兰克·德拉邦特 / 斯蒂芬·金', 71 | star: '蒂姆·罗宾斯 / 摩根·弗里曼 / 鲍勃·冈顿 / 威廉姆·赛德勒 / 克兰西·布朗 / 吉尔·贝罗斯 / 马克·罗斯顿 / 詹姆斯·惠特摩 / 杰弗里·德曼 / 拉里·布兰登伯格 / 尼尔·吉恩托利 / 布赖恩·利比 / 大卫·普罗瓦尔 / 约瑟夫·劳格诺 / 祖德·塞克利拉 / 保罗·麦克兰尼 / 芮妮·布莱恩 / 阿方索·弗里曼 / V·J·福斯特 / 弗兰克·梅德拉诺 / 马克·迈尔斯 / 尼尔·萨默斯 / 耐德·巴拉米 / 布赖恩·戴拉特 / 唐·麦克马纳斯', 72 | type: '剧情 / 犯罪', 73 | productionCountry: '美国', 74 | language: '英语', 75 | releaseDate: '1994-09-10(多伦多电影节) / 1994-10-14(美国)', 76 | filmLength: '142分钟', 77 | alias: '月黑高飞(港) / 刺激1995(台) / 地狱诺言 / 铁窗岁月 / 消香克的救赎', 78 | score: 5, 79 | }, 80 | } 81 | ]; 82 | ``` 83 | 84 | 请按照此格式配置,无内容可以不配置。 85 | 86 | | **Key** | **Description** | 87 | | :---------------------- | :---------------- | 88 | | **title** | 标题,可以不填 | 89 | | **books** | 书籍/电影数据 | 90 | | **books.cover** | 书籍/影片封面 | 91 | | **books.name** | 书名/影名 | 92 | | **books.formerName** | 原书名 | 93 | | **books.author** | 作者 | 94 | | **books.translator** | 译者 | 95 | | **books.press** | 出版社 | 96 | | **books.year** | 出版年 | 97 | | **books.score** | 评级1~5,支持.5 | 98 | | **books.readDate** | 阅读日期 | 99 | | **books.readPercentage** | 阅读进度 | 100 | | **books.direct** | 电影导演 | 101 | | **books.scenarist** | 电影编剧 | 102 | | **books.star** | 电影主演 | 103 | | **books.type** | 电影类型 | 104 | | **books.productionCountry** | 电影制片国家/地区 | 105 | | **books.language** | 电影语言 | 106 | | **books.releaseDate** | 电影上映日期 | 107 | | **books.filmLength** | 电影片长 | 108 | | **books.alias** | 电影别名 | -------------------------------------------------------------------------------- /docs/v2/src/reference/fonticon.md: -------------------------------------------------------------------------------- 1 | # 字体图标库 2 | 3 | 本主题使用的图标库为阿里巴巴矢量图标库 [iconfont](https://www.iconfont.cn/)。 4 | 5 | ## 拓展图标 6 | 7 | 大家可以在 iconfont 生成自己的图标库,生成方法参考[官方教程](https://www.iconfont.cn/help/detail?spm=a313x.7781069.1998910419.13&helptype=about)。 8 | 9 | 获取样式地址后按照下面示例方式添加到配置中 10 | 11 | ::: danger 注意 12 | 拓展图标库需要修改 FontClass/ Symbol 前缀,不能使用默认的 "icon-" 13 | ::: 14 | 15 | ```javascript 16 | window.cnblogsConfig = { 17 | fontIconExtend: "//at.alicdn.com/t/font_xxxxxxxxx.css", 18 | } 19 | ``` 20 | 21 | ### 使用教程 22 | 23 | 比如说在侧边栏配置中,这时候就可以愉快的使用自己拓展图标的图标进行配置了 24 | 25 | ``` 26 | window.cnblogsConfig = { 27 | sidebar: { // 列表数据 ['导航名称', '链接', 'icon'] 28 | navList: [ 29 | {text: "随笔", link:'https://i.cnblogs.com/posts/edit', icon: 'x-icon-brush-fill'}, 30 | ], 31 | }, 32 | } 33 | ``` 34 | 35 | ## 内置图标 36 | 37 | ::: tip 提示 38 | 内置图标分为基本图标和文章图标,两者加载的文件和位置均不同; 39 | ::: 40 | 41 | ### 基本图标 42 | 43 | 用于主题基本图标的配置,默认以CSS方式进行加载,主题初始化时就会加载; 44 | 45 | [预览页面>>](https://bndong.github.io/Cnblogs-Theme-SimpleMemory/v2/iconfontDemo/demo_index.html) 46 | 47 | 54 | 55 | ### 文章标题图标 56 | 57 | 用于文章标题前的修饰,以 JS 方式进行加载,开启相应的配置后只会在文章页进行加载; 58 | 59 | [预览页面>>](https://bndong.github.io/Cnblogs-Theme-SimpleMemory/v2/iconfontDemo/posts_index.html) 60 | 61 | -------------------------------------------------------------------------------- /docs/v2/src/reference/hook.md: -------------------------------------------------------------------------------- 1 | # 钩子 2 | 3 | 用于用户在插件处理周期中扩展自己的行为。 4 | 5 | ## 配置方式 6 | 7 | 示例配置: 8 | 9 | ```javascript 10 | 11 | window.cnblogsConfig = { 12 | // ... 主配置 13 | }; 14 | 15 | // 钩子配置 16 | window.cnblogsConfig.hooks = { 17 | 18 | beforeCode: (_) => { 19 | // console.log('code 渲染开始前'); 20 | }, 21 | afterCode: (_) => { 22 | // console.log('code 渲染结束后'); 23 | }, 24 | beforeLoading: (_) => { 25 | // console.log('loading 开始前'); 26 | }, 27 | afterLoading: (_) => { 28 | // console.log('loading 结束后'); 29 | }, 30 | dayNightControl: (_, type) => { 31 | // console.log(type); 32 | // console.log('日/夜间模式'); 33 | }, 34 | }; 35 | 36 | ``` 37 | 38 | ## 钩子方法 39 | 40 | | **方法** | **参数** | **描述** | 41 | | :-----------------: | :------: | :-----------------------: | 42 | | **beforeCode** | _ | code 渲染开始前调用此方法 | 43 | | **afterCode** | _ | code 渲染结束后调用此方法 | 44 | | **beforeLoading** | _ | loading 开始前调用此方法 | 45 | | **afterLoading** | _ | loading 结束后调用此方法 | 46 | | **dayNightControl** | _, type | 日/夜间模式切换调用此方法 | 47 | 48 | ## 关于参数 "_" 49 | 50 | 里面包含了插件渲染使用的配置、工具方法、页面状态、事件监听等。 51 | 52 | ### 查看/修改配置 53 | 54 | 当前插件渲染使用的配置都在 `$.__config` 中,可以查看当前配置,也可以直接修改使用的配置。 55 | 56 | ### 调用插件公共方法 57 | 58 | 当前插件公共方法都在 `$.__tools` 中,关于所有的公共方法可查看[此文件](https://github.com/wangyang0210/cnblogs-theme/blob/v2/src/utils/tools.js) 59 | 60 | ### 查看页面状态信息 61 | 62 | 当前插件渲染使用的配置都在 `$.__status` 中。 63 | 64 | ### 查看/触发事件 65 | 66 | 当前插件公共事件处理都在 `$.__event` 中,目前只有滚动事件和窗口大小事件的监听处理,源码可参考[此文件](https://github.com/wangyang0210/cnblogs-theme/blob/v2/src/components/event/event.js)。 67 | 68 | * 触发事件 69 | 70 | 只能触发已经注册的事件,根据插件加载,会陆续注册进来新的事件处理 handle。 71 | 72 | 示例: 73 | 74 | ```javascript 75 | $.__event.handle.scroll(); // 触发滚动处理 76 | $.__event.handle.resize(); // 触发窗口大小变化处理 77 | ``` 78 | 79 | * 添加新的事件处理 80 | 81 | 示例: 82 | 83 | ```javascript 84 | $.__event.scroll.handle.push(() => { 85 | console.log('当页面滚动时,我被执行!'); 86 | }); 87 | ``` 88 | -------------------------------------------------------------------------------- /docs/v2/src/reference/links.md: -------------------------------------------------------------------------------- 1 | # 友链页 2 | 3 | 样式参考:[友联预览](https://www.cnblogs.com/wangyang1225/p/18614782) 4 | 5 | ## 配置方式 6 | 7 | ### 标识页面为友链页面 8 | 9 | 首先需要在页面源码中加入以下代码,来标识该页面为友链页面: 10 | 11 | ```html 12 | 13 | ``` 14 | 15 | ::: danger 注意 16 | 是添加到 HTML 源码中,博客园文章的富文本编辑器和 Markdown 都有添加 HTML 代码的方式! 17 | ::: 18 | 19 | #### 富文本编辑器 20 | 21 | ![img](https://pic.imgdb.cn/item/676df60dd0e0a243d4eb1989.png) 22 | 23 | #### Markdown 24 | 25 | 直接拷贝到文本即可。 26 | 27 | ### 配置友链数据 28 | 29 | 友链的配置,可以参考其他[配置](/reference/configs)的方式。例如: 30 | 31 | ```javascript 32 | window.cnblogsConfig = [ 33 | links: { 34 | page: [ 35 | { 36 | title: '友情链接', // 标题 37 | icon: 'icon-lianjie', // iconfont 38 | style: 'color: #a78bfa;', 39 | links: [ 40 | { 41 | name: '。思索', // 昵称 42 | introduction: 'IT技术类博客', // 简介 43 | avatar: 'https://pic.cnblogs.com/face/1334215/20180504110551.png', // 头像 44 | url: 'https://cnblogs.com/wangyang0210' // 友链地址 45 | }, 46 | ] 47 | }, 48 | ] 49 | } 50 | ]; 51 | ``` 52 | 53 | 此配置可以单独出来。例如: 54 | 55 | ```javascript 56 | 57 | // 正常配置 58 | window.cnblogsConfig = { 59 | links: {}, 60 | }; 61 | 62 | // 友链页配置 63 | window.cnblogsConfig.links.page = [ 64 | { 65 | title: '友情链接', // 标题 66 | icon: 'icon-lianjie', // iconfont 67 | style: 'color: #a78bfa;', 68 | links: [ 69 | { 70 | name: '。思索', // 昵称 71 | introduction: 'IT技术类博客', // 简介 72 | avatar: 'https://pic.cnblogs.com/face/1334215/20180504110551.png', // 头像 73 | url: 'https://cnblogs.com/wangyang0210' // 友链地址 74 | }, 75 | ] 76 | }, 77 | ]; 78 | ``` 79 | 80 | 请按照此格式配置。 81 | 82 | | **Key** | **Description** | 83 | | :------------------------------- | :-------------- | 84 | | **title** | 友链标题 | 85 | | **icon** | 标题图标 | 86 | | **style** | 标题扩展样式 | 87 | | **links** | 标题下友链配置 | 88 | | **links[n].name** | 昵称 | 89 | | **links[n].introduction** | 简介 | 90 | | **links[n].avatar** | 头像 | 91 | | **links[n].url** | 友链地址 | -------------------------------------------------------------------------------- /docs/v2/src/reference/loading.md: -------------------------------------------------------------------------------- 1 | # Loading 2 | 3 | Loading 使用开源项目:[claudiocalautti/spring-loaders](https://github.com/claudiocalautti/spring-loaders) 4 | 5 | 大家可以根据该项目文档修改 `window.cnblogsConfig.loading` 的配置。 6 | 7 | ### 关于网页快照显示空白页 8 | 9 | ::: info 信息 10 | 此方案由网友 [蓝天上的云℡](https://www.cnblogs.com/yucloud/) 提供。 11 | ::: 12 | 13 | ::: danger 注意 14 | 应用此方案,会导致进入网页有闪屏的现象,大家自己权衡使用。 15 | ::: 16 | 17 | 在页首 HTML 里添加 18 | 19 | ```html 20 | 24 | ``` 25 | 26 | 即可关闭 Loading,然后在侧边栏公告JS的顶部里添加 27 | 28 | ```html 29 | 35 | ``` -------------------------------------------------------------------------------- /docs/v2/src/reference/reprinted.md: -------------------------------------------------------------------------------- 1 | # 转载文章 2 | 3 | 关于转载文章在 HTML 源码中加入如下代码来指定文章作者和来源: 4 | 5 | ```html 6 | 7 | 8 | ``` 9 | 10 | ::: danger 注意 11 | 是添加到 HTML 源码中,博客园文章的富文本编辑器和 Markdown 都有添加 HTML 代码的方式! 12 | ::: 13 | 14 | ## 富文本编辑器 15 | 16 | ![img](https://pic.imgdb.cn/item/676df60dd0e0a243d4eb1989.png) 17 | 18 | ## Markdown 19 | 20 | 直接拷贝到文本即可。 -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cnblogs-theme", 3 | "version": "2.2.18", 4 | "description": "
", 5 | "main": "index.js", 6 | "files": [ 7 | "src", 8 | "dist" 9 | ], 10 | "directories": { 11 | "doc": "docs" 12 | }, 13 | "scripts": { 14 | "test": "echo \"Error: no test specified\" && exit 1", 15 | "dev": "npx webpack --config config/webpack.dev.js", 16 | "build": "npx webpack --config config/webpack.prod.js && npx postcss ./src/style/simple-memory.css > ./dist/simple-memory.css", 17 | "analyz": "npx webpack --config config/webpack.dev.js && npx webpack-bundle-analyzer", 18 | "docs:build": "vitepress build docs/v2", 19 | "docs:preview": "vitepress preview docs/v2", 20 | "docs:dev": "vitepress dev docs/v2" 21 | }, 22 | "repository": { 23 | "type": "git", 24 | "url": "git+https://github.com/wangyang0210/cnblogs-theme.git" 25 | }, 26 | "keywords": [], 27 | "author": "wangyang0210", 28 | "license": "ISC", 29 | "bugs": { 30 | "url": "https://github.com/wangyang0210/cnblogs-theme/issues" 31 | }, 32 | "homepage": "https://github.com/wangyang0210/cnblogs-theme#readme", 33 | "devDependencies": { 34 | "@popperjs/core": "^2.11.8", 35 | "compression-webpack-plugin": "^10.0.0", 36 | "css-loader": "^5.2.7", 37 | "css-minimizer-webpack-plugin": "^5.0.1", 38 | "cssnano": "^6.1.2", 39 | "cssnano-preset-advanced": "^5.3.10", 40 | "exports-loader": "^2.0.0", 41 | "filemanager-webpack-plugin": "^7.0.0", 42 | "html-loader": "^2.1.2", 43 | "html-webpack-plugin": "^5.6.3", 44 | "imports-loader": "^2.0.0", 45 | "json5": "^2.2.3", 46 | "mini-css-extract-plugin": "^1.6.2", 47 | "postcss": "^8.4.49", 48 | "postcss-cli": "^10.1.0", 49 | "style-loader": "^2.0.0", 50 | "toml": "^3.0.0", 51 | "vitepress": "^1.5.0", 52 | "webpack": "^5.97.1", 53 | "webpack-bundle-analyzer": "^4.10.2", 54 | "webpack-cli": "^4.10.0", 55 | "webpack-dev-server": "^4.15.2", 56 | "webpack-merge": "^5.10.0" 57 | }, 58 | "browserslist": { 59 | "development": [ 60 | "last 1 chrome version", 61 | "last 1 firefox version", 62 | "last 1 safari version" 63 | ], 64 | "production": [ 65 | ">0.2%", 66 | "not dead", 67 | "nop op_mini all" 68 | ] 69 | }, 70 | "dependencies": { 71 | "markdown-it-task-lists": "^2.1.1" 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | require('cssnano')({ 4 | preset: ['default', { 5 | discardComments: { 6 | removeAll: true, 7 | }, 8 | }] 9 | }), 10 | ], 11 | }; 12 | -------------------------------------------------------------------------------- /src/components/articleDirectory/articleDirectory.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-08-25 15:18 6 | * ---------------------------------------------- 7 | * @describe: 文章目录处理 8 | */ 9 | import '../../style/articleDirectory.css'; 10 | import articleDirectoryTemp from '../../template/articleDirectory.html'; 11 | await $.__tools.dynamicLoadingJs($.__config.default.bootstrap).catch((e) => console.error('bootstrap.js', e)); 12 | export default function main() { 13 | let body = $('body'); 14 | let postBody = $('#cnblogs_post_body'); 15 | let header = postBody.find(':header'); 16 | 17 | if (header.length) { 18 | const tagList = header.map((index, element) => parseInt(element.tagName.replace(/H/g, ''))).get(); 19 | const html = header 20 | .map((index, element) => { 21 | const obj = $(element); 22 | const h = parseInt(obj[0].tagName.replace(/H/g, '')); 23 | let hid = obj.attr('id'); 24 | const titleId = `tid-${$.__tools.randomString(6)}`; 25 | obj.attr('tid', titleId); 26 | if (!hid || /^[\W|\d]+.*/.test(hid)) { 27 | if (hid) { 28 | const tocObj = $(`.toc a[href="#${hid}"]`); 29 | tocObj.length && tocObj.attr('href', `#${titleId}`); 30 | } 31 | hid = titleId; 32 | obj.attr('id', hid); 33 | } 34 | 35 | const num = [...new Set(tagList)].sort().indexOf(h); 36 | const str = num === 0 || num === -1 ? '' : '    '.repeat(num); 37 | const text = str + obj.text().replace(//g, '>'); 38 | return ``; 39 | }) 40 | .get() 41 | .join(''); 42 | 43 | let dirHtml = $.__tools.tempReplacement(articleDirectoryTemp, 'dirHtml', html); 44 | postBody.append(dirHtml); 45 | 46 | body.attr('data-bs-spy', 'scroll'); 47 | body.attr('data-bs-target', '#articleDirectory'); 48 | body.attr('data-bs-offset', '0'); 49 | body.attr('tabindex', '0'); 50 | body.scrollspy({ target: '#articleDirectory' }); 51 | 52 | if (!$.__config.articleDirectory.autoWidthScroll) { 53 | $('#articleDirectory ul li').addClass('articleDirectory-overflow'); 54 | $('#articleDirectory ul li a').addClass('articleDirectory-overflow'); 55 | } 56 | 57 | $.__event.scroll.handle.push(() => { 58 | let articleDirectory = $('#articleDirectory'); 59 | if ( 60 | $.__event.scroll.temScroll < $.__event.scroll.docScroll && 61 | $.__event.scroll.homeScroll <= $.__event.scroll.docScroll 62 | ) { 63 | articleDirectory.addClass('articleDirectoryFixed'); 64 | } 65 | 66 | if ( 67 | $.__event.scroll.temScroll > $.__event.scroll.docScroll && 68 | $.__event.scroll.homeScroll >= $.__event.scroll.docScroll 69 | ) { 70 | articleDirectory.removeClass('articleDirectoryFixed'); 71 | } 72 | }); 73 | 74 | $.__event.resize.handle.push(() => { 75 | const bodyWidth = parseFloat(document.body.clientWidth), 76 | articleDirectory = $('#articleDirectory'); 77 | if (articleDirectory.length > 0) { 78 | let mainContentWidth = $('#home').outerWidth(false), 79 | listWidth = articleDirectory.outerWidth(true); 80 | let bothWidth = (bodyWidth - mainContentWidth) / 2, 81 | rightPx = bothWidth - listWidth - 5, 82 | sideToolbarTop = $('.main-header').outerHeight(); 83 | 84 | switch ($.__config.articleDirectory.position) { 85 | case 'left': 86 | articleDirectory.css({ 87 | top: sideToolbarTop + 5 + 'px', 88 | left: (rightPx > 0 ? rightPx : 5) + 'px', 89 | width: (bothWidth > 190 && bothWidth < 260 ? bothWidth - 10 : listWidth) + 'px', 90 | }); 91 | break; 92 | case 'right': 93 | default: 94 | articleDirectory.css({ 95 | top: sideToolbarTop + 5 + 'px', 96 | right: (rightPx > 0 ? rightPx : 5) + 'px', 97 | width: (bothWidth > 190 && bothWidth < 260 ? bothWidth - 10 : listWidth) + 'px', 98 | }); 99 | break; 100 | } 101 | 102 | if (bodyWidth <= $.__config.articleDirectory.minBodyWeight || bothWidth <= 190) { 103 | articleDirectory.hide(); 104 | } else { 105 | articleDirectory.show(); 106 | } 107 | } 108 | }); 109 | 110 | $('#articleDirectory .nav-link').click(function () { 111 | let titleH = $(`:header[tid="${$(this).attr('goto')}"]`); 112 | titleH.length && $.__tools.actScroll(titleH.offset().top + 3, 500); 113 | }); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/components/articleSuffix/articleSuffix.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-08-25 15:18 6 | * ---------------------------------------------- 7 | * @describe: 文章后缀处理 8 | */ 9 | import '../../style/articleSuffix.css'; 10 | import suffixTemp from '../../template/articleSuffix.html'; 11 | 12 | export default function main() { 13 | // 图片 14 | let imgUrl = $.__config.articleSuffix.imgUrl ? $.__config.articleSuffix.imgUrl : $.__config.info.avatar ? $.__config.info.avatar : $.__config.default.avatar; 15 | 16 | // 本文作者 & 本文链接 17 | const articleAuthor = $('#articleAuthor'); 18 | const articleSource = $('#articleSource'); 19 | const author = articleAuthor?.val() || $.__config.info.name; 20 | const source = articleSource?.val() || $.__status.url; 21 | const homeUrl = articleSource?.val() || $.__status.homeUrl; 22 | const origin = articleSource.length ? '原' : '本'; 23 | 24 | let aboutHtml = $.__config.articleSuffix.aboutHtml || `评论和私信会在第一时间回复。或者直接私信我。`; 25 | 26 | // 版权声明 27 | let copyrightHtml = 28 | $.__config.articleSuffix.copyrightHtml || 29 | `本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!`; 30 | 31 | // 声援博主 32 | let supportHtml = 33 | $.__config.articleSuffix.supportHtml || 34 | `如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。`; 35 | 36 | let re = [ 37 | ['origin', origin], 38 | ['imgUrl', imgUrl], 39 | ['homeUrl', homeUrl], 40 | ['author', author], 41 | ['source', source], 42 | ['aboutHtml', aboutHtml], 43 | ['copyrightHtml', copyrightHtml], 44 | ['supportHtml', supportHtml], 45 | ]; 46 | let suffixHtml = $.__tools.batchTempReplacement(suffixTemp, re); 47 | $('#cnblogs_post_body').append(suffixHtml); 48 | 49 | // 版权声明 - COPY 50 | const config = $.__config.articleSuffix.copyInfo; 51 | const { enable, length, copyright = copyrightHtml } = config; 52 | 53 | if (enable) { 54 | const separator = '———————————————————————————————————————————————'; 55 | const newline = '\n'; 56 | const htmlSeparator = `
\n${separator}
\n`; 57 | 58 | document.body.addEventListener('copy', (event) => { 59 | const selection = window.getSelection().toString(); 60 | if (selection && selection.length > length) { 61 | event.preventDefault(); 62 | const clipboardData = event.clipboardData || window.clipboardData; 63 | 64 | if (clipboardData) { 65 | const cleanedCopyright = copyright.replace(/<\/?.+?>/g, '').replace(/ /g, ''); 66 | const htmlData = `${selection}${htmlSeparator}${copyright}
\n作者:${author}
\n原文链接:${source}
\n`; 67 | const textData = `${selection}${newline}${separator}${newline}${cleanedCopyright}${newline}作者:${author}${newline}原文链接:${source}${newline}`; 68 | 69 | clipboardData.setData('text/html', htmlData); 70 | clipboardData.setData('text/plain', textData); 71 | } 72 | } 73 | }); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/components/background/particles.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-08-25 15:23 6 | * ---------------------------------------------- 7 | * @describe: 背景鼠标滚动动画 8 | */ 9 | import particlesTemp from '../../template/particles.html'; 10 | import '../../style/particles.css'; 11 | await $.__tools.dynamicLoadingJs($.__config.default.gsap).catch((e) => console.error('gsap.js', e)); 12 | export default function main(options) { 13 | $('#footer').after(particlesTemp); 14 | let wrapper = document.getElementById('particles'), 15 | ela = wrapper.querySelector('.particles-layer--1'), 16 | elb = wrapper.querySelector('.particles-layer--2'), 17 | elc = wrapper.querySelector('.particles-layer--3'), 18 | particlesList = [ 19 | { el: ela, opacity: 0.07, speed: 0.06 }, 20 | { el: elb, opacity: 0.07, speed: 0.04 }, 21 | { el: elc, opacity: 0.07, speed: 0.05 }, 22 | ]; 23 | particlesList.forEach((l) => { 24 | gsap.to(l.el, 0.6, { delay: Math.random(), opacity: l.opacity }); 25 | }); 26 | document.addEventListener('mousemove', particlesMousemove); 27 | function particlesMousemove(t) { 28 | let e = { x: window.innerWidth / 2, y: window.innerHeight / 2 }, 29 | n = { x: t.clientX || t.pageX, y: t.clientY || t.pageY }, 30 | r = { x: e.x - n.x, y: e.y - n.y }; 31 | particlesList.forEach((l) => { 32 | gsap.to(l.el, 1, { x: r.x * l.speed, y: r.y * l.speed }); 33 | }); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/components/background/season.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-09-03 01:18 6 | * ---------------------------------------------- 7 | * @describe: 可以自定义下落物品的背景特效 8 | */ 9 | 10 | export default function main(options) { 11 | let SakuraList; 12 | let img = new Image(); 13 | img.src = options.img; 14 | let size = options.size; 15 | 16 | function Sakura(x, y, s, r, fn) { 17 | this.x = x; 18 | this.y = y; 19 | this.s = s; 20 | this.r = r; 21 | this.fn = fn; 22 | } 23 | 24 | Sakura.prototype.draw = function (cxt) { 25 | cxt.save(); 26 | cxt.translate(this.x, this.y); 27 | cxt.rotate(this.r); 28 | cxt.drawImage(img, 0, 0, size * this.s, size * this.s); 29 | cxt.restore(); 30 | }; 31 | Sakura.prototype.update = function () { 32 | this.x = this.fn.x(this.x, this.y); 33 | this.y = this.fn.y(this.y, this.y); 34 | this.r = this.fn.r(this.r); 35 | if (this.x > window.innerWidth || this.x < 0 || this.y > window.innerHeight || this.y < 0) { 36 | this.r = getRandom('fnr'); 37 | if (Math.random() > 0.4) { 38 | this.x = getRandom('x'); 39 | this.y = 0; 40 | this.s = getRandom('s'); 41 | this.r = getRandom('r'); 42 | } else { 43 | this.x = window.innerWidth; 44 | this.y = getRandom('y'); 45 | this.s = getRandom('s'); 46 | this.r = getRandom('r'); 47 | } 48 | } 49 | }; 50 | 51 | SakuraList = function () { 52 | this.list = []; 53 | }; 54 | SakuraList.prototype.push = function (sakura) { 55 | this.list.push(sakura); 56 | }; 57 | SakuraList.prototype.update = function () { 58 | for (let i = 0, len = this.list.length; i < len; i++) { 59 | this.list[i].update(); 60 | } 61 | }; 62 | SakuraList.prototype.draw = function (cxt) { 63 | for (let i = 0, len = this.list.length; i < len; i++) { 64 | this.list[i].draw(cxt); 65 | } 66 | }; 67 | SakuraList.prototype.get = function (i) { 68 | return this.list[i]; 69 | }; 70 | SakuraList.prototype.size = function () { 71 | return this.list.length; 72 | }; 73 | 74 | function getRandom(option) { 75 | let ret, random; 76 | switch (option) { 77 | case 'x': 78 | ret = Math.random() * window.innerWidth; 79 | break; 80 | case 'y': 81 | ret = Math.random() * window.innerHeight; 82 | break; 83 | case 's': 84 | ret = Math.random(); 85 | break; 86 | case 'r': 87 | ret = Math.random() * 6; 88 | break; 89 | case 'fnx': 90 | random = -0.5 + Math.random(); 91 | ret = function (x, y) { 92 | return x + 0.5 * random - 1.7; 93 | }; 94 | break; 95 | case 'fny': 96 | random = 1.5 + Math.random() * 0.7; 97 | ret = function (x, y) { 98 | return y + random; 99 | }; 100 | break; 101 | case 'fnr': 102 | random = Math.random() * 0.03; 103 | ret = function (r) { 104 | return r + random; 105 | }; 106 | break; 107 | } 108 | return ret; 109 | } 110 | 111 | function startSakura() { 112 | requestAnimationFrame = 113 | window.requestAnimationFrame || 114 | window.mozRequestAnimationFrame || 115 | window.webkitRequestAnimationFrame || 116 | window.msRequestAnimationFrame || 117 | window.oRequestAnimationFrame; 118 | let canvas = document.createElement('canvas'), 119 | cxt; 120 | canvas.height = window.innerHeight; 121 | canvas.width = window.innerWidth; 122 | canvas.setAttribute('style', 'position: fixed;left: 0;top: 0;pointer-events: none;'); 123 | canvas.setAttribute('id', 'canvas_sakura'); 124 | canvas.style.zIndex = '999999999999999999999999999999999999999999'; 125 | document.getElementsByTagName('body')[0].appendChild(canvas); 126 | cxt = canvas.getContext('2d'); 127 | let sakuraList = new SakuraList(); 128 | for (let i = 0; i < 50; i++) { 129 | let sakura, randomX, randomY, randomS, randomR, randomFnx, randomFny, randomFnR; 130 | randomX = getRandom('x'); 131 | randomY = getRandom('y'); 132 | randomR = getRandom('r'); 133 | randomS = getRandom('s'); 134 | randomFnx = getRandom('fnx'); 135 | randomFny = getRandom('fny'); 136 | randomFnR = getRandom('fnr'); 137 | sakura = new Sakura(randomX, randomY, randomS, randomR, { 138 | x: randomFnx, 139 | y: randomFny, 140 | r: randomFnR, 141 | }); 142 | sakura.draw(cxt); 143 | sakuraList.push(sakura); 144 | } 145 | requestAnimationFrame(function fn() { 146 | cxt.clearRect(0, 0, canvas.width, canvas.height); 147 | sakuraList.update(); 148 | sakuraList.draw(cxt); 149 | requestAnimationFrame(fn); 150 | }); 151 | } 152 | 153 | img.onload = function () { 154 | startSakura(); 155 | }; 156 | } 157 | -------------------------------------------------------------------------------- /src/components/banner/banner.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-08-25 15:19 6 | * ---------------------------------------------- 7 | * @describe: banner背景图片处理 8 | */ 9 | import bannerTemp from '../../template/banner.html'; 10 | 11 | export default function main() { 12 | $('#sidebar_news').prepend(bannerTemp); 13 | 14 | /** 15 | * 设置banner背景图片,初始化高度 16 | * (该处理需在loading结束之前处理) 17 | */ 18 | (() => { 19 | let mainHeader = $('#main-header'); 20 | let topImg, bgImg, height; 21 | 22 | // 设置图片 23 | if ($.__status.pageType === 'home') { 24 | topImg = $.__config.banner.home.background.length 25 | ? $.__config.banner.home.background 26 | : ['https://images.cnblogs.com/cnblogs_com/wangyang0210/1943283/o_220917053600_wallhaven-6k3oox.webp']; 27 | } else { 28 | topImg = $.__config.banner.article.background.length 29 | ? $.__config.banner.article.background 30 | : ['https://images.cnblogs.com/cnblogs_com/wangyang0210/1943283/o_220917053937_wallhaven-j5mz95.webp']; 31 | height = '40vh'; 32 | $('#homeTopTitle').hide(); 33 | $('.scroll-down').hide(); 34 | $('#home').css('margin-top', '40vh'); 35 | $('#cb_post_title_url').addClass('post-del-title'); 36 | } 37 | 38 | // 设置高度 39 | if (height) mainHeader.css('height', height); 40 | 41 | // banner动效 42 | if ($.__config.animate.bannerImages?.enable) { 43 | // 开启图片自动切换 44 | import( 45 | /* webpackChunkName: "banner-images" */ /* webpackPrefetch: true */ '../bannerImages/bannerImages' 46 | ).then((module) => { 47 | let bannerImages = module.default; 48 | bannerImages( 49 | 'main-header', 50 | topImg, 51 | $.__config.animate.bannerImages.options.itemNum, 52 | $.__config.animate.bannerImages.options.time, 53 | $.__config.animate.bannerImages.options.sort, 54 | $.__config.animate.bannerImages.options.current < 0 55 | ? $.__tools.randomNum(0, topImg.length - 1) 56 | : $.__config.animate.bannerImages.options.current 57 | ); 58 | }); 59 | } else { 60 | // 随机指定一个图片 61 | if (topImg.length > 1) bgImg = topImg[$.__tools.randomNum(0, topImg.length - 1)]; 62 | else bgImg = topImg[0] || ''; 63 | 64 | mainHeader.css({ 65 | background: `#222 url("${encodeURI(bgImg)}") center center no-repeat`, 66 | 'background-size': 'cover', 67 | }); 68 | } 69 | 70 | // Banner文字是否可选 71 | if (!$.__config.banner.titleSelect) $('.main-header-content.inner').addClass('textUnselect'); 72 | })(); 73 | 74 | // 添加事件监听 75 | $.__event.scroll.handle.push(() => { 76 | const openButton = $('#open-button'); 77 | const { temScroll, docScroll, homeScroll } = $.__event.scroll; 78 | const isScrolledDown = temScroll < docScroll && homeScroll <= docScroll; 79 | const isScrolledUp = temScroll > docScroll && homeScroll >= docScroll; 80 | const shouldToggleClass = openButton.hasClass('menu-button-scroll'); 81 | 82 | // 根据滚动方向和当前状态切换按钮样式 83 | if ((isScrolledDown && !shouldToggleClass) || (isScrolledUp && shouldToggleClass)) { 84 | openButton.toggleClass('menu-button-scroll', isScrolledDown).text(isScrolledDown ? '' : 'MENU'); 85 | } 86 | }); 87 | } 88 | -------------------------------------------------------------------------------- /src/components/bannerImages/bannerImages.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-08-25 15:19 6 | * ---------------------------------------------- 7 | * @describe: banner背景切换处理 8 | */ 9 | 10 | await $.__tools.dynamicLoadingJs($.__config.default.gsap).catch((e) => console.error('gsap.js', e)); 11 | export default function main(id, images, cols, time, sort, current) { 12 | const bgMain = document.getElementById(id); 13 | const parts = []; 14 | let playing = false; 15 | const animOptions = { duration: 2.3, ease: Power4.easeInOut }; 16 | 17 | images.forEach((src) => { 18 | const img = new Image(); 19 | img.src = src; 20 | }); 21 | 22 | for (let col = 0; col < cols; col++) { 23 | const part = document.createElement('div'); 24 | part.className = 'part'; 25 | const el = document.createElement('div'); 26 | el.className = 'section'; 27 | const img = document.createElement('img'); 28 | img.src = images[current]; 29 | el.appendChild(img); 30 | part.style.setProperty('--x', `${(-100 / cols) * col}vw`); 31 | part.appendChild(el); 32 | bgMain.appendChild(part); 33 | parts.push(part); 34 | } 35 | 36 | function go(dir) { 37 | if (playing) return; 38 | playing = true; 39 | current = (current + dir + images.length) % images.length; 40 | const bgMainHeight = bgMain.offsetHeight; 41 | parts.forEach((part, p) => { 42 | const next = document.createElement('div'); 43 | next.className = 'section'; 44 | const img = document.createElement('img'); 45 | img.src = images[current]; 46 | next.appendChild(img); 47 | 48 | if ((p - Math.max(0, dir)) % 2 === 0) up(part, next, bgMainHeight); 49 | else down(part, next, bgMainHeight); 50 | }); 51 | } 52 | 53 | function up(part, next, height) { 54 | part.appendChild(next); 55 | gsap.to(part, { ...animOptions, y: -height }).then(() => { 56 | part.children[0].remove(); 57 | gsap.to(part, { duration: 0, y: 0 }); 58 | playing = false; 59 | }); 60 | } 61 | 62 | function down(part, next, height) { 63 | part.prepend(next); 64 | gsap.to(part, { duration: 0, y: -height }); 65 | gsap.to(part, { ...animOptions, y: 0 }).then(() => { 66 | part.children[1].remove(); 67 | playing = false; 68 | }); 69 | } 70 | 71 | setInterval(() => go(sort), time); 72 | } 73 | -------------------------------------------------------------------------------- /src/components/blogIcon/blogIcon.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-08-25 15:19 6 | * ---------------------------------------------- 7 | * @describe: 网站图标处理 8 | */ 9 | export default function main() { 10 | const shortcutIcon = $('#favicon'); 11 | if ($.__config.info.blogIcon && shortcutIcon.length) shortcutIcon.attr('href', $.__config.info.blogIcon); 12 | if ($.__config.info.blogIcon && !shortcutIcon.length) { 13 | let linkObject = document.createElement('link'); 14 | linkObject.rel = 'shortcut icon'; 15 | linkObject.href = $.__config.info.blogIcon; 16 | document.getElementsByTagName('head')[0].appendChild(linkObject); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/components/comment/comment.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-08-25 15:20 6 | * ---------------------------------------------- 7 | * @describe: 评论处理 8 | */ 9 | 10 | export default function main() { 11 | // 评论框打字特效 12 | if ($.__config.articleContent.commentTyping.enable) { 13 | const POWERMODE = require('./commentTyping/commentTyping'); 14 | POWERMODE.colorful = $.__config.articleContent.commentTyping.options.colorful; 15 | POWERMODE.shake = $.__config.articleContent.commentTyping.options.shake; 16 | document.body.addEventListener('input', POWERMODE); 17 | } 18 | 19 | let setComment = () => { 20 | let feedbackItem = $('.feedbackItem'); 21 | if (feedbackItem.length) { 22 | $.each(feedbackItem, (i) => { 23 | let obj = $(feedbackItem[i]), 24 | feedbackCon = obj.find('.feedbackCon'), 25 | feedbackListSubtitle = obj.find('.feedbackListSubtitle'), 26 | commentBody = feedbackCon.length ? feedbackCon.find('.blog_comment_body') : [], 27 | avatarHtml = '', 28 | idInfo = commentBody.length ? commentBody.attr('id').split('_') : undefined; 29 | 30 | if (idInfo && idInfo.length) { 31 | let id = idInfo[idInfo.length - 1], 32 | idTmp = id.toString().match(/\d/g); 33 | 34 | if ($.isArray(idTmp)) id = idTmp.join(''); 35 | let op = $(`#comment_${id}_avatar`), 36 | patch = op.length ? op.text().trim() : $.__config.default.avatar; 37 | 38 | let ac = $(`#a_comment_author_${id}`), 39 | ah = ac.length ? ac.attr('href') : 'javascropt:void(0);'; 40 | 41 | avatarHtml = `
`; 42 | obj.prepend(avatarHtml); 43 | } 44 | 45 | feedbackListSubtitle.length && feedbackListSubtitle.find('.louzhu').length && feedbackListSubtitle.addClass('feedbackListSubtitle-louzhu'); 46 | }); 47 | $(feedbackItem[0]).css('padding-top', '0'); 48 | $(feedbackItem[feedbackItem.length - 1]).css('padding-bottom', '0'); 49 | } 50 | }; 51 | 52 | let addComment = () => { 53 | let userBlogAddress = $('.comment_my_posted a').attr('href'), 54 | userName = $('.comment_my_posted a').text(), 55 | commentInfo = $('.bq_post_comment').text(); 56 | 57 | let comment = `
58 |
59 | 60 | 61 | 62 |
63 |
64 | ${window.isBlogOwner && `[楼主]`} 65 | ${new Date().toLocaleString().replace(/\//g, '-')} 66 | ${userName} 67 |
68 |
69 |
70 |

${commentInfo}

71 |
72 |
73 |
`; 74 | 75 | $('#blog-comments-placeholder').append(comment); 76 | $('.comment_my_posted').remove(); 77 | }; 78 | 79 | $.__timeIds.commentTId = window.setInterval(() => { 80 | if ($('.feedbackItem').length) { 81 | setComment(); 82 | $.__tools.clearIntervalTimeId($.__timeIds.commentTId); 83 | } 84 | }, 1000); 85 | 86 | $(document).ajaxSuccess(function (event, xhr, settings) { 87 | // 评论重新排序 88 | if (settings.url.includes('comments-block')) { 89 | $.__tools.clearIntervalTimeId($.__timeIds.commentTId); 90 | setComment(); 91 | } 92 | 93 | // 新增评论 94 | if (settings.url.includes('PostComment/Add.aspx')) addComment(); 95 | 96 | // 删除评论 97 | if (settings.url.includes('comment/DeleteComment.aspx')) { 98 | let commentId = JSON.parse(settings?.data)?.commentId; 99 | $(`#comment_body_${commentId}`).parent().parent().remove(); 100 | $('.feedbackItem:last').css('padding-bottom', '0'); 101 | } 102 | }); 103 | } 104 | -------------------------------------------------------------------------------- /src/components/comment/commentTyping/commentTyping.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: https://github.com/disjukr/activate-power-mode 5 | * @Date 2023-02-19 12:54 6 | * ---------------------------------------------- 7 | * @describe: POWERMODE 8 | */ 9 | 10 | let canvas = document.createElement('canvas'); 11 | canvas.width = window.innerWidth; 12 | canvas.height = window.innerHeight; 13 | canvas.style.cssText = 'position:fixed;top:0;left:0;pointer-events:none;z-index:999999'; 14 | window.addEventListener('resize', function () { 15 | canvas.width = window.innerWidth; 16 | canvas.height = window.innerHeight; 17 | }); 18 | document.body.appendChild(canvas); 19 | let context = canvas.getContext('2d'); 20 | let particles = []; 21 | let particlePointer = 0; 22 | let rendering = false; 23 | 24 | POWERMODE.shake = true; 25 | 26 | function getRandom(min, max) { 27 | return Math.random() * (max - min) + min; 28 | } 29 | 30 | function getColor(el) { 31 | if (POWERMODE.colorful) { 32 | let u = getRandom(0, 360); 33 | return 'hsla(' + getRandom(u - 10, u + 10) + ', 100%, ' + getRandom(50, 80) + '%, ' + 1 + ')'; 34 | } else { 35 | return window.getComputedStyle(el).color; 36 | } 37 | } 38 | 39 | function getCaret() { 40 | let el = document.activeElement; 41 | let bcr; 42 | if (el.tagName === 'TEXTAREA' || 43 | (el.tagName === 'INPUT' && el.getAttribute('type') === 'text')) { 44 | let offset = require('./textareaCaretPosition')(el, el.selectionEnd); 45 | bcr = el.getBoundingClientRect(); 46 | return { 47 | x: offset.left + bcr.left, 48 | y: offset.top + bcr.top, 49 | color: getColor(el) 50 | }; 51 | } 52 | let selection = window.getSelection(); 53 | if (selection.rangeCount) { 54 | let range = selection.getRangeAt(0); 55 | let startNode = range.startContainer; 56 | if (startNode.nodeType === document.TEXT_NODE) { 57 | startNode = startNode.parentNode; 58 | } 59 | bcr = range.getBoundingClientRect(); 60 | return { 61 | x: bcr.left, 62 | y: bcr.top, 63 | color: getColor(startNode) 64 | }; 65 | } 66 | return { x: 0, y: 0, color: 'transparent' }; 67 | } 68 | 69 | function createParticle(x, y, color) { 70 | return { 71 | x: x, 72 | y: y, 73 | alpha: 1, 74 | color: color, 75 | velocity: { 76 | x: -1 + Math.random() * 2, 77 | y: -3.5 + Math.random() * 2 78 | } 79 | }; 80 | } 81 | 82 | function POWERMODE() { 83 | { // spawn particles 84 | let caret = getCaret(); 85 | let numParticles = 5 + Math.round(Math.random() * 10); 86 | while (numParticles--) { 87 | particles[particlePointer] = createParticle(caret.x, caret.y, caret.color); 88 | particlePointer = (particlePointer + 1) % 500; 89 | } 90 | } 91 | { // shake screen 92 | if (POWERMODE.shake) { 93 | let intensity = 1 + 2 * Math.random(); 94 | let x = intensity * (Math.random() > 0.5 ? -1 : 1); 95 | let y = intensity * (Math.random() > 0.5 ? -1 : 1); 96 | document.body.style.marginLeft = x + 'px'; 97 | document.body.style.marginTop = y + 'px'; 98 | setTimeout(function() { 99 | document.body.style.marginLeft = ''; 100 | document.body.style.marginTop = ''; 101 | }, 75); 102 | } 103 | } 104 | if(!rendering){ 105 | requestAnimationFrame(loop); 106 | } 107 | }; 108 | POWERMODE.colorful = false; 109 | 110 | function loop() { 111 | rendering = true; 112 | context.clearRect(0, 0, canvas.width, canvas.height); 113 | let rendered = false; 114 | let rect = canvas.getBoundingClientRect(); 115 | for (let i = 0; i < particles.length; ++i) { 116 | let particle = particles[i]; 117 | if (particle.alpha <= 0.1) continue; 118 | particle.velocity.y += 0.075; 119 | particle.x += particle.velocity.x; 120 | particle.y += particle.velocity.y; 121 | particle.alpha *= 0.96; 122 | context.globalAlpha = particle.alpha; 123 | context.fillStyle = particle.color; 124 | context.fillRect( 125 | Math.round(particle.x - 1.5) - rect.left, 126 | Math.round(particle.y - 1.5) - rect.top, 127 | 3, 3 128 | ); 129 | rendered = true; 130 | } 131 | if(rendered){ 132 | requestAnimationFrame(loop); 133 | }else{ 134 | rendering = false; 135 | } 136 | } 137 | 138 | module.exports = POWERMODE; 139 | -------------------------------------------------------------------------------- /src/components/comment/commentTyping/textareaCaretPosition.js: -------------------------------------------------------------------------------- 1 | /* jshint browser: true */ 2 | 3 | (function () { 4 | 5 | // The properties that we copy into a mirrored div. 6 | // Note that some browsers, such as Firefox, 7 | // do not concatenate properties, i.e. padding-top, bottom etc. -> padding, 8 | // so we have to do every single property specifically. 9 | var properties = [ 10 | 'direction', // RTL support 11 | 'boxSizing', 12 | 'width', // on Chrome and IE, exclude the scrollbar, so the mirror div wraps exactly as the textarea does 13 | 'height', 14 | 'overflowX', 15 | 'overflowY', // copy the scrollbar for IE 16 | 17 | 'borderTopWidth', 18 | 'borderRightWidth', 19 | 'borderBottomWidth', 20 | 'borderLeftWidth', 21 | 'borderStyle', 22 | 23 | 'paddingTop', 24 | 'paddingRight', 25 | 'paddingBottom', 26 | 'paddingLeft', 27 | 28 | // https://developer.mozilla.org/en-US/docs/Web/CSS/font 29 | 'fontStyle', 30 | 'fontVariant', 31 | 'fontWeight', 32 | 'fontStretch', 33 | 'fontSize', 34 | 'fontSizeAdjust', 35 | 'lineHeight', 36 | 'fontFamily', 37 | 38 | 'textAlign', 39 | 'textTransform', 40 | 'textIndent', 41 | 'textDecoration', // might not make a difference, but better be safe 42 | 43 | 'letterSpacing', 44 | 'wordSpacing', 45 | 46 | 'tabSize', 47 | 'MozTabSize' 48 | 49 | ]; 50 | 51 | var isFirefox = window.mozInnerScreenX != null; 52 | 53 | function getCaretCoordinates(element, position, options) { 54 | 55 | var debug = options && options.debug || false; 56 | if (debug) { 57 | var el = document.querySelector('#input-textarea-caret-position-mirror-div'); 58 | if ( el ) { el.parentNode.removeChild(el); } 59 | } 60 | 61 | // mirrored div 62 | var div = document.createElement('div'); 63 | div.id = 'input-textarea-caret-position-mirror-div'; 64 | document.body.appendChild(div); 65 | 66 | var style = div.style; 67 | var computed = window.getComputedStyle? getComputedStyle(element) : element.currentStyle; // currentStyle for IE < 9 68 | 69 | // default textarea styles 70 | style.whiteSpace = 'pre-wrap'; 71 | if (element.nodeName !== 'INPUT') 72 | style.wordWrap = 'break-word'; // only for textarea-s 73 | 74 | // position off-screen 75 | style.position = 'absolute'; // required to return coordinates properly 76 | if (!debug) 77 | style.visibility = 'hidden'; // not 'display: none' because we want rendering 78 | 79 | // transfer the element's properties to the div 80 | properties.forEach(function (prop) { 81 | style[prop] = computed[prop]; 82 | }); 83 | 84 | if (isFirefox) { 85 | // Firefox lies about the overflow property for textareas: https://bugzilla.mozilla.org/show_bug.cgi?id=984275 86 | if (element.scrollHeight > parseInt(computed.height)) 87 | style.overflowY = 'scroll'; 88 | } else { 89 | style.overflow = 'hidden'; // for Chrome to not render a scrollbar; IE keeps overflowY = 'scroll' 90 | } 91 | 92 | div.textContent = element.value.substring(0, position); 93 | // the second special handling for input type="text" vs textarea: spaces need to be replaced with non-breaking spaces - http://stackoverflow.com/a/13402035/1269037 94 | if (element.nodeName === 'INPUT') 95 | div.textContent = div.textContent.replace(/\s/g, "\u00a0"); 96 | 97 | var span = document.createElement('span'); 98 | // Wrapping must be replicated *exactly*, including when a long word gets 99 | // onto the next line, with whitespace at the end of the line before (#7). 100 | // The *only* reliable way to do that is to copy the *entire* rest of the 101 | // textarea's content into the created at the caret position. 102 | // for inputs, just '.' would be enough, but why bother? 103 | span.textContent = element.value.substring(position) || '.'; // || because a completely empty faux span doesn't render at all 104 | div.appendChild(span); 105 | 106 | var coordinates = { 107 | top: span.offsetTop + parseInt(computed['borderTopWidth']), 108 | left: span.offsetLeft + parseInt(computed['borderLeftWidth']) 109 | }; 110 | 111 | if (debug) { 112 | span.style.backgroundColor = '#aaa'; 113 | } else { 114 | document.body.removeChild(div); 115 | } 116 | 117 | return coordinates; 118 | } 119 | 120 | if (typeof module != "undefined" && typeof module.exports != "undefined") { 121 | module.exports = getCaretCoordinates; 122 | } else { 123 | window.getCaretCoordinates = getCaretCoordinates; 124 | } 125 | 126 | }()); 127 | -------------------------------------------------------------------------------- /src/components/common/comAfter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-08-25 15:20 6 | * ---------------------------------------------- 7 | * @describe: 后置公共处理 8 | */ 9 | import progress from '../progress/progress'; 10 | import title from '../title/title'; 11 | import footer from '../footer/footer'; 12 | import rtMenu from '../rtMenu/rtMenu'; 13 | import blogIcon from '../blogIcon/blogIcon'; 14 | import dayNight from '../dayNight/dayNight'; 15 | import console from '../console/console'; 16 | 17 | export default function main() { 18 | // 页脚 19 | footer(); 20 | 21 | // 右下角菜单 22 | rtMenu(); 23 | 24 | // 日/夜模式 25 | dayNight(); 26 | 27 | // 进度条 28 | progress(); 29 | 30 | // 背景动效 31 | (async () => { 32 | for (const [key, config] of Object.entries($.__config.animate.background)) { 33 | if (config.enable) { 34 | const module = await import(/* webpackChunkName: "background-[request]" */ `../background/${key}`); 35 | const backgroundEffect = module.default; 36 | backgroundEffect(config.options || {}); 37 | } 38 | } 39 | })(); 40 | 41 | // 鼠标动效 42 | (async () => { 43 | for (const [key, config] of Object.entries($.__config.animate.mouse)) { 44 | if (config.enable) { 45 | const module = await import(/* webpackChunkName: "mouse-[request]" */ `../mouse/${key}`); 46 | const mouse = module.default; 47 | mouse(config.options); 48 | } 49 | } 50 | })(); 51 | 52 | // 网站图标 53 | blogIcon(); 54 | 55 | // 页面title 56 | title(); 57 | 58 | // 控制台输出 59 | console(); 60 | } 61 | -------------------------------------------------------------------------------- /src/components/common/comBefore.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-08-25 15:20 6 | * ---------------------------------------------- 7 | * @describe: 前置公共处理 8 | */ 9 | import sidebar from '../sidebar/sidebar'; 10 | import banner from '../banner/banner'; 11 | import event from '../event/event'; 12 | await $.__tools.dynamicLoadingJs($.__config.default.jqueryrotate).catch((e) => console.error('jqueryrotate.js', e)); 13 | 14 | export default function main() { 15 | // 默认字体图标库 16 | import(/* webpackChunkName: "iconfont" */ /* webpackPreload: true */ '../../style/iconfont.css'); 17 | 18 | // 谷歌字体 19 | import(/* webpackChunkName: "google-fonts" */ /* webpackPreload: true */ '../../style/google-fonts.css'); 20 | 21 | // 国家公祭日和自定义重要的缅怀的日子 22 | const today = $.__tools.getTodayDate(); 23 | if (today == '12-13' || $.__config.memorialDays.includes(today)) $('html').css('filter', 'grayscale(100%)'); 24 | 25 | // 定时清除全部计时器 26 | setTimeout(() => { 27 | Object.values($.__timeIds).forEach((id) => id && clearInterval(id)); 28 | }, 30000); 29 | 30 | // 事件绑定 31 | event.init(); 32 | 33 | // 侧边栏 34 | sidebar(); 35 | 36 | // 头图 37 | banner(); 38 | 39 | // 添加扩展字体图标库; 40 | if ($.__config.fontIconExtend !== '') $.__tools.dynamicLoadingCss($.__config.fontIconExtend, 1); 41 | 42 | $.__loading.stop(); 43 | } 44 | -------------------------------------------------------------------------------- /src/components/console/console.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-08-25 15:21 6 | * ---------------------------------------------- 7 | * @describe: 控制台输出处理 8 | */ 9 | 10 | export default function main() { 11 | // 输出默认版权信息 12 | let github = [ 13 | '\n %c %c %c CnblogsTheme-GitHub %c %c https://github.com/wangyang0210/cnblogs-theme %c \n\n', 14 | 'background: #fadfa3; padding:5px 0;', 15 | 'background: #fadfa3; padding:5px 0;', 16 | 'color: #fadfa3; background: #030307; padding:5px 0;', 17 | 'background: #fadfa3; padding:5px 0;', 18 | 'background: #FCEDC9; color:#030307; padding:5px 0;', 19 | 'background: #fadfa3; padding:5px 0;', 20 | ]; 21 | window.console.log.apply(console, github); 22 | const consoleListData = $.__config.consoleList; 23 | if (consoleListData.length) { 24 | consoleListData.forEach(({text, link}) => { 25 | console.log(`\n %c ${text} %c ${link}\n`, 'color: #fadfa3; background: #030307; padding:5px 0;', 'background: #fadfa3; color:#000;padding:5px 0;'); 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/components/dayNight/dayNight.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-08-25 15:21 6 | * ---------------------------------------------- 7 | * @describe: 日夜间模式处理 8 | */ 9 | import dayNightTemp from '../../template/dayNight.html'; 10 | 11 | export default function main() { 12 | if (!$.__config.switchDayNight.enable) return; 13 | 14 | let h = parseInt(new Date().getHours()), 15 | cookieKey = 'cnblogs_config_isNight', 16 | exp = 4 * 3600, 17 | daySwitch; 18 | $.__status.dayNightCssHref = ''; 19 | const { auto, nightMode } = $.__config.switchDayNight; 20 | 21 | // 切换评论框背景 22 | const switchCommentBackground = (status) => { 23 | $.__config.articleContent.commentBackground.enable && $.__tools.setCommentBackground(status); 24 | }; 25 | 26 | const switchHighlighterTheme = (lighterCodeTheme) => { 27 | window.enableCodeThemeTypeFollowSystem && window.highlighter.setTheme(lighterCodeTheme); 28 | }; 29 | 30 | const getAutoSwitch = () => { 31 | if (auto.enable) return h >= auto.nightHour ? '' : h >= auto.dayHour ? 'daySwitch' : ''; 32 | return 'daySwitch'; 33 | }; 34 | const cookieValue = $.__tools.getCookie(cookieKey); 35 | daySwitch = nightMode ? '' : cookieValue === 'day' ? 'daySwitch' : cookieValue === 'night' ? '' : getAutoSwitch(); 36 | 37 | $('body').prepend($.__tools.tempReplacement(dayNightTemp, 'daySwitch', daySwitch)); 38 | 39 | if (daySwitch) { 40 | switchCommentBackground('day'); 41 | switchHighlighterTheme(window.codeHighlightTheme); 42 | } else { 43 | loadDarkCss(); 44 | switchCommentBackground('night'); 45 | switchHighlighterTheme(window.darkModeCodeHighlightTheme); 46 | } 47 | 48 | /** 49 | * 模式切换事件 50 | */ 51 | $('#dayNightSwitch .onOff').click(function () { 52 | if ($(this).hasClass('daySwitch')) { 53 | // 夜间 54 | $.__tools.setCookie(cookieKey, 'night', exp); 55 | $(this).removeClass('daySwitch'); 56 | loadDarkCss(); 57 | switchCommentBackground('night'); 58 | switchHighlighterTheme(window.darkModeCodeHighlightTheme); 59 | } else { 60 | // 日间 61 | $.__tools.setCookie(cookieKey, 'day', exp); 62 | $(this).addClass('daySwitch'); 63 | $('head link#baseDarkCss').remove(); 64 | switchCommentBackground('day'); 65 | switchHighlighterTheme(window.codeHighlightTheme); 66 | } 67 | }); 68 | 69 | /** 70 | * 加载夜间模式样式文件 71 | * 第一次初始化使用 import 加载并记录路径 72 | * 第二次及以后使用标签构建文件加载 73 | */ 74 | function loadDarkCss() { 75 | if ($.__status.dayNightCssHref) { 76 | $('head').append( 77 | `` 78 | ); 79 | } else { 80 | import(/* webpackChunkName: "day-night" */ /* webpackPrefetch: true */ '../../style/base.dark.css'); 81 | 82 | setTimeout(function () { 83 | let links = $('head link'); 84 | for (let i = links.length - 1; i > 0; i--) { 85 | let obj = $(links[i]); 86 | let href = obj.attr('href'); 87 | if (/^.*\/day-night\.[a-z0-9]{8}\.css$/.test(href)) { 88 | $.__status.dayNightCssHref = href; 89 | obj.attr('id', 'baseDarkCss'); 90 | break; 91 | } 92 | } 93 | }, 500); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/components/event/event.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-08-25 15:21 6 | * ---------------------------------------------- 7 | * @describe: 事件监听 8 | */ 9 | 10 | export default { 11 | init() { 12 | $.__event.scroll = { 13 | handle: [], 14 | temScroll: 0, 15 | docScroll: $(document).scrollTop(), 16 | homeScroll: $('#home').offset().top - 40, 17 | }; 18 | 19 | $(window).scroll(() => { 20 | const { scroll } = $.__event; 21 | scroll.docScroll = $(document).scrollTop(); 22 | scroll.homeScroll = $('#home').offset().top - 40; 23 | this.handle.scroll(); 24 | scroll.temScroll = scroll.docScroll; 25 | }); 26 | $.__event.resize = { handle: [] }; 27 | $(window).resize(() => this.handle.resize()); 28 | }, 29 | handle: { 30 | scroll() { 31 | $.__event.scroll.handle.forEach((fn) => fn()); 32 | }, 33 | resize() { 34 | $.__event.resize.handle.forEach((fn) => fn()); 35 | $.__tools.setDomHomePosition(); 36 | }, 37 | }, 38 | }; 39 | -------------------------------------------------------------------------------- /src/components/footer/footer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-08-25 15:22 6 | * ---------------------------------------------- 7 | * @describe: footer底部信息 8 | */ 9 | import footerTemp from '../../template/footer.html'; 10 | import { request } from '../../utils/request'; 11 | 12 | export default function main() { 13 | const footer = $('#footer'); 14 | const footerText = footer.text(); 15 | 16 | let footerHtml = footerTemp; 17 | let config = $.__config.footer; 18 | 19 | footerHtml = $.__tools.tempReplacement(footerHtml, 'footerText', footerText); 20 | 21 | // 设置音乐播放器 22 | if (config.aplayer.enable) { 23 | Promise.all([$.__tools.dynamicLoadingJs($.__config.default.aplayer), $.__tools.dynamicLoadingJs($.__config.default.meting)]) 24 | .then((r) => { 25 | $.__tools.dynamicLoadingCss($.__config.default.aplayercss); 26 | $('#footer').append(` 27 | 47 | `); 48 | }) 49 | .catch((e) => console.error('aplayer|meting', e)); 50 | } 51 | 52 | // 设置标语 53 | const re = [ 54 | ['textLeft', config.text.left], 55 | ['iconFont', config.text.iconFont.icon], 56 | ['iconColor', config.text.iconFont.color], 57 | ['iconSize', config.text.iconFont.fontSize], 58 | ['textRight', config.text.right], 59 | ]; 60 | 61 | if (config.text.left || config.text.right) { 62 | re.push(['textShow', 'block']); 63 | } else { 64 | re.push(['textShow', 'none']); 65 | } 66 | 67 | footerHtml = $.__tools.batchTempReplacement(footerHtml, re); 68 | 69 | // 设置友情链接 70 | const footerLinksData = $.__config.links.footer; 71 | if (footerLinksData.length) { 72 | const linksHtml = footerLinksData 73 | .map(({ text, link }, index) => { 74 | return `${text}${index < footerLinksData.length - 1 ? '/' : ''}`; 75 | }) 76 | .join(''); 77 | 78 | footerHtml = $.__tools.batchTempReplacement(footerHtml, [ 79 | ['linksHtml', `友情链接:${linksHtml}`], 80 | ['linkShow', 'block'], 81 | ]); 82 | } else { 83 | footerHtml = $.__tools.tempReplacement(footerHtml, 'linkShow', 'none'); 84 | } 85 | 86 | // 添加页脚 87 | footer.html(footerHtml); 88 | 89 | // 页脚样式 90 | switch (parseInt(config.style)) { 91 | case 1: 92 | $('#footer').addClass('footer-t1').find('#footerStyle1').show().css('background', 'url(//images.cnblogs.com/cnblogs_com/wangyang0210/1943283/o_221114131838_footer.webp) no-repeat 50%'); 93 | break; 94 | case 2: 95 | default: 96 | $('#footer .footer-text').css({ 'padding-bottom': '0', 'border-bottom': 'none', 'margin-bottom': '0' }); 97 | const footerStyle2 = $('#footerStyle2'); 98 | footerStyle2.show().find('.clouds').css('background', 'url(//images.cnblogs.com/cnblogs_com/wangyang0210/1943283/o_221114132857_clouds.webp) repeat-x'); 99 | footerStyle2.find('.background').css('background', 'url(//images.cnblogs.com/cnblogs_com/wangyang0210/1943283/o_221114134558_background.webp) repeat-x'); 100 | footerStyle2.find('.foreground').css('background', 'url(//images.cnblogs.com/cnblogs_com/wangyang0210/1943283/o_221114132230_foreground.webp) repeat-x'); 101 | break; 102 | } 103 | 104 | // 设置运行时间 105 | window.setInterval(() => { 106 | let runDate = $.__tools.getRunDate(($.__config.info.startDate ||= '2021-01-01')); 107 | $('#blogRunTimeSpan').text(`This blog has running : ${runDate.daysold} d ${runDate.hrsold} h ${runDate.minsold} m ${runDate.seconds} s`); 108 | }, 500); 109 | 110 | // 定时网站统计 111 | if ($.__config.umami?.url && $.__config.umami?.shareId) { 112 | const baseUrl = $.__config.umami.url; 113 | $.__timeIds.umamiTId = window.setInterval(() => { 114 | request(`${baseUrl}/api/share/${$.__config.umami.shareId}`).then((r) => { 115 | Promise.all([ 116 | request(`${baseUrl}/api/websites/${r.id}/stats?start_at=${$.__tools.getTodayStart()}&end_at=${$.__tools.getTodayEnd()}`, 'GET', {}, { 'x-umami-share-token': r.token }), 117 | request(`${baseUrl}/api/websites/${r.id}/stats?start_at=${$.__tools.getYesterdayStart()}&end_at=${$.__tools.getYesterdayEnd()}`, 'GET', {}, { 'x-umami-share-token': r.token }), 118 | request(`${baseUrl}/api/websites/${r.id}/active`, 'GET', {}, { 'x-umami-share-token': r.token }), 119 | ]).then((results) => { 120 | const todayState = results[0]; 121 | const yesterdayState = results[1]; 122 | const online = results[2]; 123 | $('#cnzzInfo') 124 | .text( 125 | `Online: ${online[0].x} | Today: ${todayState.pageviews.value} / ${todayState.uniques.value} / ${todayState.totaltime.value} | Yesterday: ${yesterdayState.pageviews.value} / ${yesterdayState.uniques.value} / ${yesterdayState.totaltime.value}` 126 | ) 127 | .show(); 128 | }); 129 | }); 130 | $.__tools.clearIntervalTimeId($.__timeIds.umamiTId); 131 | }, 1000); 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /src/components/greenChannel/greenChannel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-08-25 15:22 6 | * ---------------------------------------------- 7 | * @describe: 文章底部信息按钮处理 8 | */ 9 | import '../../style/customBtn.css'; 10 | 11 | export default function main() { 12 | const buttons = [ 13 | { 14 | id: 'green_channel_digg', 15 | text: '推荐该文', 16 | className: 'custom-btn btn-11', 17 | }, 18 | { 19 | id: 'green_channel_follow', 20 | text: '关注博主', 21 | className: 'custom-btn btn-8', 22 | }, 23 | { 24 | id: 'green_channel_favorite', 25 | text: '收藏本文', 26 | className: 'custom-btn btn-7', 27 | }, 28 | { 29 | id: 'green_channel_weibo', 30 | text: '分享微博', 31 | className: 'custom-btn btn-15', 32 | }, 33 | { 34 | id: 'green_channel_wechat', 35 | text: '分享微信', 36 | className: 'custom-btn btn-13', 37 | }, 38 | ]; 39 | 40 | buttons.forEach((button) => { 41 | $.__timeIds[`${button.id}TId`] = window.setInterval(() => { 42 | const element = $(`#${button.id}`); 43 | if (element.length) { 44 | element.after( 45 | `` 48 | ); 49 | $.__tools.clearIntervalTimeId($.__timeIds[`${button.id}TId`]); 50 | } 51 | }, 1000); 52 | }); 53 | } 54 | -------------------------------------------------------------------------------- /src/components/imgBox/imgBox.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-08-25 15:22 6 | * ---------------------------------------------- 7 | * @describe: 图片灯箱处理 8 | */ 9 | await $.__tools.dynamicLoadingCss($.__config.default.fancyboxcss); 10 | await $.__tools.dynamicLoadingJs($.__config.default.fancybox).catch((e) => console.error('fancybox.js', e)); 11 | export default function main() { 12 | setTimeout(() => { 13 | let imgLength = $('#cnblogs_post_body img').length - 1; 14 | if (!imgLength) return; 15 | 16 | let cpb = $('#cnblogs_post_body'), 17 | imgList = $(`#cnblogs_post_body img:lt(${imgLength})`), 18 | comImgList = $('.feedbackCon img'), 19 | data = []; 20 | 21 | $.each(imgList, (i) => data.push(imgList[i])); 22 | 23 | $.each(comImgList, (i) => data.push(comImgList[i])); 24 | 25 | if (cpb.length && data.length) { 26 | $.each(data, (i) => { 27 | let tem = $(data[i]); 28 | if (!tem.hasClass('code_img_closed') && !tem.hasClass('code_img_opened')) { 29 | let width = tem.attr('width'); 30 | let height = tem.attr('height'); 31 | let alt = tem.attr('alt') ?? ''; 32 | let style = tem.attr('style') ?? ''; 33 | tem.after( 34 | ` 35 | ${alt}` 38 | ); 39 | tem.remove(); 40 | } 41 | }); 42 | } 43 | }, 800); 44 | } 45 | -------------------------------------------------------------------------------- /src/components/loading/loading.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-08-25 15:22 6 | * ---------------------------------------------- 7 | * @describe: loading 处理 8 | */ 9 | import { rebound, Spinner } from 'exports-loader?exports=rebound,Spinner!../../vendor/loading/loading'; 10 | 11 | export default function main() { 12 | let loading = function () { 13 | let that = this; 14 | this.config = $?.__config?.loading || { 15 | rebound: { 16 | tension: 16, 17 | friction: 5, 18 | }, 19 | spinner: { 20 | id: 'spinner', 21 | radius: 90, 22 | sides: 3, 23 | depth: 4, 24 | colors: { 25 | background: '#f0f0f0', 26 | stroke: '#272633', 27 | base: null, 28 | child: '#272633', 29 | }, 30 | alwaysForward: true, 31 | restAt: 0.5, 32 | renderBase: false, 33 | }, 34 | }; 35 | this.spring = null; 36 | this.spinner = null; 37 | this.initRebound = () => { 38 | let settings = that.config.rebound; 39 | 40 | let springSystem = new rebound.SpringSystem(); 41 | 42 | that.spring = springSystem.createSpring(settings.tension, settings.friction); 43 | }; 44 | this.initSpinner = () => { 45 | let settings = that.config.spinner; 46 | 47 | that.spinner = new Spinner(settings); 48 | }; 49 | this.start = () => { 50 | $('#blog-news').prepend('
'); 51 | that.initRebound(); 52 | that.initSpinner(); 53 | that.spinner.init(that.spring, true); 54 | }; 55 | this.stop = () => { 56 | $('body').css('overflow', 'auto'); 57 | that.spinner.setComplete(); 58 | $('div#loading').hide(); 59 | $('a[name="top"]').hide(); 60 | }; 61 | }; 62 | return new loading(); 63 | } 64 | -------------------------------------------------------------------------------- /src/components/mouse/bubble.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-09-02 23:05 6 | * ---------------------------------------------- 7 | * @describe: 鼠标移动汽包粒子效果 8 | */ 9 | 10 | export default function main(options) { 11 | let canvasElement = document.createElement('canvas'); 12 | canvasElement.id = 'bubble'; 13 | $('#home').after(canvasElement); 14 | let canvas = document.getElementById('bubble'); 15 | let ctx = canvas.getContext('2d'); 16 | canvas.width = window.innerWidth; 17 | canvas.height = window.innerHeight; 18 | canvas.style.position = 'fixed'; 19 | canvas.style.left = '0'; 20 | canvas.style.bottom = '0'; 21 | canvas.style.zIndex = '999999999999999999999999999999999999999999'; 22 | canvas.style.pointerEvents = 'none'; 23 | let points = []; 24 | let live = options.live; 25 | let colors = options.colors; 26 | 27 | window.addEventListener('mousemove', function (evt) { 28 | for (let i = 0; i < options.quantity; i++) { 29 | points.push({ 30 | sx: evt.x, 31 | sy: evt.y, 32 | vx: 0.5 - Math.random(), 33 | vy: 0.5 - Math.random(), 34 | life: live, //存活周期 35 | color: colors[parseInt(Math.random() * colors.length)], 36 | size: Math.random() * options.size, 37 | }); 38 | } 39 | }); 40 | 41 | function drawpoints() { 42 | ctx.clearRect(0, 0, canvas.width, canvas.height); 43 | for (let i = 0; i < points.length; i++) { 44 | let point = points[i]; 45 | ctx.beginPath(); 46 | ctx.arc(point.sx, point.sy, point.size, Math.PI * 2, false); 47 | ctx.fillStyle = 'rgba(' + point.color + ',' + point.life / live + ')'; 48 | ctx.fill(); 49 | point.life--; 50 | if (point.life <= 0) { 51 | points.splice(i, 1); 52 | } 53 | point.sx += point.vx * 3; 54 | point.sy += point.vy * 3; 55 | } 56 | } 57 | 58 | setInterval(drawpoints, 20); 59 | } 60 | -------------------------------------------------------------------------------- /src/components/mouse/click.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-08-27 20:29 6 | * ---------------------------------------------- 7 | * @describe: 鼠标粒子点击特效 8 | */ 9 | 10 | export default function main() { 11 | class Circle { 12 | constructor({ origin, speed, color, angle, context }) { 13 | this.origin = origin; 14 | this.position = { 15 | ...this.origin, 16 | }; 17 | this.color = color; 18 | this.speed = speed; 19 | this.angle = angle; 20 | this.context = context; 21 | this.renderCount = 0; 22 | } 23 | 24 | draw() { 25 | this.context.fillStyle = this.color; 26 | this.context.beginPath(); 27 | this.context.arc(this.position.x, this.position.y, 2, 0, Math.PI * 2); 28 | this.context.fill(); 29 | } 30 | 31 | move() { 32 | this.position.x = Math.sin(this.angle) * this.speed + this.position.x; 33 | this.position.y = Math.cos(this.angle) * this.speed + this.position.y + this.renderCount * 0.3; 34 | this.renderCount++; 35 | } 36 | } 37 | 38 | class Boom { 39 | constructor({ origin, context, circleCount = 10, area }) { 40 | this.origin = origin; 41 | this.context = context; 42 | this.circleCount = circleCount; 43 | this.area = area; 44 | this.stop = false; 45 | this.circles = []; 46 | } 47 | 48 | randomArray(range) { 49 | const length = range.length; 50 | const randomIndex = Math.floor(length * Math.random()); 51 | return range[randomIndex]; 52 | } 53 | 54 | randomColor() { 55 | const range = ['8', '9', 'A', 'B', 'C', 'D', 'E', 'F']; 56 | return ( 57 | '#' + 58 | this.randomArray(range) + 59 | this.randomArray(range) + 60 | this.randomArray(range) + 61 | this.randomArray(range) + 62 | this.randomArray(range) + 63 | this.randomArray(range) 64 | ); 65 | } 66 | 67 | randomRange(start, end) { 68 | return (end - start) * Math.random() + start; 69 | } 70 | 71 | init() { 72 | for (let i = 0; i < this.circleCount; i++) { 73 | const circle = new Circle({ 74 | context: this.context, 75 | origin: this.origin, 76 | color: this.randomColor(), 77 | angle: this.randomRange(Math.PI - 1, Math.PI + 1), 78 | speed: this.randomRange(1, 6), 79 | }); 80 | this.circles.push(circle); 81 | } 82 | } 83 | 84 | move() { 85 | this.circles.forEach((circle, index) => { 86 | if (circle.position.x > this.area.width || circle.position.y > this.area.height) { 87 | return this.circles.splice(index, 1); 88 | } 89 | circle.move(); 90 | }); 91 | if (this.circles.length == 0) this.stop = true; 92 | } 93 | 94 | draw() { 95 | this.circles.forEach((circle) => circle.draw()); 96 | } 97 | } 98 | 99 | class CursorSpecialEffects { 100 | constructor() { 101 | this.computerCanvas = document.createElement('canvas'); 102 | this.renderCanvas = document.createElement('canvas'); 103 | 104 | this.computerContext = this.computerCanvas.getContext('2d'); 105 | this.renderContext = this.renderCanvas.getContext('2d'); 106 | 107 | this.globalWidth = window.innerWidth; 108 | this.globalHeight = window.innerHeight; 109 | 110 | this.booms = []; 111 | this.running = false; 112 | } 113 | 114 | handleMouseDown(e) { 115 | const boom = new Boom({ 116 | origin: { 117 | x: e.clientX, 118 | y: e.clientY, 119 | }, 120 | context: this.computerContext, 121 | area: { 122 | width: this.globalWidth, 123 | height: this.globalHeight, 124 | }, 125 | }); 126 | boom.init(); 127 | this.booms.push(boom); 128 | this.running || this.run(); 129 | } 130 | 131 | handlePageHide() { 132 | this.booms = []; 133 | this.running = false; 134 | } 135 | 136 | init() { 137 | const style = this.renderCanvas.style; 138 | style.position = 'fixed'; 139 | style.top = style.left = 0; 140 | style.zIndex = '999999999999999999999999999999999999999999'; 141 | style.pointerEvents = 'none'; 142 | 143 | style.width = this.renderCanvas.width = this.computerCanvas.width = this.globalWidth; 144 | style.height = this.renderCanvas.height = this.computerCanvas.height = this.globalHeight; 145 | 146 | document.body.append(this.renderCanvas); 147 | 148 | window.addEventListener('mousedown', this.handleMouseDown.bind(this)); 149 | window.addEventListener('pagehide', this.handlePageHide.bind(this)); 150 | } 151 | 152 | run() { 153 | this.running = true; 154 | if (this.booms.length == 0) { 155 | this.running = false; 156 | return; 157 | } 158 | 159 | requestAnimationFrame(this.run.bind(this)); 160 | 161 | this.computerContext.clearRect(0, 0, this.globalWidth, this.globalHeight); 162 | this.renderContext.clearRect(0, 0, this.globalWidth, this.globalHeight); 163 | 164 | this.booms.forEach((boom, index) => { 165 | if (boom.stop) { 166 | return this.booms.splice(index, 1); 167 | } 168 | boom.move(); 169 | boom.draw(); 170 | }); 171 | this.renderContext.drawImage(this.computerCanvas, 0, 0, this.globalWidth, this.globalHeight); 172 | } 173 | } 174 | 175 | const cursorSpecialEffects = new CursorSpecialEffects(); 176 | cursorSpecialEffects.init(); 177 | } 178 | -------------------------------------------------------------------------------- /src/components/mouse/cursor.js: -------------------------------------------------------------------------------- 1 | export default function main(options) { 2 | document.body.style.cursor = `url(${options.url || 'https://files.cnblogs.com/files/wangyang0210/normal.gif?t=1681261712'}), default`; 3 | } 4 | -------------------------------------------------------------------------------- /src/components/mouse/mo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-09-04 19:36 6 | * ---------------------------------------------- 7 | * @describe: 使用mo.js实现各种效果 8 | */ 9 | 10 | export default function main(options) { 11 | $.__tools 12 | .dynamicLoadingJs($.__config.default.mojs) 13 | .then(() => { 14 | const burst = new mojs.Burst({ 15 | left: 0, 16 | top: 0, 17 | ...options, 18 | }); 19 | burst.el.style.zIndex = 999999; 20 | document.addEventListener('click', function (e) { 21 | burst.tune({ x: e.pageX, y: e.pageY }).setSpeed(3).replay(); 22 | }); 23 | }) 24 | .catch((e) => console.error('mo.js: ', e)); 25 | } 26 | -------------------------------------------------------------------------------- /src/components/mouse/mouse.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-08-25 15:23 6 | * ---------------------------------------------- 7 | * @describe: 鼠标移动/点击效果 8 | */ 9 | import '../../style/mouse.css'; 10 | await $.__tools.dynamicLoadingJs($.__config.default.gsap).catch((e) => console.error('gsap.js', e)); 11 | export default function main(options) { 12 | const cursor = document.createElement('div'); 13 | cursor.className = 'cursor'; 14 | 15 | const cursorF = document.createElement('div'); 16 | cursorF.className = 'cursor-f'; 17 | 18 | let cursorX = 0; 19 | let cursorY = 0; 20 | let pageX = 0; 21 | let pageY = 0; 22 | let size = options.size; 23 | let sizeF = options.sizeF; 24 | let followSpeed = 0.16; 25 | 26 | document.body.appendChild(cursor); 27 | document.body.appendChild(cursorF); 28 | 29 | if ('ontouchstart' in window) { 30 | cursor.style.display = 'none'; 31 | cursorF.style.display = 'none'; 32 | } 33 | 34 | cursor.style.setProperty('--size', size + 'px'); 35 | cursorF.style.setProperty('--size', sizeF + 'px'); 36 | 37 | window.addEventListener('mousemove', function (e) { 38 | pageX = e.pageX; 39 | pageY = e.pageY; 40 | cursor.style.top = pageY - size / 2 + 'px'; 41 | let cursorLeft = pageX - size / 2; 42 | let offsetWidth = document.body.offsetWidth; 43 | cursorLeft = cursorLeft < 0 ? 0 : offsetWidth - size < cursorLeft ? offsetWidth - size : cursorLeft; 44 | cursor.style.left = cursorLeft + 'px'; 45 | }); 46 | 47 | function lerp(start, end, amount) { 48 | return (1 - amount) * start + amount * end; 49 | } 50 | 51 | function loop() { 52 | cursorX = lerp(cursorX, pageX, followSpeed); 53 | cursorY = lerp(cursorY, pageY, followSpeed); 54 | cursorF.style.top = cursorY - sizeF / 2 + 'px'; 55 | let cursorFLeft = cursorX - sizeF / 2; 56 | let offsetWidth = document.body.offsetWidth; 57 | cursorFLeft = cursorFLeft < 0 ? 0 : offsetWidth - sizeF < cursorFLeft ? offsetWidth - sizeF : cursorFLeft; 58 | cursorF.style.left = cursorFLeft + 'px'; 59 | 60 | requestAnimationFrame(loop); 61 | } 62 | 63 | loop(); 64 | 65 | let startY; 66 | let endY; 67 | let clicked = false; 68 | 69 | function mousedown(e) { 70 | gsap.to(cursor, { scale: 4.5 }); 71 | gsap.to(cursorF, { scale: 0.4 }); 72 | 73 | clicked = true; 74 | startY = e.clientY || e.touches[0].clientY || e.targetTouches[0].clientY; 75 | } 76 | 77 | function mouseup(e) { 78 | gsap.to(cursor, { scale: 1 }); 79 | gsap.to(cursorF, { scale: 1 }); 80 | 81 | endY = e.clientY || endY; 82 | if (clicked && startY && Math.abs(startY - endY) >= 40) { 83 | clicked = false; 84 | startY = null; 85 | endY = null; 86 | } 87 | } 88 | 89 | window.addEventListener('mousedown', mousedown, false); 90 | window.addEventListener('touchstart', mousedown, false); 91 | window.addEventListener( 92 | 'touchmove', 93 | function (e) { 94 | if (clicked) endY = e.touches[0].clientY || e.targetTouches[0].clientY; 95 | }, 96 | false 97 | ); 98 | window.addEventListener('touchend', mouseup, false); 99 | window.addEventListener('mouseup', mouseup, false); 100 | } 101 | -------------------------------------------------------------------------------- /src/components/progress/progress.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-08-25 15:23 6 | * ---------------------------------------------- 7 | * @describe: 头部进度条处理 8 | */ 9 | 10 | export default function main() { 11 | $.__tools 12 | .dynamicLoadingJs($.__config.default.toprogress) 13 | .then((r) => { 14 | $('#blog-news').prepend('
'); 15 | let progressBar = ToProgress && new window.ToProgress($.__config.progressBar, '#progressBar'); 16 | // 添加事件监听 17 | $.__event.scroll.handle.push(() => progressBar.setProgress($.__tools.getScrollPercent())); 18 | }) 19 | .catch((e) => console.log('toprogress.js', e)); 20 | } 21 | -------------------------------------------------------------------------------- /src/components/sidebar/lib/classie.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-08-25 15:24 6 | * ---------------------------------------------- 7 | * @describe: 侧边栏处理 8 | */ 9 | export default function main() { 10 | function classReg(className) { 11 | return new RegExp(`(^|\\s+)${className}(\\s+|$)`); 12 | } 13 | 14 | const hasClass = (elem, c) => elem.classList ? elem.classList.contains(c) : classReg(c).test(elem.className); 15 | const addClass = (elem, c) => elem.classList ? elem.classList.add(c) : !hasClass(elem, c) && (elem.className += ` ${c}`); 16 | const removeClass = (elem, c) => elem.classList ? elem.classList.remove(c) : elem.className = elem.className.replace(classReg(c), ' '); 17 | 18 | const toggleClass = (elem, c) => (hasClass(elem, c) ? removeClass : addClass)(elem, c); 19 | 20 | return { 21 | hasClass, 22 | addClass, 23 | removeClass, 24 | toggleClass, 25 | has: hasClass, 26 | add: addClass, 27 | remove: removeClass, 28 | toggle: toggleClass, 29 | }; 30 | } 31 | -------------------------------------------------------------------------------- /src/components/sidebar/lib/main4.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-08-25 15:24 6 | * ---------------------------------------------- 7 | * @describe: 侧边栏处理 8 | */ 9 | await $.__tools.dynamicLoadingJs($.__config.default.snapsvg).catch((e) => console.error('snapsvg-cjs.js', e)); 10 | await $.__tools.dynamicLoadingJs($.__config.default.optiscroll).catch((e) => console.log('optiscroll.js', e)); 11 | await $.__tools.dynamicLoadingCss($.__config.default.optiscrollcss); 12 | export default function main() { 13 | const bodyEl = document.body; 14 | const content = document.querySelector('.content-wrap'); 15 | const openbtn = document.getElementById('open-button'); 16 | const closebtn = document.getElementById('close-button'); 17 | const morphEl = document.getElementById('morph-shape'); 18 | const s = Snap(morphEl.querySelector('svg')); 19 | const path = s.select('path'); 20 | const initialPath = path.attr('d'); 21 | let isOpen = false; 22 | let isAnimating = false; 23 | let myOptiscrollInstance; 24 | 25 | function init() { 26 | initEvents(); 27 | myOptiscrollInstance = new Optiscroll(document.querySelector('#menuWrap'), { 28 | preventParentScroll: true, 29 | forceScrollbars: true, 30 | }); 31 | } 32 | 33 | function initEvents() { 34 | openbtn.addEventListener('click', toggleMenu); 35 | if (closebtn) closebtn.addEventListener('click', toggleMenu); 36 | content.addEventListener('click', (ev) => { 37 | if (isOpen && ev.target !== openbtn) toggleMenu(); 38 | }); 39 | } 40 | 41 | function toggleMenu() { 42 | $('.menu-wrap').show(); 43 | if (isOpen) { 44 | $(bodyEl).removeClass('show-menu'); 45 | $('#content-wrap').fadeOut(300); 46 | $(bodyEl).css('overflow', 'auto'); 47 | $('#mainContent').off('touchmove'); 48 | path.attr('d', initialPath); 49 | isAnimating = false; 50 | } else { 51 | $(bodyEl).addClass('show-menu'); 52 | $('#content-wrap').show(); 53 | $('body').css('overflow', 'hidden'); 54 | myOptiscrollInstance.scrollTo(false, 'top'); 55 | } 56 | isOpen = !isOpen; 57 | } 58 | 59 | init(); 60 | 61 | return { 62 | myOptiscrollInstance, 63 | }; 64 | } 65 | -------------------------------------------------------------------------------- /src/components/status/status.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-08-25 15:24 6 | * ---------------------------------------------- 7 | * @describe: 博客基础信息抓取处理 8 | */ 9 | 10 | let status = { 11 | url: window.location.href, 12 | user: '', 13 | pageType: '', 14 | articleId: '', 15 | }; 16 | // 提取url信息 17 | let tmp = status.url.split('/'); 18 | status.user = tmp[3]; 19 | status.homeUrl = tmp.slice(0, 4).join('/'); 20 | let topics = $('#topics').length; 21 | status.pageType = !topics 22 | ? 'home' 23 | : $('#bookListFlg').length 24 | ? 'books' 25 | : $('#linkListFlg').length 26 | ? 'links' 27 | : 'article'; 28 | if (topics) status.articleId = tmp[tmp.length - 1].split('.')[0]; 29 | 30 | export default status; 31 | -------------------------------------------------------------------------------- /src/components/title/title.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-08-25 15:25 6 | * ---------------------------------------------- 7 | * @describe: 页面title处理 8 | */ 9 | 10 | export default function main() { 11 | 12 | const RelTitle = document.title; 13 | const config = $.__config.title; 14 | let hidden, visibilityChange, timer; 15 | 16 | 17 | if (typeof document.hidden !== 'undefined') { 18 | hidden = 'hidden'; 19 | visibilityChange = 'visibilitychange'; 20 | } 21 | if (typeof document.mozHidden !== 'undefined') { 22 | // Firefox up to v17 23 | hidden = 'mozHidden'; 24 | visibilityChange = 'mozvisibilitychange'; 25 | } 26 | 27 | if (typeof document.webkitHidden !== 'undefined') { 28 | // Chrome up to v32, Android up to v4.4, Blackberry up to v10 29 | hidden = 'webkitHidden'; 30 | visibilityChange = 'webkitvisibilitychange'; 31 | } 32 | 33 | let handleVisibilityChange = () => { 34 | if (timer) clearTimeout(timer); 35 | 36 | if (document[hidden] && config.onblurTime >= 0) { 37 | timer = setTimeout(() => { 38 | document.title = `${config.onblur} - ${RelTitle.split(' - ')[0]}`; 39 | }, config.onblurTime); 40 | } 41 | 42 | if (!document[hidden] && config.focusTime >= 0) { 43 | document.title = config.focus; 44 | timer = setTimeout(() => { 45 | document.title = RelTitle; 46 | }, config.focusTime); 47 | } 48 | 49 | if (!document[hidden] && config.focusTime < 0) { 50 | document.title = RelTitle; 51 | } 52 | }; 53 | if (typeof document.addEventListener !== 'undefined' || typeof document[hidden] !== 'undefined') { 54 | document.addEventListener(visibilityChange, handleVisibilityChange, false); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-08-25 15:26 6 | * ---------------------------------------------- 7 | * @describe: 主程序文件 8 | */ 9 | import loading from './components/loading/loading'; 10 | import defaultConfig from './components/config/config.json5'; 11 | import status from './components/status/status'; 12 | import tools from './utils/tools'; 13 | import event from './components/event/event'; 14 | $.__loading = loading(); 15 | $.__loading.start(); 16 | $(document).ready(function () { 17 | // 初始化 18 | $.__config = $.extend(true, defaultConfig, window?.cnblogsConfig || {}); // 配置信息 19 | $.__status = status; // 页面状态信息 20 | $.__tools = tools; // 公共处理工具 21 | $.__timeIds = {}; // 定时器 22 | $.__event = {}; // 事件 23 | $.__config.info.name ||= $.__status.user; 24 | $.__tools 25 | .dynamicLoadingJs($.__config.default.moment) 26 | .then((r) => { 27 | import( 28 | /* webpackChunkName: "page-[request]" */ /* webpackPrefetch: true */ `./page/${$.__status.pageType}` 29 | ).then((module) => { 30 | const page = module.default; 31 | // 前置公共处理 32 | import( 33 | /* webpackChunkName: "com-before" */ /* webpackPrefetch: true */ './components/common/comBefore' 34 | ).then((beforeModule) => { 35 | const comBefore = beforeModule.default; 36 | comBefore(); 37 | // 页面逻辑处理 38 | page(); 39 | 40 | // 后置公共处理 41 | import( 42 | /* webpackChunkName: "com-after" */ /* webpackPrefetch: true */ './components/common/comAfter' 43 | ).then((afterModule) => { 44 | const comAfter = afterModule.default; 45 | comAfter(); 46 | (() => { 47 | $.__tools.setDomHomePosition(); // 文章主体位置修正 48 | event.handle.scroll(); // 触发滚动处理 49 | event.handle.resize(); // 触发窗口大小变化处理 50 | })(); 51 | }); 52 | }); 53 | }); 54 | }) 55 | .catch((e) => console.error('moment.js', e)); 56 | }); 57 | -------------------------------------------------------------------------------- /src/page/article.js: -------------------------------------------------------------------------------- 1 | import comArticle from './common/com-article'; 2 | import imgBox from '../components/imgBox/imgBox'; 3 | 4 | export default function main() { 5 | // 文章页公共处理 6 | comArticle(); 7 | 8 | // 图片灯箱处理 9 | imgBox(); 10 | } 11 | -------------------------------------------------------------------------------- /src/page/books.js: -------------------------------------------------------------------------------- 1 | import '../style/books.css'; 2 | import booksTemp from '../template/books.html'; 3 | import articleDirectory from '../components/articleDirectory/articleDirectory'; 4 | import comArticle from './common/com-article'; 5 | 6 | export default function main() { 7 | // 文章页公共处理 8 | comArticle(); 9 | 10 | // 书单页处理 11 | if ($.__config.bookList.length) { 12 | import(/* webpackChunkName: "gf-blink" */ '../style/gf-blink.css'); 13 | 14 | let postBody = $('#cnblogs_post_body'), 15 | html = ''; 16 | const infoObj = { 17 | formerName: '原 名:', 18 | author: '作 者:', 19 | translator: '译 者:', 20 | press: '出版社:', 21 | year: '出版年:', 22 | direct: '导 演: ', 23 | scenarist: '编 剧: ', 24 | star: '主 演: ', 25 | type: '类 型: ', 26 | productionCountry: '制片国家/地区: ', 27 | language: '语 言: ', 28 | releaseDate: '上映日期: ', 29 | filmLength: '片 长: ', 30 | alias: '别 名: ', 31 | }; 32 | 33 | $.__config.bookList.forEach((list) => { 34 | if (list.title) html += `

${list.title}

`; 35 | html += '
'; 36 | list.books.forEach((book) => { 37 | let cardHtml = booksTemp, 38 | scoreHtml = '', 39 | infoHtml = ''; 40 | 41 | if (book?.score > 0) { 42 | const fullStars = Math.floor(book.score); 43 | const halfStar = book.score > fullStars ? '' : ''; 44 | const emptyStars = ``.repeat(5 - fullStars); 45 | scoreHtml = ``.repeat(fullStars) + halfStar + emptyStars; 46 | } else { 47 | scoreHtml = ``.repeat(5); 48 | } 49 | 50 | Object.entries(infoObj).forEach(([key, value]) => { 51 | if (book?.[key]) infoHtml += `${value} ${book?.[key]}
`; 52 | }); 53 | 54 | cardHtml = $.__tools.batchTempReplacement(cardHtml, [ 55 | ['cover', book.cover || ''], 56 | ['name', book.name || ''], 57 | ['readDate', book?.readDate || ''], 58 | ['readDateStyle', book?.readDate ? 'initial;' : 'none'], 59 | ['readPercentage', book?.readPercentage || ''], 60 | ['readPercentageStyle', book?.readPercentage ? 'initial;' : 'none'], 61 | ['scoreHtml', scoreHtml], 62 | ['infoHtml', infoHtml], 63 | ]); 64 | html += cardHtml; 65 | }); 66 | html += '
'; 67 | }); 68 | let articleSuffixFlg = $('.articleSuffix-flg'); 69 | articleSuffixFlg.length ? articleSuffixFlg.before(html) : postBody.append(html); 70 | } 71 | 72 | // 设置文章目录 73 | articleDirectory(); 74 | } 75 | -------------------------------------------------------------------------------- /src/page/common/com-article.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-08-25 15:26 6 | * ---------------------------------------------- 7 | * @describe: 文章页公共处理部分 8 | * 由于书单页、友链页等部分页面基础是文章页,所以共通部分提取至此来处理 9 | */ 10 | import articleInfo from '../../components/articleInfo/articleInfo'; 11 | import comment from '../../components/comment/comment'; 12 | import articleSuffix from '../../components/articleSuffix/articleSuffix'; 13 | import articleDirectory from '../../components/articleDirectory/articleDirectory'; 14 | import greenChannel from '../../components/greenChannel/greenChannel'; 15 | 16 | export default function main() { 17 | /** 18 | * 设置文章banner动效 19 | */ 20 | 21 | $.__config.animate.articleBanner.enable && 22 | import(/* webpackChunkName: "nh-banner-animation" */ '../../style/nhBannerAnimation.css'); 23 | 24 | /** 25 | * 清除文章页冲突样式 26 | */ 27 | const postMain = $('#main'); 28 | const elementsToModify = postMain.find('.cnblogs-markdown, .cnblogs-post-body'); 29 | elementsToModify.removeClass('cnblogs-markdown cnblogs-post-body'); 30 | // 延迟删除类名 31 | [...Array(11).keys()].forEach((i) => { 32 | setTimeout(() => { 33 | elementsToModify.removeClass('cnblogs-markdown cnblogs-post-body'); 34 | }, i * 500); 35 | }); 36 | 37 | // 设置文章信息 38 | articleInfo(); 39 | 40 | // 设置文章目录 41 | articleDirectory(); 42 | 43 | // 设置文章底部信息按钮 44 | greenChannel(); 45 | 46 | // 设置文章后缀 47 | articleSuffix(); 48 | 49 | // 设置评论框 50 | comment(); 51 | } 52 | -------------------------------------------------------------------------------- /src/page/home.js: -------------------------------------------------------------------------------- 1 | import { request } from '../utils/request'; 2 | 3 | export default function main() { 4 | // 设置主页标语 5 | $('#homeTopTitle span').text($.__config.info.name); 6 | 7 | // 博客名字动效 8 | if ($.__config.animate.homeBannerTitle.enable) { 9 | const titleSpan = $('#homeTopTitle span'); 10 | titleSpan.hover( 11 | () => titleSpan.addClass('pageTitleText'), 12 | () => titleSpan.removeClass('pageTitleText') 13 | ); 14 | } 15 | 16 | // 主页banner动效 17 | if ($.__config.animate.homeBanner.enable) { 18 | import(/* webpackChunkName: "circle-magic" */ '../vendor/circleMagic/circleMagic').then((module) => { 19 | $('.main-header').circleMagic($.__config.animate.homeBanner.options); 20 | }); 21 | } 22 | 23 | // 头图点击滚动到内容位置 24 | $('.scroll-down').click(function () { 25 | const endScroll = $('#home').offset().top + 10; 26 | $.__tools.actScroll(endScroll, 500); 27 | }); 28 | 29 | // 设置主页文章信息样式 30 | $('#main .c_b_p_desc_readmore').text('阅读全文 »'); 31 | const allTitles = $('#main .postTitle, #main .entrylistPosttitle'); 32 | $.each(allTitles, (i, titleElement) => { 33 | let title = $(titleElement), 34 | titleText = title.text(), 35 | postDescText = title.nextAll('.postDesc:eq(0), .entrylistItemPostDesc:eq(0)').text(); 36 | title.after(postMetaHtml(postDescText)); 37 | if (title.hasClass('postTitle') && /\[置顶\]/.test(titleText)) { 38 | title.append('置顶'); 39 | title.find('a').text(titleText.replace(/\[置顶\]/, '')); 40 | } 41 | }); 42 | function postMetaHtml(postDescText) { 43 | const { date, vnum, cnum, tnum } = $.__tools.handlePostDesc(postDescText); 44 | return ` `; 50 | } 51 | 52 | // 设置摘要文章 53 | const descElements = $('.c_b_p_desc'); 54 | descElements.each((i, element) => { 55 | const $obj = $(element); 56 | const $img = $obj.find('img.desc_img'); 57 | if ($img.length) { 58 | const src = $img.attr('src'); 59 | $img.hide(); 60 | $obj.addClass('desc-width-60'); 61 | $obj.parent('div').addClass('desc-parent-minheight-150'); 62 | const $newDiv = $('
'); 63 | $newDiv.find('div').css({ 64 | background: `url('${src}') center center / contain no-repeat`, 65 | }); 66 | $obj.after($newDiv); 67 | } 68 | }); 69 | 70 | // 主页的随机一言 71 | let hitokoto = $('#hitokoto'); 72 | let configTitle = $.__config.banner.home.title; 73 | const topTitleList = ['当你凝视深渊时,深渊也在凝视着你。', '有的人25岁就死了,只是到75岁才埋葬']; 74 | 75 | const updateHitokotoDisplay = (content) => { 76 | hitokoto.html(content).css('display', '-webkit-box'); 77 | $.__tools.setDomHomePosition(); 78 | }; 79 | 80 | function fetchAndSetTitle(url) { 81 | request(url) 82 | .then(topTitleContent) 83 | .catch(() => { 84 | const listIndex = $.__tools.randomNum(0, topTitleList.length - 1); 85 | updateHitokotoDisplay(topTitleList[listIndex]); 86 | }); 87 | } 88 | 89 | function topTitleContent(r) { 90 | if (r.status === 'success') { 91 | const { note, content, data } = r; 92 | const poetry = `《${data?.origin?.title}》 - ${data?.origin?.dynasty} - ${data?.origin?.author}`; 93 | updateHitokotoDisplay(note || data.content); 94 | $('#hitokotoAuthor') 95 | .text(content || poetry) 96 | .show(); 97 | } 98 | } 99 | 100 | const titleSources = { 101 | one: 'https://one.oyo.cool/', 102 | jinrishici: 'https://v2.jinrishici.com/one.json', 103 | }; 104 | 105 | 106 | if (Array.isArray(configTitle)&&configTitle.length) { 107 | updateHitokotoDisplay(configTitle[$.__tools.randomNum(0, configTitle.length - 1)]); 108 | return 109 | } 110 | 111 | if (typeof configTitle === 'string') { 112 | updateHitokotoDisplay(configTitle); 113 | return 114 | } 115 | 116 | const titleSource = titleSources[$.__config.banner.home.titleSource]; 117 | if (titleSource) { 118 | fetchAndSetTitle(titleSource); 119 | } else { 120 | const listIndex = $.__tools.randomNum(0, topTitleList.length - 1); 121 | updateHitokotoDisplay(topTitleList[listIndex]); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/page/links.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-08-25 15:27 6 | * ---------------------------------------------- 7 | * @describe: 友链页处理 8 | */ 9 | import comArticle from './common/com-article'; 10 | import '../style/links.css'; 11 | import linksTemp from '../template/links.html'; 12 | import articleDirectory from '../components/articleDirectory/articleDirectory'; 13 | 14 | export default function main() { 15 | // 文章页公共处理 16 | comArticle(); 17 | 18 | // 添加友链 19 | if ($.__config.links.page.length) { 20 | import(/* webpackChunkName: "gf-blink" */ /* webpackPrefetch: true */ '../style/gf-blink.css'); 21 | 22 | const postBody = $('#cnblogs_post_body'); 23 | const articleSuffixFlg = $('.articleSuffix-flg'); 24 | 25 | // 生成友链的html 26 | const generateLinkHtml = (link, index) => { 27 | const { avatar = '', name = '', introduction = '', url = '' } = link; 28 | const icons = ['icon-zhifeiji', 'icon-like-fill', 'icon-flashlight-fill']; 29 | const icon = icons[index % icons.length]; 30 | return $.__tools.batchTempReplacement(linksTemp, [ 31 | ['avatar', avatar], 32 | ['name', name], 33 | ['introduction', introduction], 34 | ['url', url], 35 | ['icon', icon], 36 | ]); 37 | }; 38 | 39 | // 生成完整的友链分类的html 40 | const generateSectionHtml = (data) => { 41 | const { title, icon, style, links } = data; 42 | const sectionTitle = title ? `

${title}

` : ''; 43 | const linksHtml = links.map(generateLinkHtml).join(''); 44 | return `${sectionTitle}`; 45 | }; 46 | 47 | const linksHtml = $.__config.links.page.map(generateSectionHtml).join(''); 48 | 49 | // 插入模版 50 | articleSuffixFlg.length ? articleSuffixFlg.before(linksHtml) : postBody.append(linksHtml); 51 | } 52 | 53 | articleDirectory(); 54 | } 55 | -------------------------------------------------------------------------------- /src/style/articleDirectory.css: -------------------------------------------------------------------------------- 1 | #articleDirectory { 2 | position: absolute; 3 | top: calc(40vh + 5px); 4 | right: 0; 5 | width: 260px; 6 | z-index: 1; 7 | max-height: 55vh; 8 | overflow: auto; 9 | box-shadow: 0 4px 11px -2px rgb(37 44 97 / 15%), 0 1px 3px 0 rgb(93 100 148 / 20%); 10 | background: rgba(255, 255, 255, .9); 11 | } 12 | 13 | #articleDirectory.articleDirectoryFixed { 14 | position: fixed; 15 | max-height: 95vh; 16 | top: 5px !important; 17 | } 18 | 19 | #articleDirectory ul { 20 | margin: 0; 21 | padding: 10px 10px 10px 5px; 22 | } 23 | 24 | #articleDirectory ul li { 25 | list-style: none; 26 | text-align: left; 27 | text-overflow: ellipsis; 28 | white-space: nowrap; 29 | margin: 0; 30 | padding: 2px 0; 31 | height: 24px; 32 | cursor: pointer; 33 | } 34 | 35 | .articleDirectory-overflow { 36 | overflow: hidden; 37 | } 38 | 39 | #articleDirectory ul li a { 40 | color: #000; 41 | padding: 0 0 0 10px; 42 | display: inline-block; 43 | width: 100%; 44 | height: 100%; 45 | position: relative; 46 | text-overflow: ellipsis; 47 | white-space: nowrap; 48 | } 49 | 50 | #articleDirectory ul li a:hover, #articleDirectory ul li a.active { 51 | background: rgba(80, 80, 80, .04); 52 | color: #807dd4; 53 | } 54 | 55 | #articleDirectory ul li a:hover::after, #articleDirectory ul li a.active:after { 56 | content: ""; 57 | z-index: 1; 58 | top: 0; 59 | right: 0; 60 | width: 100%; 61 | height: 100%; 62 | position: absolute; 63 | left: 0; 64 | bottom: 0; 65 | display: inline-block; 66 | border-left: 3px solid #807dd4; 67 | } 68 | -------------------------------------------------------------------------------- /src/style/articleSuffix.css: -------------------------------------------------------------------------------- 1 | #articleSuffix { 2 | background-image: linear-gradient(180deg,#fff,#f5f5fa); 3 | box-shadow: 0 4px 11px 0 rgb(37 44 97 / 10%), 0 1px 3px 0 rgb(93 100 148 / 13%); 4 | position: relative; 5 | overflow: hidden; 6 | cursor: pointer; 7 | margin: 0 5px; 8 | color: #3a416f; 9 | border-radius: 4px; 10 | } 11 | 12 | .essaySuffix-eof { 13 | font-weight: 700; 14 | font-size: 16px; 15 | text-align: center; 16 | color: #ddd; 17 | text-indent: 0 18 | } 19 | 20 | #articleSuffix .articleSuffix-bg { 21 | position: absolute; 22 | right: -22px; 23 | top: 0; 24 | bottom: 0; 25 | height: 240px; 26 | margin-top: -23px; 27 | width: 210px; 28 | opacity: .5; 29 | } 30 | 31 | #articleSuffix .articleSuffix-left { 32 | max-width: 140px; 33 | float: left; 34 | padding: 12px; 35 | } 36 | 37 | #articleSuffix .articleSuffix-left img { 38 | width: 128px; 39 | height: 128px; 40 | border: 1px solid #ddd; 41 | padding: 6px; 42 | margin: 0; 43 | display: block; 44 | border-radius: 4px; 45 | } 46 | 47 | #articleSuffix .articleSuffix-right { 48 | height: 160px; 49 | width: calc(100% - 170px); 50 | float: right; 51 | } 52 | 53 | #articleSuffix .articleSuffix-right item { 54 | display:inline-block; 55 | position:absolute; 56 | top: 50%; 57 | transform: translate(0, -50%); 58 | padding-top: 8px; 59 | } 60 | 61 | #articleSuffix .articleSuffix-right li { 62 | list-style: none; 63 | line-height: 1.35em; 64 | } 65 | 66 | #articleSuffix .articleSuffix-right li b { 67 | font-weight: bold; 68 | } -------------------------------------------------------------------------------- /src/style/books.css: -------------------------------------------------------------------------------- 1 | .book-cards { 2 | display: grid; 3 | grid-template-columns: repeat(2, 49%); 4 | grid-column-gap: 20px; 5 | grid-row-gap: 15px; 6 | margin: 5px; 7 | position: relative; 8 | } 9 | 10 | @media only screen and (max-width: 960px) { 11 | .book-cards { 12 | grid-template-columns: repeat(1, 100%); 13 | grid-column-gap: 15px; 14 | grid-row-gap: 10px; 15 | } 16 | } 17 | 18 | .book-card { 19 | margin: 10px 0; 20 | background-color: #fff; 21 | box-shadow: 0 4px 11px -2px rgb(37 44 97 / 10%), 0 1px 3px 0 rgb(93 100 148 / 15%); 22 | border-radius: 4px; 23 | display: flex; 24 | flex-direction: column; 25 | cursor: pointer; 26 | padding: 0 15px 15px 15px; 27 | color: #8b939c; 28 | position: relative; 29 | } 30 | 31 | .book-cards .book-rate i { 32 | margin-right: 1px; 33 | font-size: 13px; 34 | } 35 | 36 | .book-cards .book-card-img { 37 | width: 160px; 38 | margin-top: -35px; 39 | border-radius: 2px; 40 | box-shadow: 0px 1px 7px 2px #c7c9d3; 41 | border-bottom: 1px solid #dcddde; 42 | object-fit: cover; 43 | margin-bottom: 20px; 44 | transition: 0.3s ease; 45 | } 46 | .book-cards .book-card-img:hover { 47 | transform: scale(1.04); 48 | } 49 | 50 | .card-content { 51 | color: #3d4954; 52 | padding: 20px 30px; 53 | overflow: hidden; 54 | position: relative; 55 | } 56 | 57 | .book-cards .book-name { 58 | font-weight: 500; 59 | text-overflow: ellipsis; 60 | overflow: hidden; 61 | white-space: nowrap; 62 | font-family: 'ZCOOL XiaoWei',serif; 63 | font-size: 16px; 64 | } 65 | 66 | .book-cards .book-by { 67 | font-size: 13px; 68 | color: #bbb; 69 | margin-top: 4px; 70 | position: absolute; 71 | bottom: 6px; 72 | right: 10px; 73 | } 74 | 75 | .book-cards .book-by i { 76 | font-size: 14px; 77 | margin: 0 4px; 78 | display: none; 79 | } 80 | 81 | .book-cards .book-rate > label { 82 | color: #cccccc; 83 | } 84 | 85 | .book-cards .rate { 86 | display: inline-block; 87 | white-space: nowrap; 88 | overflow: hidden; 89 | text-overflow: ellipsis; 90 | width: 100%; 91 | } 92 | 93 | .book-rate > input:checked ~ label, 94 | .book-rate:not(:checked) > label:hover, 95 | .book-rate:not(:checked) > label:hover ~ label { 96 | color: #ff9700; 97 | } 98 | 99 | .book-rate > input:checked + label:hover, 100 | .book-rate > input:checked ~ label:hover, 101 | .book-rate > label:hover ~ input:checked ~ label, 102 | .book-rate > input:checked ~ label:hover ~ label { 103 | color: #ff9700; 104 | } 105 | 106 | .book-cards .card-vote { 107 | color: #8b939c; 108 | font-size: 13px; 109 | } 110 | 111 | .book-cards .card-sum { 112 | color: #8b939c; 113 | font-size: 13px; 114 | line-height: 1.6em; 115 | -webkit-line-clamp: 4; 116 | margin-top: 15px; 117 | } 118 | 119 | .book-cards .content-wrapper { 120 | display: flex; 121 | position: relative; 122 | } 123 | 124 | .book-cards .book-rate i { 125 | color: #ff9700; 126 | font-size: 14px; 127 | font-weight: bold; 128 | } -------------------------------------------------------------------------------- /src/style/links.css: -------------------------------------------------------------------------------- 1 | #links-box { 2 | display: grid; 3 | grid-template-columns: repeat(3,30%); 4 | grid-column-gap: 30px; 5 | grid-row-gap: 10px; 6 | margin: 5px; 7 | position: relative; 8 | } 9 | 10 | @media only screen and (max-width: 960px) { 11 | #links-box { 12 | grid-template-columns: repeat(2, 50%); 13 | } 14 | } 15 | 16 | @media only screen and (max-width: 720px) { 17 | #links-box { 18 | grid-template-columns: repeat(1, 100%); 19 | } 20 | } 21 | 22 | #links-box .links-item { 23 | width: 250px; 24 | position: relative; 25 | padding: 0 6px; 26 | max-width: 100%; 27 | height: 70px; 28 | align-items: center; 29 | display: flex; 30 | border-radius: 6px; 31 | background-color: #fff; 32 | margin: 10px 5px; 33 | color: rgba(107,114,128,1); 34 | cursor:pointer; 35 | justify-self: center; 36 | box-shadow: 0 1px 7px 2px #c7c9d3; 37 | } 38 | 39 | #links-box .links-item:hover { 40 | transform: scale(1.04); 41 | } 42 | 43 | #links-box .links-item > img { 44 | width: 60px; 45 | height: 60px; 46 | border-radius: 6px; 47 | display: block; 48 | vertical-align: middle; 49 | } 50 | 51 | #links-box .links-item .links-info { 52 | margin-left: 10px; 53 | width: 180px; 54 | } 55 | 56 | #links-box .links-item .links-info .links-info-name { 57 | overflow: hidden; 58 | white-space: nowrap; 59 | text-overflow: ellipsis; 60 | font-weight: bold; 61 | color: #777aaf; 62 | font-size: 1.5rem; 63 | position: relative; 64 | top: -2px; 65 | } 66 | 67 | #links-box .links-item .links-info .links-info-text { 68 | font-style: oblique; 69 | font-size: 14px; 70 | font-family: ZCOOL XiaoWei,serif; 71 | text-overflow: ellipsis; 72 | overflow: hidden; 73 | white-space: nowrap; 74 | width: 100%; 75 | } 76 | 77 | #links-box .links-item .links-info span { 78 | display: block; 79 | } 80 | 81 | #links-box .links-item .links-icon { 82 | width: 22px; 83 | height: 22px; 84 | position: absolute; 85 | top: 0; 86 | right: 0; 87 | margin-right: -8px; 88 | margin-top: -7px; 89 | align-items: center; 90 | display: flex; 91 | border-radius: 6px; 92 | -webkit-transform: rotate(360deg); 93 | animation: rotation 3s linear infinite; 94 | -moz-animation: rotation 3s linear infinite; 95 | -webkit-animation: rotation 3s linear infinite; 96 | -o-animation: rotation 3s linear infinite; 97 | box-shadow: 0 1px 7px 2px #c7c9d3; 98 | transition: .3s ease; 99 | } 100 | 101 | #links-box .links-item:nth-child(3n+0) .links-icon { 102 | background-color: rgba(52,211,153,1); 103 | } 104 | 105 | #links-box .links-item:nth-child(3n+1) .links-icon { 106 | background-color: rgba(167,139,250,1); 107 | } 108 | 109 | #links-box .links-item:nth-child(3n+2) .links-icon { 110 | background-color: #f87171; 111 | } 112 | 113 | #links-box .links-item .links-icon a { 114 | color: #fff; 115 | --transform-rotate: -45deg; 116 | transform: rotate(-45deg); 117 | } 118 | 119 | #links-box .links-item .links-icon a i.icon-zhifeiji { 120 | position: relative; 121 | top: 3px; 122 | left: 2px; 123 | font-size: 14px; 124 | } 125 | 126 | #links-box .links-item .links-icon a i.icon-like-fill, 127 | #links-box .links-item .links-icon a i.icon-flashlight-fill { 128 | position: relative; 129 | top: 4px; 130 | left: 3px; 131 | font-size: 14px; 132 | } 133 | 134 | @-webkit-keyframes rotation { 135 | from {-webkit-transform: rotate(0deg);} 136 | to {-webkit-transform: rotate(360deg);} 137 | } 138 | -------------------------------------------------------------------------------- /src/style/mouse.css: -------------------------------------------------------------------------------- 1 | /*html {*/ 2 | /* cursor: none;*/ 3 | /*}*/ 4 | 5 | .cursor { 6 | border-radius: 50%; 7 | background: #333; 8 | } 9 | 10 | .cursor-f { 11 | top: 0; 12 | left: 0; 13 | background-image: url("data:image/svg+xml,%3Csvg width='47' height='47' viewBox='0 0 47 47' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M42.4202 42.4202C38.8403 46 33.3594 46 23.5 46C13.6406 46 8.15966 46 4.57983 42.4202C1 38.8403 1 33.3594 1 23.5C1 13.6406 1 8.15966 4.57983 4.57983C8.15966 1 13.6406 1 23.5 1C33.3594 1 38.8403 1 42.4202 4.57983C46 8.15966 46 13.6406 46 23.5C46 33.3594 46 38.8403 42.4202 42.4202Z' stroke='black'/%3E%3C/svg%3E%0A"); 14 | background-size: cover; 15 | opacity: 0.7; 16 | } 17 | 18 | .cursor, .cursor-f { 19 | width: var(--size); 20 | height: var(--size); 21 | position: absolute; 22 | z-index: 999; 23 | pointer-events: none; 24 | } -------------------------------------------------------------------------------- /src/style/nhBannerAnimation.css: -------------------------------------------------------------------------------- 1 | #nhBannerAnimation { 2 | width: 100%; 3 | height: 100%; 4 | position: absolute; 5 | z-index: 1; 6 | } 7 | 8 | #nhBannerAnimation .circles { 9 | position: absolute; 10 | top: 0; 11 | left: 0; 12 | width: 100%; 13 | height: 100%; 14 | overflow: hidden; 15 | } 16 | 17 | #nhBannerAnimation .circles li { 18 | position: absolute; 19 | display: block; 20 | list-style: none; 21 | width: 20px; 22 | height: 20px; 23 | background: rgba(255, 255, 255, 0.2); 24 | animation: nhBannerAnimation 25s linear infinite; 25 | bottom: -150px; 26 | 27 | } 28 | 29 | #nhBannerAnimation .circles li:nth-child(1) { 30 | left: 25%; 31 | width: 80px; 32 | height: 80px; 33 | animation-delay: 0s; 34 | } 35 | 36 | 37 | #nhBannerAnimation .circles li:nth-child(2) { 38 | left: 10%; 39 | width: 20px; 40 | height: 20px; 41 | animation-delay: 2s; 42 | animation-duration: 12s; 43 | } 44 | 45 | #nhBannerAnimation .circles li:nth-child(3) { 46 | left: 70%; 47 | width: 20px; 48 | height: 20px; 49 | animation-delay: 4s; 50 | } 51 | 52 | #nhBannerAnimation .circles li:nth-child(4) { 53 | left: 40%; 54 | width: 60px; 55 | height: 60px; 56 | animation-delay: 0s; 57 | animation-duration: 18s; 58 | } 59 | 60 | #nhBannerAnimation .circles li:nth-child(5) { 61 | left: 65%; 62 | width: 20px; 63 | height: 20px; 64 | animation-delay: 0s; 65 | } 66 | 67 | #nhBannerAnimation .circles li:nth-child(6) { 68 | left: 75%; 69 | width: 110px; 70 | height: 110px; 71 | animation-delay: 3s; 72 | } 73 | 74 | #nhBannerAnimation .circles li:nth-child(7) { 75 | left: 35%; 76 | width: 150px; 77 | height: 150px; 78 | animation-delay: 7s; 79 | } 80 | 81 | #nhBannerAnimation .circles li:nth-child(8) { 82 | left: 50%; 83 | width: 25px; 84 | height: 25px; 85 | animation-delay: 15s; 86 | animation-duration: 45s; 87 | } 88 | 89 | #nhBannerAnimation .circles li:nth-child(9) { 90 | left: 20%; 91 | width: 15px; 92 | height: 15px; 93 | animation-delay: 2s; 94 | animation-duration: 35s; 95 | } 96 | 97 | #nhBannerAnimation .circles li:nth-child(10) { 98 | left: 85%; 99 | width: 150px; 100 | height: 150px; 101 | animation-delay: 0s; 102 | animation-duration: 11s; 103 | } 104 | 105 | 106 | @keyframes nhBannerAnimation { 107 | 108 | 0% { 109 | transform: translateY(0) rotate(0deg); 110 | opacity: 1; 111 | border-radius: 0; 112 | } 113 | 114 | 100% { 115 | transform: translateY(-1000px) rotate(720deg); 116 | opacity: 0; 117 | border-radius: 50%; 118 | } 119 | 120 | } -------------------------------------------------------------------------------- /src/style/particles.css: -------------------------------------------------------------------------------- 1 | #particles { 2 | position: fixed; 3 | left: 0; 4 | top: 0; 5 | width: 100vw; 6 | height: 100vh; 7 | overflow: hidden; 8 | opacity: .6; 9 | z-index: -2; 10 | pointer-events: none 11 | } 12 | 13 | #particles .particles-layer { 14 | position: absolute; 15 | top: -5%; 16 | left: -5%; 17 | width: 110%; 18 | height: 110%; 19 | background-repeat: repeat; 20 | background-position: center center; 21 | opacity: 0; 22 | display: block 23 | } 24 | 25 | #particles .particles-layer--1 { 26 | background-image: url('https://cdn.jsdelivr.net/gh/wangyang0210/pic/imgs/project/cnblogs/bg-pattern-1.svg') 27 | } 28 | 29 | #particles .particles-layer--2 { 30 | background-image: url('https://cdn.jsdelivr.net/gh/wangyang0210/pic/imgs/project/cnblogs/bg-pattern-2.svg') 31 | } 32 | 33 | #particles .particles-layer--3 { 34 | background-image: url('https://cdn.jsdelivr.net/gh/wangyang0210/pic/imgs/project/cnblogs/bg-pattern-3.svg') 35 | } 36 | 37 | @media (max-width: 767px) { 38 | #particles { 39 | display: none; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/template/articleDirectory.html: -------------------------------------------------------------------------------- 1 |
2 | 7 |
-------------------------------------------------------------------------------- /src/template/articleSuffix.html: -------------------------------------------------------------------------------- 1 | 2 |

__EOF__

3 |
4 |
5 | 6 | 7 | 8 |
9 |
10 | 11 |
12 |
13 | 14 |
  • 15 | ##origin##文作者: 16 | ##author## 17 |
  • 18 |
  • 19 | ##origin##文链接: 20 | ##source## 21 |
  • 22 |
  • 23 | 关于博主: 24 | ##aboutHtml## 25 |
  • 26 |
  • 27 | 版权声明: 28 | ##copyrightHtml## 29 |
  • 30 |
  • 31 | 声援博主: 32 | ##supportHtml## 33 |
  • 34 |
    35 |
    36 |
    37 |
    38 |
    39 | -------------------------------------------------------------------------------- /src/template/banner.html: -------------------------------------------------------------------------------- 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 | 32 |
    -------------------------------------------------------------------------------- /src/template/books.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | 4 |
    5 |
    ##name##
    6 |
    7 |
    8 | ##scoreHtml## 9 |
    10 | 11 | ##infoHtml## 12 | 13 |
    14 |
    15 |
    16 |
    17 | ##readDate## 18 | ##readPercentage## 19 |
    20 |
    -------------------------------------------------------------------------------- /src/template/dayNight.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |
    5 |
    6 |
    7 |
    8 |
    9 |
    10 |
    11 |
    12 |
    13 |
    14 |
    15 |
    16 |
    17 |
    -------------------------------------------------------------------------------- /src/template/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
    4 | 5 |
    6 |
    7 |
    8 |
    9 |
    10 | 35 | 36 | -------------------------------------------------------------------------------- /src/template/links.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/template/particles.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |
    5 |
    -------------------------------------------------------------------------------- /src/template/rtMenu.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 | 9 | 10 | 16 | 17 | 18 | 22 | 23 | 27 | 28 | 44 | 45 | 55 | 56 |
    57 | 58 | 已关注 59 | 60 | 61 |
    62 | 63 | 105 |
    106 | 107 |
    108 | 109 | 点击开启 110 | 111 | 112 |
    113 | 114 |
    115 | 116 | 返回顶部 117 | 118 |
    119 | 120 |
    121 |
    122 |
    -------------------------------------------------------------------------------- /src/template/sidebarNav.html: -------------------------------------------------------------------------------- 1 | 6 | 11 | 12 | 17 | 18 | 23 | -------------------------------------------------------------------------------- /src/utils/request.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/wangyang0210 3 | * https://www.cnblogs.com/wangyang0210/ 4 | * @author: WangYang, i@oyo.cool 5 | * @Date 2022-08-25 15:28 6 | * ---------------------------------------------- 7 | * @describe: fetch封装 8 | */ 9 | 10 | export async function request(url = '', method = 'GET', data = {}, headers = {}) { 11 | let options = { 12 | method: method, 13 | mode: 'cors', 14 | redirect: 'follow', 15 | referrerPolicy: 'no-referrer', 16 | }; 17 | if (Object.keys(headers).length) { 18 | options.headers = headers; 19 | } 20 | if (Object.keys(data).length) { 21 | options.body = JSON.stringify(data); 22 | } 23 | const response = await fetch(url, options); 24 | return response.json(); 25 | } 26 | -------------------------------------------------------------------------------- /src/vendor/circleMagic/circleMagic.js: -------------------------------------------------------------------------------- 1 | ;(function ($) { 2 | $.fn.circleMagic = function (options) { 3 | 4 | let width, height, canvas, ctx, animateHeader = true; 5 | let circles = []; 6 | 7 | let settings = $.extend({ 8 | color: 'rgba(255,255,255,.5)', 9 | radius: 10, 10 | density: 0.3, 11 | clearOffset: 0.2 12 | }, options); 13 | 14 | let container = this['0']; 15 | initContainer(); 16 | addListeners(); 17 | 18 | function initContainer() { 19 | width = container.offsetWidth; 20 | height = container.offsetHeight; 21 | 22 | initCanvas(); 23 | canvas = document.getElementById('homeTopCanvas'); 24 | canvas.width = width; 25 | canvas.height = height; 26 | canvas.style.position = 'absolute'; 27 | canvas.style.left = '0'; 28 | canvas.style.bottom = '0'; 29 | canvas.style.zIndex = '1'; 30 | ctx = canvas.getContext('2d'); 31 | 32 | for (let x = 0; x < width * settings.density; x++) { 33 | let c = new Circle(); 34 | circles.push(c); 35 | } 36 | animate(); 37 | } 38 | 39 | function initCanvas() { 40 | let canvasElement = document.createElement('canvas'); 41 | canvasElement.id = 'homeTopCanvas'; 42 | container.appendChild(canvasElement); 43 | canvasElement.parentElement.style.overflow = 'hidden'; 44 | 45 | } 46 | 47 | function addListeners() { 48 | window.addEventListener('scroll', scrollCheck, false); 49 | window.addEventListener('resize', resize, false); 50 | } 51 | 52 | function scrollCheck() { 53 | document.body.scrollTop > height ? animateHeader = false : animateHeader = true; 54 | } 55 | 56 | function resize() { 57 | width = container.clientWidth; 58 | height = container.clientHeight; 59 | container.height = height + 'px'; 60 | canvas.width = width; 61 | canvas.height = height; 62 | } 63 | 64 | function animate() { 65 | if (animateHeader) { 66 | ctx.clearRect(0, 0, width, height); 67 | for (let i in circles) { 68 | circles[i].draw(); 69 | } 70 | } 71 | requestAnimationFrame(animate); 72 | } 73 | 74 | function randomColor() { 75 | let r = Math.floor(Math.random() * 255); 76 | let g = Math.floor(Math.random() * 255); 77 | let b = Math.floor(Math.random() * 255); 78 | let alpha = Math.random().toPrecision(2); 79 | return 'rgba(' + r + ', ' + g + ', ' + b + ', ' + alpha + ')'; 80 | } 81 | 82 | function Circle() { 83 | let that = this; 84 | (function () { 85 | that.pos = {}; 86 | init(); 87 | })(); 88 | 89 | function init() { 90 | that.pos.x = Math.random() * width; 91 | that.pos.y = height + Math.random() * 100; 92 | that.alpha = 0.1 + Math.random() * settings.clearOffset; 93 | that.scale = 0.1 + Math.random() * 0.3; 94 | that.speed = Math.random(); 95 | settings.color === 'random' ? that.color = randomColor() : that.color = settings.color; 96 | } 97 | 98 | this.draw = function () { 99 | if (that.alpha <= 0) init(); 100 | that.pos.y -= that.speed; 101 | that.alpha -= 0.0005; 102 | ctx.beginPath(); 103 | ctx.arc(that.pos.x, that.pos.y, that.scale * settings.radius, 0, 2 * Math.PI, false); 104 | ctx.fillStyle = that.color; 105 | ctx.fill(); 106 | ctx.closePath(); 107 | }; 108 | } 109 | } 110 | })(jQuery); 111 | -------------------------------------------------------------------------------- /src/vendor/consoleText/consoleText.js: -------------------------------------------------------------------------------- 1 | /** 2 | * UPDATES AND DOCS AT: https://github.com/BNDong 3 | * https://www.cnblogs.com/bndong/ 4 | * @author: BNDong, dbnuo@foxmail.com 5 | * @param words [] 循环文字数组 6 | * @param id string 文字domId 7 | * @param conId string 符合domId 8 | * @param colors [] 颜色 9 | * @param isCycle boolean 是否循环 10 | * @param callback fun 每个文字设置后回调 11 | */ 12 | export default function main(words, id, containerId, isCycle) { 13 | let textIndex = 0; 14 | let visible = true; 15 | let containerElement = document.getElementById(containerId); 16 | let targetElement = document.getElementById(id); 17 | containerElement.innerHTML = '_'; 18 | 19 | const deleteText = () => { 20 | targetElement.innerHTML = targetElement.innerHTML.slice(0, -1) 21 | if (targetElement.innerHTML.length > 0) { 22 | setTimeout(deleteText, 200) 23 | } else { 24 | textIndex = 0 25 | setTimeout(typeWriter, 200) 26 | } 27 | } 28 | const typeWriter = () => { 29 | targetElement.innerHTML += words[textIndex++] 30 | if (textIndex < words.length) { 31 | setTimeout(typeWriter, 200) 32 | } else if (isCycle) { 33 | setTimeout(() => { deleteText() }, 1000) 34 | } 35 | } 36 | 37 | window.setInterval(() => { 38 | if (visible) { 39 | containerElement.style.visibility = 'hidden'; 40 | visible = false; 41 | } else { 42 | containerElement.style.visibility = 'visible'; 43 | visible = true; 44 | } 45 | }, 400); 46 | setTimeout(typeWriter, 200); 47 | } 48 | --------------------------------------------------------------------------------