feat(lenticular-result): 切换为手动倾斜模式 + 触摸滑块双向同步

- @simulate → onTouchSimulate:触摸 x 投影到滑块 + 驱动引擎
- @update:slider-value → onSliderChange:滑块拖动驱动引擎
- @slider-reset → onSliderReset:复位滑块+引擎
- v-model:slider-value 双向
- 删 3 处 scheduleTiltStart / stopTiltPreview / gyroSourceLabel 引用
- 触摸结束不强制回中

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
zerosaturation 2026-07-06 18:02:51 +08:00
parent 851a8f6c43
commit dcdbc041a9

View File

@ -29,9 +29,12 @@
<image class="card-frame" src="/static/square/gerenzhongxincangpinkuang.png" mode="aspectFit" /> <image class="card-frame" src="/static/square/gerenzhongxincangpinkuang.png" mode="aspectFit" />
<view class="craft-lenticular-slot"> <view class="craft-lenticular-slot">
<LenticularCard v-if="lenticularLayers.length > 0" class="craft-lenticular-card" <LenticularCard v-if="lenticularLayers.length > 0" class="craft-lenticular-card"
:layers="lenticularLayers" :transforms="layerTransforms" :gyro-source="gyroSourceLabel" :layers="lenticularLayers" :transforms="layerTransforms"
:skip-built-in-touch="true" tilt-hint-text="晃动查看" :shimmer-mid-opacity="0.16" :show-slider="true" v-model:slider-value="tiltValue"
@simulate="simulate" /> tilt-hint-text="晃动或滑动查看" :shimmer-mid-opacity="0.16"
@simulate="onTouchSimulate"
@update:slider-value="onSliderChange"
@slider-reset="onSliderReset" />
</view> </view>
</view> </view>
</view> </view>
@ -61,8 +64,7 @@
</template> </template>
<script setup> <script setup>
import { ref, computed, onMounted, onUnmounted } from 'vue'; import { ref, computed, onMounted } from 'vue';
import { onShow, onHide } from '@dcloudio/uni-app';
import { getOssSignatureApi, createMintOrderApi, estimateMintCostApi } from '@/utils/api.js'; import { getOssSignatureApi, createMintOrderApi, estimateMintCostApi } from '@/utils/api.js';
import { resolveH5OssPostUrl } from '@/utils/h5OssPostUrl.js'; import { resolveH5OssPostUrl } from '@/utils/h5OssPostUrl.js';
import LenticularCard from '@/components/lenticular/LenticularCard.vue'; import LenticularCard from '@/components/lenticular/LenticularCard.vue';
@ -102,12 +104,41 @@ const confirmCostInfo = ref({
const lenticularLayers = ref([]); const lenticularLayers = ref([]);
const { const {
layerTransforms, layerTransforms,
simulate, simulateTilt,
gyroSourceLabel, simulateTiltFromNormalized,
scheduleTiltStart, simulateTiltReset,
stopTiltPreview,
} = useLenticularCraftTiltPreview(lenticularLayers); } = useLenticularCraftTiltPreview(lenticularLayers);
// / single source of truthspec §3.4
const tiltValue = ref(0.5);
/**
* 触摸 滑块 + 引擎
* 把触摸 x 投影到滑块 0..1用户最新要求手滑时滑块也动
*/
function onTouchSimulate(x, y) {
const sliderPos = Math.max(0, Math.min(1, (x + 1) / 2))
tiltValue.value = sliderPos
simulateTiltFromNormalized(x, y)
}
/**
* 滑块 引擎tiltValue 已被 v-model 自动更新这里只驱动引擎
* 用户最新要求滑块滑动相关的手滑/卡片也到那个角度
*/
function onSliderChange(v) {
const dx = (v - 0.5) * 90
simulateTilt(dx, 0)
}
/**
* 复位按钮滑块回 0.5 + 引擎回中
*/
function onSliderReset() {
tiltValue.value = 0.5
simulateTiltReset()
}
// //
const isCraftDetailFlow = computed(() => isDetailAfterSelect(craftFormData.value)); const isCraftDetailFlow = computed(() => isDetailAfterSelect(craftFormData.value));
// //
@ -710,7 +741,6 @@ const initLenticularPreview = () => {
const subjectPath = p.subjectPath || ''; const subjectPath = p.subjectPath || '';
lenticularLayers.value = buildLenticularLayersTwo(bgPath, subjectPath); lenticularLayers.value = buildLenticularLayersTwo(bgPath, subjectPath);
selectedIndex.value = 0; selectedIndex.value = 0;
scheduleTiltStart();
} catch (e) { } catch (e) {
console.error('[GenerationResult] lenticular init', e); console.error('[GenerationResult] lenticular init', e);
} }
@ -764,19 +794,6 @@ onMounted(() => {
} }
}); });
onShow(() => {
if (isLenticularDisplay.value && lenticularLayers.value.length) {
scheduleTiltStart();
}
});
onHide(() => {
stopTiltPreview();
});
onUnmounted(() => {
stopTiltPreview();
});
</script> </script>
<style scoped> <style scoped>