feat:Style optimization, addition of background configuration options, brightness, and theme.
1
dist/css/app.4bb21bc8.css
vendored
1
dist/css/chunk-vendors.0d1c5105.css
vendored
BIN
dist/favicon.ico
vendored
Before Width: | Height: | Size: 274 B |
BIN
dist/fonts/element-icons.abe71f7d.ttf
vendored
BIN
dist/fonts/element-icons.d9491be2.woff
vendored
1
dist/img/add.ca18f050.svg
vendored
@ -1 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1626099491673" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2195" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M560.54 553.96m-300.58 0a300.58 300.58 0 1 0 601.16 0 300.58 300.58 0 1 0-601.16 0Z" fill="#E03B5D" p-id="2196"></path><path d="M515.4 954A448 448 0 0 1 198.56 189.1a448 448 0 1 1 633.68 633.68A445.14 445.14 0 0 1 515.4 954z m0-844.14c-218.4 0-396 177.66-396 396s177.68 396 396 396 396-177.68 396-396-177.6-395.98-396-395.98z" fill="#231815" p-id="2197"></path><path d="M487.06 212.12m24 0l8.7 0q24 0 24 24l0 539.62q0 24-24 24l-8.7 0q-24 0-24-24l0-539.62q0-24 24-24Z" fill="#231815" p-id="2198"></path><path d="M519.74 800.76h-8.68a25.02 25.02 0 0 1-25-25V236.12a25.02 25.02 0 0 1 25-25h8.68a25.02 25.02 0 0 1 25 25v539.64a25.02 25.02 0 0 1-25 25z m-8.68-587.64a23.02 23.02 0 0 0-23 23v539.64a23.02 23.02 0 0 0 23 23h8.68a23.02 23.02 0 0 0 23-23V236.12a23.02 23.02 0 0 0-23-23z" fill="#231815" p-id="2199"></path><path d="M809.22 476.22m0 24l0 8.7q0 24-24 24l-539.62 0q-24 0-24-24l0-8.7q0-24 24-24l539.62 0q24 0 24 24Z" fill="#231815" p-id="2200"></path><path d="M785.22 534H245.58a25.02 25.02 0 0 1-25-25v-8.68a25.02 25.02 0 0 1 25-25h539.64a25.02 25.02 0 0 1 25 25v8.68a25.02 25.02 0 0 1-25 25z m-539.64-56.78a23.02 23.02 0 0 0-23 23v8.68a23.02 23.02 0 0 0 23 23h539.64a23.02 23.02 0 0 0 23-23v-8.68a23.02 23.02 0 0 0-23-23z" fill="#231815" p-id="2201"></path></svg>
|
Before Width: | Height: | Size: 1.6 KiB |
BIN
dist/img/bg.18b122a7.jpg
vendored
Before Width: | Height: | Size: 295 KiB |
1
dist/img/blog.f57ba53d.svg
vendored
@ -1 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1625141545685" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2501" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M615.98 656.9m-300.58 0a300.58 300.58 0 1 0 601.16 0 300.58 300.58 0 1 0-601.16 0Z" fill="#E03B5D" p-id="2502"></path><path d="M771.7 931H245.82c-76.58 0-138.9-60.44-138.9-134.72V479.36a133.16 133.16 0 0 1 46.14-100.28L416 150.28a142 142 0 0 1 185.52 0l262.94 228.8a133.16 133.16 0 0 1 46.14 100.28v316.92c0 74.28-62.32 134.72-138.9 134.72zM508.76 166.74a90 90 0 0 0-59.26 22L186.56 417.58A82.12 82.12 0 0 0 158 479.36v316.92C158 842.42 197.38 880 245.82 880h525.88c48.44 0 87.86-37.54 87.86-83.68V479.36a82.12 82.12 0 0 0-28.6-61.78L568 188.78a90.12 90.12 0 0 0-59.24-22.04z" fill="#231815" p-id="2503"></path><path d="M362.78 734.16m28.34 0l241.76 0q28.34 0 28.34 28.34l0 3.1q0 28.34-28.34 28.34l-241.76 0q-28.34 0-28.34-28.34l0-3.1q0-28.34 28.34-28.34Z" fill="#231815" p-id="2504"></path><path d="M632.88 794.92H391.12a29.38 29.38 0 0 1-29.34-29.34v-3.08a29.38 29.38 0 0 1 29.34-29.34h241.76a29.38 29.38 0 0 1 29.34 29.34v3.08a29.38 29.38 0 0 1-29.34 29.34z m-241.76-59.76a27.36 27.36 0 0 0-27.34 27.34v3.08a27.36 27.36 0 0 0 27.34 27.34h241.76a27.36 27.36 0 0 0 27.34-27.34v-3.08a27.36 27.36 0 0 0-27.34-27.34z" fill="#231815" p-id="2505"></path></svg>
|
Before Width: | Height: | Size: 1.5 KiB |
1
dist/img/file.807fb7b5.svg
vendored
@ -1 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1624769226567" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1298" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M698.0096 632.064m-212.7872 0a212.7872 212.7872 0 1 0 425.5744 0 212.7872 212.7872 0 1 0-425.5744 0Z" fill="#FF8080" p-id="1299"></path><path d="M771.9936 870.4H255.3856c-82.6368 0-149.8624-67.2256-149.8624-149.8624V317.7472c0-82.6368 67.2256-149.9136 149.8624-149.9136h92.3136c29.2864 0 57.8048 10.3424 80.2816 29.184l88.5248 74.1888c4.1472 3.4816 9.472 5.4272 14.8992 5.4272h240.5376c82.6368 0 149.8624 67.2256 149.8624 149.9136v294.0416c0.0512 82.5856-67.1744 149.8112-149.8112 149.8112zM255.3856 219.0336c-54.4256 0-98.6624 44.288-98.6624 98.7136v402.7904c0 54.4256 44.288 98.6624 98.6624 98.6624h516.608c54.4256 0 98.6624-44.288 98.6624-98.6624V426.496c0-54.4256-44.288-98.7136-98.6624-98.7136H531.456c-17.4592 0-34.4064-6.1952-47.7696-17.3568L395.0592 236.288a73.94816 73.94816 0 0 0-47.36-17.2544H255.3856z" fill="#512C56" p-id="1300"></path><path d="M629.6064 550.7072h-90.368V460.3392c0-14.1312-11.4688-25.6-25.6-25.6s-25.6 11.4688-25.6 25.6v90.368H397.7216c-14.1312 0-25.6 11.4688-25.6 25.6s11.4688 25.6 25.6 25.6h90.368v90.368c0 14.1312 11.4688 25.6 25.6 25.6s25.6-11.4688 25.6-25.6v-90.368h90.368c14.1312 0 25.6-11.4688 25.6-25.6s-11.4688-25.6-25.6512-25.6z" fill="#512C56" p-id="1301"></path></svg>
|
Before Width: | Height: | Size: 1.6 KiB |
1
dist/img/logo.f38dc2e8.svg
vendored
@ -1 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1624778788435" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10366" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M604.22 630.62m-300.58 0a300.58 300.58 0 1 0 601.16 0 300.58 300.58 0 1 0-601.16 0Z" fill="#E03B5D" p-id="10367"></path><path d="M323.1 430.26a48.72 48.72 0 0 1-48.7-48.68V119.04a26 26 0 0 1 52 0v254.82l53.28-50.4a48.74 48.74 0 0 1 68.8 1.88l1.06 1.2L486 370.1V119.04a26 26 0 1 1 52 0v260.28a48.68 48.68 0 0 1-84 33.46l-1.06-1.18-40.1-48-56.28 53.24a48.58 48.58 0 0 1-33.46 13.42z" fill="#231815" p-id="10368"></path><path d="M788.64 962H265.28a140.84 140.84 0 0 1-140.68-140.74V232.44a140.84 140.84 0 0 1 140.68-140.7h523.36a140.86 140.86 0 0 1 140.7 140.7v588.82A140.86 140.86 0 0 1 788.64 962zM265.28 146.36a86.16 86.16 0 0 0-86 86v588.9a86.16 86.16 0 0 0 86 86h523.36a86.18 86.18 0 0 0 86-86V232.44a86.18 86.18 0 0 0-86-86z" fill="#231815" p-id="10369"></path></svg>
|
Before Width: | Height: | Size: 1.1 KiB |
1
dist/img/search.c77e1385.svg
vendored
@ -1 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1624771399713" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2852" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M446.112 177.545c137.568 0.22 252.613 104.598 266.163 241.493 13.563 136.896-78.778 261.819-213.618 289.009-134.853 27.203-268.386-52.157-308.945-183.609s25.018-272.252 151.738-325.78a267.236 267.236 0 0 1 104.662-21.113m0-62.06c-182.794 0-330.99 148.195-330.99 330.99s148.196 330.99 330.99 330.99 330.99-148.196 330.99-330.99-148.195-330.99-330.99-330.99z m431.322 793.34a30.85 30.85 0 0 1-21.941-9.101l-157.22-157.22c-11.753-12.18-11.585-31.535 0.374-43.508 11.973-11.972 31.328-12.14 43.494-0.375l157.22 157.22a31.037 31.037 0 0 1 6.724 33.81 31.004 31.004 0 0 1-28.651 19.175z m0 0" p-id="2853"></path></svg>
|
Before Width: | Height: | Size: 989 B |
1
dist/img/translate.fa0bf271.svg
vendored
@ -1 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1625141560343" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2813" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M424.42 531.9m-303.48 0a303.48 303.48 0 1 0 606.96 0 303.48 303.48 0 1 0-606.96 0Z" fill="#E03B5D" p-id="2814"></path><path d="M468.1 886c-225.52 0-408.98-183.5-408.98-409.02S242.58 68 468.1 68s408.98 183.46 408.98 408.98S693.62 886 468.1 886z m0-766c-196.84 0-356.98 160.14-356.98 356.98S271.26 834 468.1 834s356.98-160.14 356.98-356.98S664.94 120 468.1 120z" fill="#231815" p-id="2815"></path><path d="M217.36 636.7A26 26 0 0 1 194 622.14a311.58 311.58 0 0 1 142.44-416.98 26 26 0 1 1 22.9 46.68c-128.48 63.06-181.72 218.9-118.66 347.4a26 26 0 0 1-23.32 37.46z" fill="#231815" p-id="2816"></path><path d="M703.718732 766.595201m20.039406-20.039406l0.014142-0.014142q20.039406-20.039406 40.078812 0l150.104628 150.104627q20.039406 20.039406 0 40.078813l-0.014142 0.014142q-20.039406 20.039406-40.078813 0l-150.104627-150.104628q-20.039406-20.039406 0-40.078812Z" fill="#231815" p-id="2817"></path><path d="M894 946a29.22 29.22 0 0 1-20.74-8.58l-150.1-150.1a29.34 29.34 0 0 1 41.5-41.5l150 150.18a29.38 29.38 0 0 1 0 41.5A29.26 29.26 0 0 1 894 946z m-150.2-206.72a27.36 27.36 0 0 0-19.32 46.72l150 150a27.34 27.34 0 1 0 38.68-38.66l-150.1-150.1a27.14 27.14 0 0 0-19.26-7.96z" fill="#231815" p-id="2818"></path></svg>
|
Before Width: | Height: | Size: 1.6 KiB |
1
dist/img/user.6e444b4a.svg
vendored
@ -1 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1625141521003" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2190" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M626.44 662.52m-244.78 0a244.78 244.78 0 1 0 489.56 0 244.78 244.78 0 1 0-489.56 0Z" fill="#E03B5D" p-id="2191"></path><path d="M791.86 919.74H239.1a139.54 139.54 0 0 1-139.38-139.4v-64.52a139.54 139.54 0 0 1 139.38-139.38h552.76a139.54 139.54 0 0 1 139.38 139.38v64.52a139.54 139.54 0 0 1-139.38 139.4zM239.1 628.44a87.48 87.48 0 0 0-87.38 87.38v64.52a87.48 87.48 0 0 0 87.38 87.4h552.76a87.48 87.48 0 0 0 87.38-87.4v-64.52a87.48 87.48 0 0 0-87.38-87.38z" fill="#231815" p-id="2192"></path><path d="M515.48 628.88c-153.48 0-278.44-124.88-278.44-278.44S362 72 515.48 72 794 196.92 794 350.44s-125 278.44-278.52 278.44z m0-504.86A226.44 226.44 0 1 0 742 350.44 226.68 226.68 0 0 0 515.48 124z" fill="#231815" p-id="2193"></path><path d="M339.06 376.44a26 26 0 0 1-26-26A199.18 199.18 0 0 1 512 151.5a26 26 0 0 1 0 52 147.12 147.12 0 0 0-146.94 146.94 26 26 0 0 1-26 26z" fill="#231815" p-id="2194"></path></svg>
|
Before Width: | Height: | Size: 1.3 KiB |
21
dist/index.html
vendored
@ -1,21 +0,0 @@
|
||||
<!DOCTYPE html><html lang="en" style="height: 100%;"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><link href="./static/css/bootstrap.css" rel="stylesheet"><link href="./static/css/style.css" rel="stylesheet"><link href="./static/css/index.css" rel="stylesheet"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0"><meta name="keywords" content="红隼书签, docschina, JavaScript, webpack, Node.js, Vue, React, Babel, Parcel, Rollup, RxJS, ECMAScript, Koa, Preact, PostCSS, 开源翻译, 开源技术文档, 中文文档, Web 前端中文文档, webpack 中文文档, doc.webpack-china.org, Node.js 中文文档, nodejs.cn, Vue.js 中文文档, vuefe.cn, React 中文文档, doc.react-china.org, Babel 中文文档, babeljs.cn, Parcel 中文文档, parceljs.io, Rollup 中文文档, rollupjs.cn, RxJS 中文文档, ECMAScript 中文文档, Koa 中文文档, koajs.cn, Preact 中文文档, Polymer, TypeScript, Element UI, iView UI, Vuetify, San, Lavas, Mint UI, Ant Design, ThinkJS, egg, Express, ESLint, 前端周刊, JavaScript Weekly, Node Weekly, Vue News, CSS Weekly, react status, Frontend Focus, Mobile Dev Weekly, Bitcoin Weekly, Golang Weekly"><meta name="description" content="红隼书签,深入挖掘国外前端新领域,为中国 Web 前端开发人员提供优质文档!!"><meta name="author" content="leehey, lizhihua, liqichang"><title>红隼书签-为中国 Web 前端开发人员提供优质网站导航</title><link href="css/app.4bb21bc8.css" rel="preload" as="style"><link href="css/chunk-vendors.0d1c5105.css" rel="preload" as="style"><link href="js/app.d8cd24ca.js" rel="preload" as="script"><link href="js/chunk-vendors.c88644cf.js" rel="preload" as="script"><link href="css/chunk-vendors.0d1c5105.css" rel="stylesheet"><link href="css/app.4bb21bc8.css" rel="stylesheet"></head><body style="height:100%;margin: 0;"><noscript><strong>We're sorry but luotian-dev doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app" style="height: 100%;"></div><div id="mybookmark" style="height: 100%;display: none;opacity: 0;"></div><canvas id="canvas-complex" style="width:100vw;height:100vh;position: absolute;z-index:-99;top:0;opacity: 0.35;"></canvas><div class="demo-2"><div class="content"><div id="large-header" class="large-header"><canvas id="demo-canvas"></canvas></div></div></div><script src="./static/js/granim.min.js"></script><script src="./static/js/bg.js"></script><script>// 也可以切换成其他背景
|
||||
var granimInstance = new Granim({
|
||||
element: '#canvas-complex',
|
||||
direction: 'left-right',
|
||||
isPausedWhenNotInView: true,
|
||||
states: {
|
||||
"default-state": {
|
||||
gradients: [
|
||||
[
|
||||
{ color: '#833ab4', pos: .2 },
|
||||
{ color: '#fd1d1d', pos: .8 },
|
||||
{ color: '#38ef7d', pos: 1 }
|
||||
], [
|
||||
{ color: '#40e0d0', pos: 0 },
|
||||
{ color: '#ff8c00', pos: .2 },
|
||||
{ color: '#ff0080', pos: .75 }
|
||||
],
|
||||
]
|
||||
}
|
||||
}
|
||||
});</script><script src="js/chunk-vendors.c88644cf.js"></script><script src="js/app.d8cd24ca.js"></script></body></html>
|
2
dist/js/app.d8cd24ca.js
vendored
1
dist/js/app.d8cd24ca.js.map
vendored
64
dist/js/chunk-vendors.c88644cf.js
vendored
1
dist/js/chunk-vendors.c88644cf.js.map
vendored
7
dist/static/css/bootstrap.css
vendored
126
dist/static/css/index.css
vendored
@ -1,126 +0,0 @@
|
||||
*{
|
||||
margin:0px;
|
||||
padding:0px;
|
||||
border:none;
|
||||
outline:none;
|
||||
font-size: 100%;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
body {
|
||||
|
||||
font-size:16px;
|
||||
color:#585f5f;
|
||||
line-height:1.5em;
|
||||
font-weight:400;
|
||||
background:#ffffff;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-font-smoothing: antialiased;
|
||||
font-family: 'Inter', sans-serif;
|
||||
}
|
||||
|
||||
a{
|
||||
text-decoration:none;
|
||||
cursor:pointer;
|
||||
color: #24a77e;
|
||||
}
|
||||
|
||||
.theme_color{
|
||||
color:#24a77e;
|
||||
}
|
||||
|
||||
a:hover,
|
||||
a:focus,
|
||||
a:visited,
|
||||
a:active,
|
||||
button:active{
|
||||
text-decoration:none;
|
||||
outline:none;
|
||||
}
|
||||
|
||||
h1,h2,h3,h4,h5,h6 {
|
||||
position:relative;
|
||||
font-weight:normal;
|
||||
margin:0px 0px 15px;
|
||||
background:none;
|
||||
line-height:1.25em;
|
||||
font-family: 'Libre Baskerville', serif;
|
||||
}
|
||||
|
||||
h1{
|
||||
font-size: 60px;
|
||||
}
|
||||
|
||||
h2{
|
||||
font-size: 48px;
|
||||
}
|
||||
|
||||
h3{
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
h4{
|
||||
font-size: 26px;
|
||||
}
|
||||
|
||||
h5{
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
h6{
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
input,select,button{
|
||||
font-family: 'Inter', sans-serif;
|
||||
}
|
||||
|
||||
textarea{
|
||||
overflow:hidden;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
button{
|
||||
outline: none !important;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
p{
|
||||
font-size: 15px;
|
||||
line-height: 1.7em;
|
||||
font-weight: 400;
|
||||
margin: 0 0 15px;
|
||||
}
|
||||
|
||||
.text{
|
||||
font-size: 15px;
|
||||
line-height: 1.7em;
|
||||
font-weight: 400;
|
||||
margin: 0 0;
|
||||
}
|
||||
|
||||
.clearfix::after{display:block;clear:both;content:""}
|
||||
|
||||
::-webkit-input-placeholder{color: inherit;}
|
||||
::-moz-input-placeholder{color: inherit;}
|
||||
::-ms-input-placeholder{color: inherit;}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width:5px;
|
||||
height:5px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track-piece {
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color:#dddddd;
|
||||
background-clip:padding-box;
|
||||
min-height:28px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background-color:#bbb;
|
||||
}
|
15935
dist/static/css/style.css
vendored
84
dist/static/js/bg.js
vendored
@ -1,84 +0,0 @@
|
||||
(function () {
|
||||
var width; var height; var largeHeader; var canvas; var ctx; var circles; var target; var animateHeader = true
|
||||
// Main
|
||||
initHeader()
|
||||
addListeners()
|
||||
function initHeader() {
|
||||
width = window.innerWidth
|
||||
height = window.innerHeight
|
||||
target = { x: 0, y: height }
|
||||
largeHeader = document.getElementById('large-header')
|
||||
largeHeader.style.height = height + 'px'
|
||||
canvas = document.getElementById('demo-canvas')
|
||||
canvas.width = width
|
||||
canvas.height = height
|
||||
ctx = canvas.getContext('2d')
|
||||
|
||||
// create particles
|
||||
circles = []
|
||||
for (var x = 0; x < width * 0.5; x++) {
|
||||
var c = new Circle()
|
||||
circles.push(c)
|
||||
}
|
||||
animate()
|
||||
}
|
||||
// Event handling
|
||||
function addListeners() {
|
||||
window.addEventListener('scroll', scrollCheck)
|
||||
window.addEventListener('resize', resize)
|
||||
}
|
||||
|
||||
function scrollCheck() {
|
||||
if (document.body.scrollTop > height) animateHeader = false
|
||||
else animateHeader = true
|
||||
}
|
||||
|
||||
function resize() {
|
||||
width = window.innerWidth
|
||||
height = window.innerHeight
|
||||
largeHeader.style.height = height + 'px'
|
||||
canvas.width = width
|
||||
canvas.height = height
|
||||
}
|
||||
|
||||
function animate() {
|
||||
if (animateHeader) {
|
||||
ctx.clearRect(0, 0, width, height)
|
||||
for (var i in circles) {
|
||||
circles[i].draw()
|
||||
}
|
||||
}
|
||||
requestAnimationFrame(animate)
|
||||
}
|
||||
|
||||
// Canvas manipulation
|
||||
function Circle() {
|
||||
var _this = this;
|
||||
|
||||
// constructor
|
||||
(function () {
|
||||
_this.pos = {}
|
||||
init()
|
||||
})()
|
||||
|
||||
function init() {
|
||||
_this.pos.x = Math.random() * width
|
||||
_this.pos.y = height + Math.random() * 100
|
||||
_this.alpha = 0.1 + Math.random() * 0.3
|
||||
_this.scale = 0.1 + Math.random() * 0.3
|
||||
_this.velocity = Math.random()
|
||||
}
|
||||
|
||||
this.draw = function () {
|
||||
if (_this.alpha <= 0) {
|
||||
init()
|
||||
}
|
||||
_this.pos.y -= _this.velocity
|
||||
_this.alpha -= 0.0005
|
||||
ctx.beginPath()
|
||||
ctx.arc(_this.pos.x, _this.pos.y, _this.scale * 20, 0, 2.5 * Math.PI, false)
|
||||
ctx.fillStyle = 'rgba(255,255,255,' + _this.alpha + ')'
|
||||
ctx.fill()
|
||||
}
|
||||
}
|
||||
})()
|
2
dist/static/js/granim.min.js
vendored
1
gitattributes
Normal file
@ -0,0 +1 @@
|
||||
*.js linguist-language=vue
|
14839
package-lock.json
generated
@ -16,7 +16,6 @@
|
||||
<meta name="author" content="leehey, lizhihua, liqichang">
|
||||
<title>红隼书签-为中国 Web 前端开发人员提供优质网站导航</title>
|
||||
</head>
|
||||
|
||||
<body style="height:100%;margin: 0;">
|
||||
<noscript>
|
||||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
|
||||
@ -30,8 +29,7 @@
|
||||
</div>
|
||||
<!-- 渐变背景 -->
|
||||
<canvas id="canvas-complex"
|
||||
style="width:100vw;height:100vh;position: absolute;z-index:-99;top:0;opacity: 0.35;"></canvas>
|
||||
|
||||
style="width:100vw;height:100vh;position: absolute;z-index:-99;top:0;opacity: 0.95;"></canvas>
|
||||
<!-- 气泡背景 -->
|
||||
<div class="demo-2">
|
||||
<div class="content">
|
||||
@ -44,29 +42,6 @@
|
||||
<!-- 引入の依赖 -->
|
||||
<script src="./static/js/granim.min.js"></script>
|
||||
<script src="./static/js/bg.js"></script>
|
||||
<script>
|
||||
// 也可以切换成其他背景
|
||||
var granimInstance = new Granim({
|
||||
element: '#canvas-complex',
|
||||
direction: 'left-right',
|
||||
isPausedWhenNotInView: true,
|
||||
states: {
|
||||
"default-state": {
|
||||
gradients: [
|
||||
[
|
||||
{ color: '#833ab4', pos: .2 },
|
||||
{ color: '#fd1d1d', pos: .8 },
|
||||
{ color: '#38ef7d', pos: 1 }
|
||||
], [
|
||||
{ color: '#40e0d0', pos: 0 },
|
||||
{ color: '#ff8c00', pos: .2 },
|
||||
{ color: '#ff0080', pos: .75 }
|
||||
],
|
||||
]
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,126 +1,187 @@
|
||||
*{
|
||||
margin:0px;
|
||||
padding:0px;
|
||||
border:none;
|
||||
outline:none;
|
||||
* {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: none;
|
||||
outline: none;
|
||||
font-size: 100%;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
body {
|
||||
|
||||
font-size:16px;
|
||||
color:#585f5f;
|
||||
line-height:1.5em;
|
||||
font-weight:400;
|
||||
background:#ffffff;
|
||||
font-size: 16px;
|
||||
color: #585f5f;
|
||||
line-height: 1.5em;
|
||||
font-weight: 400;
|
||||
background: #ffffff;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-font-smoothing: antialiased;
|
||||
font-family: 'Inter', sans-serif;
|
||||
}
|
||||
|
||||
a{
|
||||
text-decoration:none;
|
||||
cursor:pointer;
|
||||
a {
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
color: #24a77e;
|
||||
}
|
||||
|
||||
.theme_color{
|
||||
color:#24a77e;
|
||||
.theme_color {
|
||||
color: #24a77e;
|
||||
}
|
||||
|
||||
a:hover,
|
||||
a:focus,
|
||||
a:visited,
|
||||
a:active,
|
||||
button:active{
|
||||
text-decoration:none;
|
||||
outline:none;
|
||||
button:active {
|
||||
text-decoration: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
h1,h2,h3,h4,h5,h6 {
|
||||
position:relative;
|
||||
font-weight:normal;
|
||||
margin:0px 0px 15px;
|
||||
background:none;
|
||||
line-height:1.25em;
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
position: relative;
|
||||
font-weight: normal;
|
||||
margin: 0px 0px 15px;
|
||||
background: none;
|
||||
line-height: 1.25em;
|
||||
font-family: 'Libre Baskerville', serif;
|
||||
}
|
||||
|
||||
h1{
|
||||
h1 {
|
||||
font-size: 60px;
|
||||
}
|
||||
|
||||
h2{
|
||||
h2 {
|
||||
font-size: 48px;
|
||||
}
|
||||
|
||||
h3{
|
||||
h3 {
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
h4{
|
||||
h4 {
|
||||
font-size: 26px;
|
||||
}
|
||||
|
||||
h5{
|
||||
h5 {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
h6{
|
||||
h6 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
input,select,button{
|
||||
input,
|
||||
select,
|
||||
button {
|
||||
font-family: 'Inter', sans-serif;
|
||||
}
|
||||
|
||||
textarea{
|
||||
overflow:hidden;
|
||||
textarea {
|
||||
overflow: hidden;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
button{
|
||||
button {
|
||||
outline: none !important;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
p{
|
||||
p {
|
||||
font-size: 15px;
|
||||
line-height: 1.7em;
|
||||
font-weight: 400;
|
||||
margin: 0 0 15px;
|
||||
}
|
||||
|
||||
.text{
|
||||
.text {
|
||||
font-size: 15px;
|
||||
line-height: 1.7em;
|
||||
font-weight: 400;
|
||||
margin: 0 0;
|
||||
}
|
||||
|
||||
.clearfix::after{display:block;clear:both;content:""}
|
||||
.clearfix::after {
|
||||
display: block;
|
||||
clear: both;
|
||||
content: ""
|
||||
}
|
||||
|
||||
::-webkit-input-placeholder{color: inherit;}
|
||||
::-moz-input-placeholder{color: inherit;}
|
||||
::-ms-input-placeholder{color: inherit;}
|
||||
::-webkit-input-placeholder {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
::-moz-input-placeholder {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
::-ms-input-placeholder {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width:5px;
|
||||
height:5px;
|
||||
}
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track-piece {
|
||||
::-webkit-scrollbar-track-piece {
|
||||
border-radius: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color:#dddddd;
|
||||
background-clip:padding-box;
|
||||
min-height:28px;
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-clip: padding-box;
|
||||
min-height: 28px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background-color:#bbb;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #bbb;
|
||||
}
|
||||
|
||||
.my-dialog {
|
||||
border-radius: 12px !important;
|
||||
}
|
||||
|
||||
.el-dialog__header .el-dialog__title {
|
||||
color: #e03b5d;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.el-dialog__header {
|
||||
padding: 12px 20px !important;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
|
||||
.bookmark {
|
||||
border-radius: 12px !important;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.el-dialog__body {
|
||||
padding: 15px 30px!important;
|
||||
}
|
||||
|
||||
.el-dialog__headerbtn {
|
||||
top: 12px !important;
|
||||
}
|
||||
|
||||
.el-select {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.el-form-item{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 7px!important;
|
||||
min-height: 26px;
|
||||
}
|
||||
|
||||
.el-form-item__label{
|
||||
display: inline-block!important;
|
||||
}
|
156
src/App.vue
@ -1,5 +1,4 @@
|
||||
<template>
|
||||
<div class="bg"></div>
|
||||
<div id="app">
|
||||
<div class="bookmark" id="bookmark">
|
||||
<div class="tool-bar">
|
||||
@ -13,7 +12,7 @@
|
||||
</div>
|
||||
<img src="./assets/svg/add.svg" class="tool-icon" @click="add({},'add')" />
|
||||
<a title="我的博客" href="https://zhanhongzhu.top" target="_blank"><img src="./assets/svg/blog.svg" class="tool-icon" /></a>
|
||||
<a title="在线翻译" href="https://translate.google.cn" target="_blank"><img src="./assets/svg/translate.svg" class="tool-icon" /></a>
|
||||
<a title="github" href="https://github.com" target="_blank"><img src="./assets/svg/translate.svg" class="tool-icon" /></a>
|
||||
<span class="login-s" @click="loginClick"><img src="./assets/svg/user.svg" class="tool-icon" title="已登录" /><span class="login-status" :title="userInfo.username">{{userInfo.username.slice(0, 5)}}</span></span>
|
||||
</div>
|
||||
<!-- userInfo.objectId?LoginOut:handleUserLogin -->
|
||||
@ -29,11 +28,13 @@
|
||||
</div>
|
||||
<!-- 导入导出 -->
|
||||
<div class="import-tool">
|
||||
<span class="import-text">导入/导出: </span>
|
||||
<span class="import-text">导入/导出:</span>
|
||||
<i class="el-icon-upload2" title="导入浏览器书签" @click="importBookmark">
|
||||
<input type="file" ref="filElem" id="file">
|
||||
</i>
|
||||
<i class="el-icon-download" title="导出浏览器书签" @click="exportBookmark"></i>
|
||||
<i class="el-icon-setting" title="配置项" @click="configClick"></i>
|
||||
<i class="el-icon-refresh" title="重置" @click="resetClick"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right-box">
|
||||
@ -72,22 +73,30 @@
|
||||
<Dialog class="my-dialog" v-model="isDetailVisible" @closeViews="closeViews" :detail="detail" :selectType="activeIndex" @fresh="search" />
|
||||
<!-- 登录弹窗 -->
|
||||
<Login v-model="isLoginVisible" @closeViews="closeLoginViews" @setUser="setUsername" />
|
||||
|
||||
<!-- 配置项-背景 动画效果 -->
|
||||
<Configd v-model="isConfigVisible" @closeViews="closeConfigViews" @fresh="fresh" />
|
||||
|
||||
<!-- 配置项-背景 -->
|
||||
<Bg ref="bgRef" />
|
||||
</template>
|
||||
<script>
|
||||
import { reactive, toRefs } from '@vue/reactivity'
|
||||
import { reactive, toRefs, watch, ref, onMounted, computed } from 'vue'
|
||||
import { myData } from './assets/Json/印象笔记.js'
|
||||
import { watch } from '@vue/runtime-core'
|
||||
import Dialog from './components/Dialog.vue'
|
||||
import Bg from './components/Bg.vue'
|
||||
import Login from './components/Login.vue'
|
||||
import Configd from './components/Configd.vue'
|
||||
import gsap from 'gsap'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { saveObject, getObject } from './Api/common.js'
|
||||
import { exportBookmark, walkBookmarksTree } from './components/utils.js'
|
||||
import Cookie from 'js-cookie'
|
||||
import { themeConfig } from './components/theme'
|
||||
import Api from './Api/user.js'
|
||||
var rowData = []
|
||||
export default {
|
||||
components: { Dialog, Login },
|
||||
components: { Dialog, Login, Configd, Bg },
|
||||
name: 'kestrel-bookmark',
|
||||
setup() {
|
||||
// 扁平化数组
|
||||
@ -108,10 +117,13 @@ export default {
|
||||
allData: [],
|
||||
isDetailVisible: false,
|
||||
isLoginVisible: false,
|
||||
isConfigVisible: false,
|
||||
detail: {},
|
||||
userInfo: {
|
||||
username: '未登录'
|
||||
}
|
||||
},
|
||||
themeStyle: {},
|
||||
theme: 'light'
|
||||
})
|
||||
/*
|
||||
**数据来源
|
||||
@ -207,6 +219,13 @@ export default {
|
||||
const handleUserLogin = () => {
|
||||
data.isLoginVisible = true
|
||||
}
|
||||
|
||||
// 配置项
|
||||
const configClick = () => {
|
||||
data.isConfigVisible = true
|
||||
}
|
||||
const closeConfigViews = (v) => (data.isConfigVisible = v)
|
||||
|
||||
// 关闭弹窗事件
|
||||
const closeViews = (v) => (data.isDetailVisible = v)
|
||||
const closeLoginViews = (v) => (data.isLoginVisible = v)
|
||||
@ -292,8 +311,71 @@ export default {
|
||||
getBookmarkList()
|
||||
})
|
||||
}
|
||||
const bgRef = ref(null)
|
||||
const fresh = () => {
|
||||
setTheme()
|
||||
bgRef.value.init()
|
||||
}
|
||||
|
||||
// 设置主题
|
||||
const setTheme = () => {
|
||||
const obj1 = localStorage.getItem('granimConfig')
|
||||
if (obj1) {
|
||||
const obj = JSON.parse(obj1)
|
||||
data.theme = obj.theme
|
||||
data.themeStyle = themeConfig[`${data.theme}`]
|
||||
data.themeStyle.opacity0 =
|
||||
obj.opacity0 && obj.opacity0 > 0.5 ? obj.opacity0 : 0.5
|
||||
} else {
|
||||
data.themeStyle = themeConfig.light
|
||||
data.themeStyle.opacity0 = 0.8
|
||||
}
|
||||
}
|
||||
// 背景色
|
||||
const bgColor = computed(() => {
|
||||
return themeConfig[`${data.theme}`].bgColor
|
||||
})
|
||||
// 激活样式
|
||||
const activeColor = computed(() => {
|
||||
return themeConfig[`${data.theme}`].activeColor
|
||||
})
|
||||
// 亮度
|
||||
const opacity0 = computed(() => {
|
||||
return data.themeStyle.opacity0
|
||||
})
|
||||
// 文字颜色
|
||||
const textColor = computed(() => {
|
||||
return themeConfig[`${data.theme}`].textColor
|
||||
})
|
||||
// 边框色
|
||||
const borderColor = computed(() => {
|
||||
return themeConfig[`${data.theme}`].borderColor
|
||||
})
|
||||
// 滚动条样式
|
||||
const scrollbarColor = computed(() => {
|
||||
return themeConfig[`${data.theme}`].scrollbarColor
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
setTheme()
|
||||
})
|
||||
|
||||
// 重置配置项
|
||||
const resetClick = () => {
|
||||
localStorage.removeItem('granimConfig')
|
||||
bgRef.value.init()
|
||||
}
|
||||
|
||||
return {
|
||||
scrollbarColor,
|
||||
textColor,
|
||||
opacity0,
|
||||
activeColor,
|
||||
borderColor,
|
||||
bgColor,
|
||||
resetClick,
|
||||
bgRef,
|
||||
fresh,
|
||||
deleteClick,
|
||||
...toRefs(data),
|
||||
selectType,
|
||||
@ -305,7 +387,9 @@ export default {
|
||||
importBookmark,
|
||||
exportBookmark,
|
||||
loginClick,
|
||||
setUsername
|
||||
setUsername,
|
||||
configClick,
|
||||
closeConfigViews
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@ -339,17 +423,21 @@ export default {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.bookmark {
|
||||
position: relative;
|
||||
margin-top: 10vh;
|
||||
margin-top: 8vh;
|
||||
width: 1200px;
|
||||
height: calc(80vh);
|
||||
height: calc(75vh);
|
||||
border: 1px solid rgba(255, 255, 255, 0.18);
|
||||
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.2);
|
||||
border-radius: 6px;
|
||||
background: #fff;
|
||||
background: v-bind(bgColor);
|
||||
opacity: v-bind(opacity0);
|
||||
.left-box {
|
||||
width: 200px;
|
||||
height: 100%;
|
||||
@ -366,11 +454,11 @@ export default {
|
||||
}
|
||||
.active {
|
||||
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.2);
|
||||
background: #a0cae6;
|
||||
background: v-bind(activeColor);
|
||||
}
|
||||
.inactive {
|
||||
box-shadow: none;
|
||||
background: #fff;
|
||||
background: v-bind(bgColor);
|
||||
}
|
||||
.label {
|
||||
font-size: 14px;
|
||||
@ -381,7 +469,7 @@ export default {
|
||||
padding: 10px 15px;
|
||||
&:hover {
|
||||
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.2);
|
||||
background: #a0cae6;
|
||||
background: v-bind(activeColor);
|
||||
}
|
||||
.text-elipss {
|
||||
overflow: hidden;
|
||||
@ -420,6 +508,7 @@ export default {
|
||||
animation-delay: 0.3ms;
|
||||
animation: 0.3ms;
|
||||
box-shadow: 0 8px 18px 0 rgba(31, 38, 135, 0.3);
|
||||
background: v-bind(activeColor);
|
||||
}
|
||||
&:hover .logo-box-tools {
|
||||
opacity: 0.85;
|
||||
@ -441,12 +530,12 @@ export default {
|
||||
}
|
||||
.tool-bar {
|
||||
height: 48px;
|
||||
border-bottom: 1px solid #eee;
|
||||
border-bottom: 1px solid v-bind(borderColor);
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background: rgb(250, 248, 248);
|
||||
background: v-bind(bgColor);
|
||||
.tool-logo {
|
||||
margin: 0 15px;
|
||||
a {
|
||||
@ -482,7 +571,7 @@ export default {
|
||||
height: 2rem;
|
||||
color: #4e6e8e;
|
||||
display: inline-block;
|
||||
border: 1px solid #eaecef;
|
||||
border: 1px solid v-bind(borderColor);
|
||||
border-radius: 0.25rem;
|
||||
font-size: 0.9rem;
|
||||
line-height: 2rem;
|
||||
@ -495,6 +584,14 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: v-bind(scrollbarColor);
|
||||
background-clip: padding-box;
|
||||
min-height: 28px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.box-m {
|
||||
display: flex;
|
||||
height: calc(100% - 50px);
|
||||
@ -503,6 +600,7 @@ export default {
|
||||
width: 62px;
|
||||
height: 100%;
|
||||
margin-right: 10px;
|
||||
filter: drop-shadow(0px 0px 1px #888);
|
||||
img {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
@ -522,7 +620,7 @@ export default {
|
||||
padding-top: 3px;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #000000;
|
||||
color: v-bind(textColor);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
@ -537,7 +635,8 @@ export default {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
color: rgba(0, 0, 0, 0.7);
|
||||
color: v-bind(textColor);
|
||||
opacity: 0.8;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
@ -568,14 +667,6 @@ export default {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
.bg {
|
||||
position: fixed;
|
||||
z-index: -999;
|
||||
position: fixed;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: url(./assets/bg.jpg);
|
||||
}
|
||||
|
||||
.logo-box-tools {
|
||||
position: absolute;
|
||||
@ -597,17 +688,18 @@ export default {
|
||||
.import-tool {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
background: #fbf5f5;
|
||||
background: v-bind(bgColor);
|
||||
height: 36px;
|
||||
padding: 3px 15px;
|
||||
padding: 3px 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
bottom: 0;
|
||||
z-index: 99;
|
||||
border-top: 1px solid v-bind(borderColor);
|
||||
i {
|
||||
font-size: 18px;
|
||||
margin: 1px 4px;
|
||||
padding: 4px;
|
||||
font-size: 15px;
|
||||
margin: 1px 2px;
|
||||
padding: 3px;
|
||||
cursor: pointer;
|
||||
color: #e03b5d;
|
||||
background: #ff00001f;
|
||||
|
69
src/components/Bg.vue
Normal file
@ -0,0 +1,69 @@
|
||||
<template>
|
||||
<div class="bg"></div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, defineExpose } from 'vue'
|
||||
// 默认配置
|
||||
const defaultConfig = {
|
||||
direction: 'left-right',
|
||||
isPausedWhenNotInView: true,
|
||||
opacity: [1, 1],
|
||||
states: {
|
||||
'default-state': {
|
||||
gradients: [
|
||||
[
|
||||
{ color: '#833ab4', pos: 0.2 },
|
||||
{ color: '#fd1d1d', pos: 0.8 },
|
||||
{ color: '#38ef7d', pos: 1 }
|
||||
],
|
||||
[
|
||||
{ color: '#40e0d0', pos: 0 },
|
||||
{ color: '#ff8c00', pos: 0.2 },
|
||||
{ color: '#ff0080', pos: 0.75 }
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
image: {
|
||||
source: 'https://zhanhongzhu.top/bg.jpg',
|
||||
position: ['center', 'bottom'],
|
||||
stretchMode: ['stretch', 'stretch-if-bigger'],
|
||||
blendingMode: 'multiply'
|
||||
}
|
||||
}
|
||||
|
||||
let granimInstance = null
|
||||
const init = () => {
|
||||
let granimConfig = localStorage.getItem('granimConfig')
|
||||
granimConfig = granimConfig ? JSON.parse(granimConfig) : defaultConfig
|
||||
delete granimConfig.opacity
|
||||
// 切换背景光影效果
|
||||
// eslint-disable-next-line no-undef, no-new
|
||||
granimInstance = new Granim({
|
||||
element: '#canvas-complex',
|
||||
...granimConfig,
|
||||
opacity: 1
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({ init })
|
||||
|
||||
onMounted(() => {
|
||||
if (granimInstance) {
|
||||
granimInstance.destroy()
|
||||
}
|
||||
init()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.bg {
|
||||
position: fixed;
|
||||
z-index: -999;
|
||||
position: fixed;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: url(../assets/bg.jpg);
|
||||
}
|
||||
</style>
|
312
src/components/Configd.vue
Normal file
@ -0,0 +1,312 @@
|
||||
<!-- /* eslint-disable */ -->
|
||||
<template>
|
||||
<el-dialog custom-class="my-dialog" title="配置项" :visible="isConfigVisible" width="700px">
|
||||
<el-form status-icon ref="refruleForm" :rules="rules" :model="ruleForm" label-width="60px" size="small">
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="背景">
|
||||
<input id="file" @change="handleFileChange" accept="image/*" type="file" :multiple="false">
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="主题" class="slelec">
|
||||
<el-select v-model="theme" placeholder="光影" @change="setGranim">
|
||||
<el-option label="清新" value="light" />
|
||||
<el-option label="暗黑" value="dark" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="光影" class="slelec">
|
||||
<el-select v-model="selectVal" placeholder="光影" @change="setGranim">
|
||||
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="亮度" class="slelec">
|
||||
<el-input v-model="opacity0" placeholder="亮度" onkeyup="value=value.replace(/[^\d.]/g,0)" @change="setGranim"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="位置">
|
||||
<el-select v-model="direction" placeholder="位置" @change="setGranim">
|
||||
<el-option v-for="item in directions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="效果">
|
||||
<div class="granim-box">
|
||||
<canvas id="granim-box"></canvas>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="透明度" class="opacity">
|
||||
<el-input v-model="opacity1" placeholder="透明度参数1" onkeyup="value=value.replace(/[^\d]/g,0)" />
|
||||
<el-input v-model="opacity2" placeholder="透明度参数2" onkeyup="value=value.replace(/[^\d]/g,0)" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="closeViews" size="small">关 闭</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import Cookie from 'js-cookie'
|
||||
import {
|
||||
watch,
|
||||
reactive,
|
||||
ref,
|
||||
toRefs,
|
||||
onMounted,
|
||||
useAttrs,
|
||||
nextTick
|
||||
} from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import Api from '../Api/user.js' // register
|
||||
import { config } from './config.js'
|
||||
export default {
|
||||
model: {
|
||||
value: 'isConfigVisible',
|
||||
events: 'closeViews'
|
||||
},
|
||||
props: {
|
||||
isConfigVisible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
setup(props, context) {
|
||||
const state = reactive({
|
||||
ruleForm: {
|
||||
username: '',
|
||||
password: ''
|
||||
},
|
||||
options: [
|
||||
{ label: '渐变-01', value: 'gradient1' },
|
||||
{ label: '渐变-02', value: 'gradient2' },
|
||||
{ label: '渐变-03', value: 'gradient3' },
|
||||
{ label: '迷雾森林', value: 'gradient4' }
|
||||
],
|
||||
directions: [
|
||||
{ label: '从上到下', value: 'top-bottom' },
|
||||
{ label: '从左到右', value: 'left-right' },
|
||||
{ label: '环形', value: 'diagonal' },
|
||||
{ label: '对角线', value: 'radial' },
|
||||
{ label: '自定义', value: 'custom' }
|
||||
],
|
||||
selectVal: 'gradient4',
|
||||
direction: 'left-right',
|
||||
opacity1: 0.15,
|
||||
opacity2: 0.15,
|
||||
imageUrl: '',
|
||||
granimRef: null,
|
||||
theme: 'light',
|
||||
opacity0: 0.8
|
||||
})
|
||||
// 定义校验规则 表单代码中必须以 :rules 接收
|
||||
const rules = {
|
||||
password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
|
||||
email: [
|
||||
{
|
||||
type: 'email',
|
||||
required: true,
|
||||
message: '请输入正确的邮箱',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
}
|
||||
const refruleForm = ref(null)
|
||||
// 确定按钮的格式
|
||||
const submitForm = () => {
|
||||
refruleForm.value.validate((valid) => {
|
||||
if (valid) {
|
||||
const formData = { ...state.ruleForm }
|
||||
Api.login(formData.email, formData.password)
|
||||
.then((res) => {
|
||||
Cookie.set('userInfo', JSON.stringify(res))
|
||||
context.emit('setUser')
|
||||
ElMessage.success('登录成功')
|
||||
closeViews()
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err.code === 210) {
|
||||
ElMessage.error('账号或密码不正确')
|
||||
} else if (err.code === 211) {
|
||||
Api.register(formData.email, formData.password).then((res) => {
|
||||
Cookie.set('userInfo', JSON.stringify(res))
|
||||
context.emit('setUser')
|
||||
ElMessage.success('注册成功')
|
||||
closeViews()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
// 关闭弹窗
|
||||
function closeViews() {
|
||||
refruleForm.value.resetFields()
|
||||
context.emit('closeViews', false)
|
||||
}
|
||||
|
||||
const setGranim = () => {
|
||||
state.opacity1 = state.opacity1 || 1
|
||||
state.opacity2 = state.opacity2 || 1
|
||||
const obj = config[`${state.selectVal}`]
|
||||
// 配置项
|
||||
const granimConfig = {
|
||||
...obj,
|
||||
opacity1: state.opacity1,
|
||||
opacity2: state.opacity2,
|
||||
opacity0: state.opacity0,
|
||||
selectVal: state.selectVal,
|
||||
theme: state.theme,
|
||||
opacity: [state.opacity1, state.opacity2],
|
||||
direction: state.direction,
|
||||
image: {
|
||||
source: state.imageUrl,
|
||||
position: ['center', 'bottom'],
|
||||
stretchMode: ['stretch', 'stretch-if-bigger'],
|
||||
blendingMode: 'multiply'
|
||||
}
|
||||
}
|
||||
// 存储配置到缓存
|
||||
localStorage.setItem('granimConfig', JSON.stringify(granimConfig))
|
||||
|
||||
// eslint-disable-next-line no-undef, no-new
|
||||
state.granimRef = new Granim({
|
||||
element: '#granim-box',
|
||||
...granimConfig
|
||||
})
|
||||
context.emit('fresh')
|
||||
}
|
||||
// 文件转成 base64
|
||||
function changeFileIntoBase64(file) {
|
||||
return new Promise((resolve) => {
|
||||
const fr = new FileReader()
|
||||
/* eslint-disable */
|
||||
fr.readAsDataURL(file)
|
||||
fr.onload = (result) => {
|
||||
const base64Str = result.currentTarget.result
|
||||
resolve(base64Str)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const handleFileChange = (e) => {
|
||||
const file = e.target.files[0]
|
||||
changeFileIntoBase64(file)
|
||||
.then((res) => {
|
||||
state.imageUrl = res
|
||||
})
|
||||
.finally(() => {
|
||||
setGranim()
|
||||
})
|
||||
}
|
||||
|
||||
const attrs = useAttrs()
|
||||
onMounted(() => {
|
||||
let granimConfig = localStorage.getItem('granimConfig')
|
||||
if (granimConfig) {
|
||||
let obj = JSON.parse(granimConfig)
|
||||
state.selectVal = obj.selectVal
|
||||
state.direction = obj.direction
|
||||
state.opacity1 =
|
||||
obj.opacity && obj.opacity.length > 0 ? obj.opacity[0] : 0.15 // 选择显示的透明度 或 选择动画
|
||||
state.opacity2 =
|
||||
obj.opacity && obj.opacity.length > 0 ? obj.opacity[1] : 0.15
|
||||
state.imageUrl = obj.image && obj.image.source ? obj.image.source : ''
|
||||
state.theme = obj.theme
|
||||
state.opacity0 = obj.opacity0
|
||||
}
|
||||
state.granimRef = null
|
||||
})
|
||||
|
||||
watch(
|
||||
() => attrs.modelValue,
|
||||
(v) => {
|
||||
if (v) {
|
||||
nextTick(() => {
|
||||
if (state.granimRef) {
|
||||
state.granimRef.destroy()
|
||||
}
|
||||
setGranim()
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
}
|
||||
)
|
||||
return {
|
||||
...toRefs(state),
|
||||
closeViews,
|
||||
submitForm,
|
||||
refruleForm,
|
||||
rules,
|
||||
setGranim,
|
||||
handleFileChange,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.my-dialog {
|
||||
background: red;
|
||||
}
|
||||
.my-dialog /deep/.el-dialog__header {
|
||||
border-bottom: 1px solid #eee !important;
|
||||
}
|
||||
.my-dialog /deep/.el-dialog__title {
|
||||
font-size: 16px;
|
||||
color: #e03b5d;
|
||||
}
|
||||
|
||||
.granim-box {
|
||||
height: 240px;
|
||||
width: 100%;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
canvas {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
.slelec {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
// :deep(.el-form-item__label) {
|
||||
// }
|
||||
}
|
||||
|
||||
.opacity {
|
||||
:deep(.el-form-item__content) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.el-input {
|
||||
&:first-child {
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#file {
|
||||
height: 32px;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
input[type='text'] {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
@ -40,8 +40,7 @@
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
import { reactive, ref, toRefs } from '@vue/reactivity'
|
||||
import { nextTick, watch } from '@vue/runtime-core'
|
||||
import { reactive, ref, toRefs, nextTick, watch } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
export default {
|
||||
model: {
|
||||
|
@ -24,7 +24,7 @@
|
||||
</template>
|
||||
<script>
|
||||
import Cookie from 'js-cookie'
|
||||
import { reactive, ref, toRefs } from '@vue/reactivity'
|
||||
import { reactive, ref, toRefs } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import Api from '../Api/user.js' // register
|
||||
export default {
|
||||
|
88
src/components/config.js
Normal file
@ -0,0 +1,88 @@
|
||||
export const config = {
|
||||
gradient1: {
|
||||
direction: 'left-right',
|
||||
// isPausedWhenNotInView: true,
|
||||
image: {
|
||||
source: 'https://zhanhongzhu.top/bg.jpg',
|
||||
position: ['center', 'bottom'],
|
||||
stretchMode: ['stretch', 'stretch-if-bigger'],
|
||||
blendingMode: 'multiply'
|
||||
},
|
||||
states: {
|
||||
'default-state': {
|
||||
gradients: [
|
||||
[
|
||||
{ color: '#833ab4', pos: 0.2 },
|
||||
{ color: '#fd1d1d', pos: 0.8 },
|
||||
{ color: '#38ef7d', pos: 1 }
|
||||
],
|
||||
[
|
||||
{ color: '#40e0d0', pos: 0 },
|
||||
{ color: '#ff8c00', pos: 0.2 },
|
||||
{ color: '#ff0080', pos: 0.75 }
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
gradient2: {
|
||||
direction: 'left-right',
|
||||
opacity: [1, 1],
|
||||
// isPausedWhenNotInView: true,
|
||||
image: {
|
||||
source: 'https://zhanhongzhu.top/bg.jpg',
|
||||
position: ['center', 'bottom'],
|
||||
stretchMode: ['stretch', 'stretch-if-bigger'],
|
||||
blendingMode: 'multiply'
|
||||
},
|
||||
states: {
|
||||
'default-state': {
|
||||
gradients: [
|
||||
['#AA076B', '#61045F'],
|
||||
['#02AAB0', '#00CDAC'],
|
||||
['#DA22FF', '#9733EE']
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
gradient3: {
|
||||
direction: 'left-right',
|
||||
// isPausedWhenNotInView: true,
|
||||
image: {
|
||||
source: 'https://zhanhongzhu.top/bg.jpg',
|
||||
position: ['center', 'bottom'],
|
||||
stretchMode: ['stretch', 'stretch-if-bigger'],
|
||||
blendingMode: 'multiply'
|
||||
},
|
||||
states: {
|
||||
'default-state': {
|
||||
gradients: [
|
||||
['#ff9966', '#ff5e62'],
|
||||
['#00F260', '#0575E6'],
|
||||
['#e1eec3', '#f05053']
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
gradient4: {
|
||||
direction: 'top-bottom',
|
||||
// isPausedWhenNotInView: true,
|
||||
image: {
|
||||
source: 'https://zhanhongzhu.top/bg.jpg',
|
||||
position: ['center', 'bottom'],
|
||||
stretchMode: ['stretch', 'stretch-if-bigger'],
|
||||
blendingMode: 'multiply'
|
||||
},
|
||||
states: {
|
||||
'default-state': {
|
||||
gradients: [
|
||||
['#29323c', '#485563'],
|
||||
['#FF6B6B', '#556270'],
|
||||
['#80d3fe', '#7ea0c4'],
|
||||
['#f0ab51', '#eceba3']
|
||||
],
|
||||
transitionSpeed: 7000
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
20
src/components/theme.js
Normal file
@ -0,0 +1,20 @@
|
||||
export const themeConfig = {
|
||||
light: {
|
||||
bgColor: '#fff',
|
||||
activeColor: '#a0cae6',
|
||||
textColor: '#111',
|
||||
hoverColor: '#fff',
|
||||
borderColor: '#eee',
|
||||
scrollbarColor: '#dddddd',
|
||||
svgColor: ''
|
||||
},
|
||||
dark: {
|
||||
bgColor: '#111',
|
||||
activeColor: '#000',
|
||||
textColor: '#fff',
|
||||
hoverColor: '#000',
|
||||
borderColor: '#2c2c2c',
|
||||
scrollbarColor: '#222',
|
||||
svgColor: '#888'
|
||||
}
|
||||
}
|
@ -5,8 +5,12 @@ import ElementPlus from 'element-plus'
|
||||
import 'element-plus/lib/theme-chalk/index.css'
|
||||
// 接入了Leancloud
|
||||
import AV from 'leancloud-storage'
|
||||
|
||||
// 请注册leancloud,新建应用,然后替换这个
|
||||
AV.init({ appId: '\x42\x77\x4c\x72\x43\x67\x64\x56\x79\x4c\x73\x35\x32\x6d\x4a\x4f\x31\x48\x63\x72\x58\x61\x6b\x49\x2d\x67\x7a\x47\x7a\x6f\x48\x73\x7a', appKey: '\x32\x35\x67\x4e\x77\x7a\x77\x34\x64\x56\x37\x49\x41\x68\x37\x69\x30\x49\x7a\x44\x6e\x59\x76\x56', serverURL: '\x68\x74\x74\x70\x73\x3a\x2f\x2f\x62\x77\x6c\x72\x63\x67\x64\x76\x2e\x6c\x63\x2d\x63\x6e\x2d\x6e\x31\x2d\x73\x68\x61\x72\x65\x64\x2e\x63\x6f\x6d' })
|
||||
AV.init({
|
||||
appId: '\x42\x77\x4c\x72\x43\x67\x64\x56\x79\x4c\x73\x35\x32\x6d\x4a\x4f\x31\x48\x63\x72\x58\x61\x6b\x49\x2d\x67\x7a\x47\x7a\x6f\x48\x73\x7a', appKey: '\x32\x35\x67\x4e\x77\x7a\x77\x34\x64\x56\x37\x49\x41\x68\x37\x69\x30\x49\x7a\x44\x6e\x59\x76\x56', serverURL: '\x68\x74\x74\x70\x73\x3a\x2f\x2f\x62\x77\x6c\x72\x63\x67\x64\x76\x2e\x6c\x63\x2d\x63\x6e\x2d\x6e\x31\x2d\x73\x68\x61\x72\x65\x64\x2e\x63\x6f\x6d'
|
||||
})
|
||||
|
||||
const app = createApp(App)
|
||||
app.use(ElementPlus)
|
||||
app.mount('#app')
|
||||
|