1. 迎宾海报
This commit is contained in:
@@ -197,6 +197,31 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 爱心拼接:绝对定位心形轮廓 + 串行挂载 -->
|
||||
<div v-else-if="page.type === 'heart-collage'" ref="multiRootRef" class="g-heart mt-6">
|
||||
<div
|
||||
v-for="(slot, imgIdx) in HEART_SLOTS"
|
||||
:key="imgIdx"
|
||||
class="g-heart-slot"
|
||||
:class="{ 'g-heart-placeholder': imgIdx >= shownCount }"
|
||||
:style="heartSlotStyle(slot)"
|
||||
>
|
||||
<div
|
||||
v-if="imgIdx < shownCount"
|
||||
v-reveal="{ variant: heartReveal(imgIdx), immediate: true }"
|
||||
class="absolute inset-0 g-heart-cell"
|
||||
:class="frameClass"
|
||||
>
|
||||
<img
|
||||
:src="displayAt(imgIdx)"
|
||||
class="preview-img g-heart-img"
|
||||
decoding="async"
|
||||
@click.stop="previewImage(originalAt(imgIdx))"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else class="text-center text-[#8A8680] text-[12px] mt-6">未识别的版式:{{ page.type }}</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -236,8 +261,26 @@ const SEQUENTIAL_SELF_TYPES = new Set([
|
||||
'polaroid',
|
||||
'nine-grid',
|
||||
'one-large-five-small',
|
||||
'heart-collage',
|
||||
])
|
||||
|
||||
/** 爱心拼接槽位:百分比绝对定位,轮廓接近 ♥(顶开叉、中最宽、底收尖) */
|
||||
const HEART_SLOTS = [
|
||||
{ l: 10, t: 0, w: 32, h: 13 }, // 0 左上叶
|
||||
{ l: 58, t: 0, w: 32, h: 13 }, // 1 右上叶(中间约 16% 开叉)
|
||||
{ l: 0, t: 14, w: 14, h: 15.5 }, // 2 左外上
|
||||
{ l: 0, t: 30.5, w: 14, h: 15.5 }, // 3 左外下
|
||||
{ l: 15, t: 14, w: 26, h: 32 }, // 4 左大图
|
||||
{ l: 42, t: 14, w: 16, h: 32 }, // 5 中轴
|
||||
{ l: 59, t: 14, w: 26, h: 32 }, // 6 右大图
|
||||
{ l: 86, t: 14, w: 14, h: 15.5 }, // 7 右外上
|
||||
{ l: 86, t: 30.5, w: 14, h: 15.5 }, // 8 右外下
|
||||
{ l: 10, t: 47, w: 13, h: 16 }, // 9 左下收腰
|
||||
{ l: 24, t: 47, w: 52, h: 16 }, // 10 中下横
|
||||
{ l: 77, t: 47, w: 13, h: 16 }, // 11 右下收腰
|
||||
{ l: 38, t: 64, w: 24, h: 14 }, // 12 心尖
|
||||
]
|
||||
|
||||
const props = defineProps({
|
||||
page: { type: Object, required: true },
|
||||
/** 九宫格:开启串行 v-reveal;关闭则一次展示 */
|
||||
@@ -447,7 +490,7 @@ const runSequentialByType = async () => {
|
||||
await runOlfsSequential()
|
||||
return
|
||||
}
|
||||
if (type === 'masonry' || type === 'polaroid') {
|
||||
if (type === 'masonry' || type === 'polaroid' || type === 'heart-collage') {
|
||||
await runMultiSequential()
|
||||
}
|
||||
}
|
||||
@@ -608,6 +651,23 @@ function polaroidTransform(i) {
|
||||
return `rotate(${a}deg) translateY(${s}px)`
|
||||
}
|
||||
|
||||
/** 爱心:左右对称入场,中轴与心尖用缩放 */
|
||||
function heartReveal(i) {
|
||||
if (i === 5 || i === 12) return 'scale'
|
||||
if (i === 0 || i === 2 || i === 3 || i === 4 || i === 9) return 'left'
|
||||
if (i === 1 || i === 6 || i === 7 || i === 8 || i === 11) return 'right'
|
||||
return 'up'
|
||||
}
|
||||
|
||||
function heartSlotStyle(slot) {
|
||||
return {
|
||||
left: `${slot.l}%`,
|
||||
top: `${slot.t}%`,
|
||||
width: `${slot.w}%`,
|
||||
height: `${slot.h}%`,
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@@ -706,6 +766,9 @@ function polaroidTransform(i) {
|
||||
max-width: 400px;
|
||||
height: clamp(340px, 48vh, 460px);
|
||||
}
|
||||
.g-heart {
|
||||
max-width: 400px;
|
||||
}
|
||||
.g-carousel-slide {
|
||||
height: min(52vh, 420px);
|
||||
}
|
||||
@@ -724,6 +787,75 @@ function polaroidTransform(i) {
|
||||
.g-dot { width: 7px; height: 7px; border-radius: 9999px; border: none; background: rgba(168,140,107,0.3); padding: 0; cursor: pointer; transition: all 0.3s; }
|
||||
.g-dot.active { background: #a88c6b; width: 18px; border-radius: 9999px; }
|
||||
|
||||
/* 爱心拼接:绝对定位块状心形 + 淡囍底纹 */
|
||||
.g-heart {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
margin-inline: auto;
|
||||
aspect-ratio: 0.8 / 1;
|
||||
padding: 4px 2px 8px;
|
||||
box-sizing: border-box;
|
||||
isolation: isolate;
|
||||
}
|
||||
.g-heart::before,
|
||||
.g-heart::after {
|
||||
content: '囍';
|
||||
position: absolute;
|
||||
z-index: 0;
|
||||
font-family: var(--font-calligraphy), serif;
|
||||
font-weight: 700;
|
||||
color: #c97878;
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
line-height: 1;
|
||||
}
|
||||
.g-heart::before {
|
||||
top: 22%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
font-size: clamp(64px, 24vw, 108px);
|
||||
opacity: 0.07;
|
||||
}
|
||||
.g-heart::after {
|
||||
bottom: 10%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
font-size: clamp(36px, 12vw, 56px);
|
||||
opacity: 0.05;
|
||||
}
|
||||
.g-heart-slot {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
contain: layout paint;
|
||||
}
|
||||
.g-heart-placeholder {
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
background: transparent !important;
|
||||
border: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
.g-heart-cell {
|
||||
overflow: hidden;
|
||||
transition: transform 0.35s ease, box-shadow 0.35s ease;
|
||||
}
|
||||
@media (hover: hover) {
|
||||
.g-heart-cell:hover {
|
||||
transform: scale(1.03);
|
||||
z-index: 3;
|
||||
box-shadow: 0 6px 18px rgba(80, 50, 40, 0.16);
|
||||
}
|
||||
}
|
||||
.g-heart-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.g-polaroid { display: flex; flex-wrap: wrap; justify-content: center; gap: 14px 10px; padding: 14px 4px 4px; }
|
||||
.g-polaroid-slot {
|
||||
width: 42%;
|
||||
|
||||
Reference in New Issue
Block a user