分类添加样式选择
This commit is contained in:
parent
65ed6b21a9
commit
f71bf0f027
|
@ -750,6 +750,18 @@ spec:
|
|||
label: 版权声明
|
||||
placeholder: '本文是原创文章,采用 <a target="_blank" href="/cc">CC BY-NC-ND 4.0</a> 协议,完整转载请注明来自 <a href="/" target="_blank" >程序员小航</a>'
|
||||
help: "版权声明内容,支持填入 HTML 标签"
|
||||
- group: categories
|
||||
label: 分类
|
||||
formSchema:
|
||||
- $formkit: select
|
||||
name: use
|
||||
label: 样式选择
|
||||
value: default
|
||||
options:
|
||||
- label: 默认
|
||||
value: default
|
||||
- label: 3D
|
||||
value: 3D
|
||||
- group: aiDescription
|
||||
label: 文章ai摘要
|
||||
formSchema:
|
||||
|
|
|
@ -0,0 +1,148 @@
|
|||
#libCategories {
|
||||
margin: 40px 0;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
#libCategories * {
|
||||
box-sizing: inherit!important;
|
||||
}
|
||||
|
||||
#libCategories .title {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#libCategories p {
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
#libCategories h1 + p, #libCategories p + p {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
#libCategories .container {
|
||||
padding: 20px 20px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
#libCategories .card-wrap {
|
||||
margin: 10px;
|
||||
transform: perspective(1200px);
|
||||
transform-style: preserve-3d;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#libCategories .card-wrap:hover .card-info {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
#libCategories .card-wrap:hover .card-info p {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#libCategories .card-wrap:hover .card-info, #libCategories .card-wrap:hover .card-info p {
|
||||
transition: 0.6s cubic-bezier(0.23, 1, 0.32, 1);
|
||||
}
|
||||
|
||||
#libCategories .card-wrap:hover .card-info:after {
|
||||
transition: 3s cubic-bezier(0.23, 1, 0.32, 1);
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
#libCategories .card-wrap:hover .card-bg {
|
||||
transition: 0.5s cubic-bezier(0.23, 1, 0.32, 1), opacity 4s cubic-bezier(0.23, 1, 0.32, 1);
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
#libCategories .card-wrap:hover .card {
|
||||
transition: 0.5s cubic-bezier(0.23, 1, 0.32, 1);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
#libCategories a{
|
||||
border:none!important;
|
||||
background:none!important;
|
||||
}
|
||||
|
||||
#libCategories .card {
|
||||
position: relative;
|
||||
flex: 0 0 240px;
|
||||
width: 320px;
|
||||
height: 320px;
|
||||
background-color: #000;
|
||||
overflow: hidden;
|
||||
box-shadow: rgba(0, 0, 0, 0.66) 0 30px 60px 0, inset #333 0 0 0 5px, inset rgba(255, 255, 255, 0.4) 0 0 0 6px;
|
||||
transition: 0.8s cubic-bezier(0.445, 0.05, 0.55, 0.95);
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
#libCategories .card-bg {
|
||||
opacity: 0.5;
|
||||
position: absolute;
|
||||
top: -30px;
|
||||
left: -30px;
|
||||
width: 120%;
|
||||
height: 120%;
|
||||
padding: 20px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
transition: 0.8s cubic-bezier(0.445, 0.05, 0.55, 0.95), opacity 4s 0.8s cubic-bezier(0.445, 0.05, 0.55, 0.95);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#libCategories .card-info {
|
||||
padding: 20px;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
color: #fff;
|
||||
transform: translateY(40%);
|
||||
transition: 0.6s 1.6s cubic-bezier(0.215, 0.61, 0.355, 1);
|
||||
}
|
||||
|
||||
#libCategories .card-info p {
|
||||
opacity: 0;
|
||||
text-shadow: black 0 0.2px 0.5px;
|
||||
transition: 0.6s 1.6s cubic-bezier(0.215, 0.61, 0.355, 1);
|
||||
}
|
||||
|
||||
#libCategories .card-info * {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
#libCategories .card-info:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: linear-gradient(to bottom, transparent 0%, rgba(0, 0, 0, 0.6) 100%);
|
||||
background-blend-mode: overlay;
|
||||
opacity: 0;
|
||||
transform: translateY(100%);
|
||||
transition: 5s 1s cubic-bezier(0.445, 0.05, 0.55, 0.95);
|
||||
}
|
||||
|
||||
#libCategories .card-info h1 {
|
||||
font-size: 36px;
|
||||
font-weight: 700;
|
||||
text-shadow: rgba(0, 0, 0, 0.1) 0 10px 10px;
|
||||
padding-left: 0;
|
||||
line-height: 1.2;
|
||||
color: var(--heo-white);
|
||||
}
|
||||
|
||||
#libCategories .card-info h1:before {
|
||||
display: none;
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
Vue.config.devtools = true;
|
||||
|
||||
Vue.component("card", {
|
||||
template: `
|
||||
<div class="card-wrap"
|
||||
@mousemove="handleMouseMove"
|
||||
@mouseenter="handleMouseEnter"
|
||||
@mouseleave="handleMouseLeave"
|
||||
ref="card">
|
||||
<div class="card"
|
||||
:style="cardStyle">
|
||||
<div class="card-bg" :style="[cardBgTransform, cardBgImage]"></div>
|
||||
<div class="card-info">
|
||||
<slot name="header"></slot>
|
||||
<slot name="content"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>`,
|
||||
mounted() {
|
||||
this.width = this.$refs.card.offsetWidth;
|
||||
this.height = this.$refs.card.offsetHeight;
|
||||
},
|
||||
props: ["dataImage"],
|
||||
data: () => ({
|
||||
width: 0,
|
||||
height: 0,
|
||||
mouseX: 0,
|
||||
mouseY: 0,
|
||||
mouseLeaveDelay: null
|
||||
}),
|
||||
|
||||
computed: {
|
||||
mousePX() {
|
||||
return this.mouseX / this.width;
|
||||
},
|
||||
mousePY() {
|
||||
return this.mouseY / this.height;
|
||||
},
|
||||
cardStyle() {
|
||||
const rX = this.mousePX * 30;
|
||||
const rY = this.mousePY * -30;
|
||||
return {
|
||||
transform: `rotateY(${rX}deg) rotateX(${rY}deg)`
|
||||
};
|
||||
},
|
||||
cardBgTransform() {
|
||||
const tX = this.mousePX * -40;
|
||||
const tY = this.mousePY * -40;
|
||||
return {
|
||||
transform: `translateX(${tX}px) translateY(${tY}px)`
|
||||
};
|
||||
},
|
||||
cardBgImage() {
|
||||
return {
|
||||
backgroundImage: `url(${this.dataImage})`
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
handleMouseMove(e) {
|
||||
this.mouseX = e.pageX - this.$refs.card.offsetLeft - this.width / 2;
|
||||
this.mouseY = e.pageY - this.$refs.card.offsetTop - this.height / 2;
|
||||
},
|
||||
handleMouseEnter() {
|
||||
clearTimeout(this.mouseLeaveDelay);
|
||||
},
|
||||
handleMouseLeave() {
|
||||
this.mouseLeaveDelay = setTimeout(() => {
|
||||
this.mouseX = 0;
|
||||
this.mouseY = 0;
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var app = new Vue({
|
||||
el: "#lib-cards"
|
||||
});
|
File diff suppressed because one or more lines are too long
|
@ -12,18 +12,34 @@
|
|||
|
||||
<div id="page">
|
||||
<h1 class="page-title" style="display: inline;">分类</h1>
|
||||
<div class="category-lists">
|
||||
<div th:if="${#strings.equals(theme.config.categories.use, 'default')}" class="category-lists">
|
||||
<div class="category-title is-center">分类 - <span class="category-amount">11</span></div>
|
||||
<div class="tag-cloud-list is-center">
|
||||
<a style="font-size: 1em;"
|
||||
th:each="categoryItem : ${categoryFinder.listAll()}"
|
||||
th:href="@{${categoryItem.status.permalink}}"
|
||||
th:id="${categoryItem.spec.displayName}">
|
||||
<span style="font-size: 22px;" class="tags-punctuation">[[${categoryItem.spec.displayName}]]</span>
|
||||
|
||||
<a style="font-size: 1em;" th:each="categoryItem : ${categoryFinder.listAll()}"
|
||||
th:href="@{${categoryItem.status.permalink}}" th:id="${categoryItem.spec.displayName}">
|
||||
<span style="font-size: 22px;"
|
||||
class="tags-punctuation">[[${categoryItem.spec.displayName}]]</span>
|
||||
|
||||
<span class="tagsPageCount">[[${categoryItem.status.visiblePostCount}]]</span></a>
|
||||
</div>
|
||||
</div>
|
||||
<th:block th:if="${#strings.equals(theme.config.categories.use, '3D')}">
|
||||
<link rel="stylesheet" th:href="@{/assets/libs/no3d/no3d.css}">
|
||||
<div id="libCategories" >
|
||||
<div id="lib-cards" class="container" >
|
||||
<a th:each="categoryItem : ${categoryFinder.listAll()}" th:href="@{${categoryItem.status.permalink}}" th:id="${categoryItem.spec.displayName}">
|
||||
<card th:data-image="${categoryItem.spec.cover}">
|
||||
<h1 slot="header">[[${categoryItem.spec.displayName}]]</h1>
|
||||
<p slot="content">[[${categoryItem.spec.description}]]</p>
|
||||
</card>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="js-pjax">
|
||||
<script th:src="@{/assets/libs/no3d/vue.min.js}"></script>
|
||||
<script th:src="@{/assets/libs/no3d/no3d.js}"></script>
|
||||
</div>
|
||||
</th:block>
|
||||
</div>
|
||||
</main>
|
||||
<!-- 底部 -->
|
||||
|
@ -32,4 +48,4 @@
|
|||
|
||||
</th:block>
|
||||
|
||||
</html>
|
||||
</html>
|
Loading…
Reference in New Issue