refactor(vibe-stories): extract screen region styling to computed property

This commit is contained in:
sanbuphy
2026-03-29 11:43:08 +08:00
parent b3ca518409
commit e191fa7ddb
@@ -1,5 +1,5 @@
<script setup> <script setup>
import { inject, onMounted, onUnmounted, ref } from 'vue' import { computed, inject, onMounted, onUnmounted, ref } from 'vue'
import { withBase } from 'vitepress' import { withBase } from 'vitepress'
import macbookImage from '../../../../assets/macbook.png' import macbookImage from '../../../../assets/macbook.png'
import story1Cover from '../../../zh-cn/vibe-stories/images/story-1/image5.png' import story1Cover from '../../../zh-cn/vibe-stories/images/story-1/image5.png'
@@ -59,6 +59,25 @@ const isPaginating = ref(false)
const containerRef = ref(null) const containerRef = ref(null)
let wheelHandler = null let wheelHandler = null
const screenRegion = ref({
centerX: 50,
centerY: 45.75,
width: 80,
height: 90,
radius: 4
})
const formatPercent = (value) => `${value}%`
const formatPixels = (value) => `${value}px`
const screenContentStyle = computed(() => ({
top: formatPercent(screenRegion.value.centerY - screenRegion.value.height / 2),
left: formatPercent(screenRegion.value.centerX - screenRegion.value.width / 2),
width: formatPercent(screenRegion.value.width),
height: formatPercent(screenRegion.value.height),
borderRadius: formatPixels(screenRegion.value.radius)
}))
const transitionName = ref('slide-left') const transitionName = ref('slide-left')
const next = () => { const next = () => {
@@ -147,7 +166,7 @@ onUnmounted(() => {
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6" /></svg> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6" /></svg>
</button> </button>
<div class="screen-content"> <div class="screen-content" :style="screenContentStyle">
<a :href="withBase(tStories[currentIndex].link)" class="screen-link"> <a :href="withBase(tStories[currentIndex].link)" class="screen-link">
<transition :name="transitionName"> <transition :name="transitionName">
<div :key="currentIndex" class="screen-image-wrapper"> <div :key="currentIndex" class="screen-image-wrapper">
@@ -256,17 +275,13 @@ onUnmounted(() => {
width: 100%; width: 100%;
max-width: 700px; max-width: 700px;
margin: 0 auto; margin: 0 auto;
/* Keep the MacBook frame height stable before the PNG finishes loading. */
aspect-ratio: 4608 / 2675;
} }
.laptop-frame { .laptop-frame {
position: absolute; position: relative;
inset: 0;
z-index: 10; z-index: 10;
width: 100%; width: 100%;
height: 100%; height: auto;
object-fit: contain;
pointer-events: none; pointer-events: none;
filter: drop-shadow(0 25px 25px rgb(0 0 0 / 0.15)); filter: drop-shadow(0 25px 25px rgb(0 0 0 / 0.15));
} }
@@ -278,16 +293,8 @@ onUnmounted(() => {
.screen-content { .screen-content {
position: absolute; position: absolute;
z-index: 1; z-index: 1;
top: 0;
left: 10%;
width: 80%;
height: 92%;
background: #0b0b0f; background: #0b0b0f;
overflow: hidden; overflow: hidden;
border-top-left-radius: 12px;
border-top-right-radius: 12px;
clip-path: inset(0 round 12px 12px 0 0);
contain: paint;
perspective: 1000px; perspective: 1000px;
transform: translateZ(0); transform: translateZ(0);
-webkit-transform: translateZ(0); -webkit-transform: translateZ(0);
@@ -300,14 +307,9 @@ onUnmounted(() => {
position: absolute; position: absolute;
inset: 0; inset: 0;
display: block; display: block;
background: transparent;
overflow: hidden; overflow: hidden;
border-top-left-radius: 12px; border-radius: inherit;
border-top-right-radius: 12px;
clip-path: inset(0 round 12px 12px 0 0);
transform: translateZ(0);
-webkit-transform: translateZ(0);
mask-image: radial-gradient(white, black);
-webkit-mask-image: -webkit-radial-gradient(white, black);
} }
.screen-link:focus, .screen-link:focus,
@@ -319,9 +321,7 @@ onUnmounted(() => {
position: absolute; position: absolute;
inset: 0; inset: 0;
overflow: hidden; overflow: hidden;
border-top-left-radius: 12px; border-radius: inherit;
border-top-right-radius: 12px;
clip-path: inset(0 round 12px 12px 0 0);
} }
.screen-image { .screen-image {
@@ -330,9 +330,6 @@ onUnmounted(() => {
height: 100%; height: 100%;
object-fit: cover; object-fit: cover;
object-position: center; object-position: center;
border-top-left-radius: 12px;
border-top-right-radius: 12px;
backface-visibility: hidden;
} }
/* Transitions */ /* Transitions */
@@ -509,4 +506,5 @@ onUnmounted(() => {
.dark .indicator-dot.active { .dark .indicator-dot.active {
background: #f5f5f7; background: #f5f5f7;
} }
</style> </style>