|
@@ -1,78 +1,121 @@
|
|
|
<template>
|
|
|
- <ControlPanl
|
|
|
- :group="[{ items: options }]"
|
|
|
- v-model="selectOptions"
|
|
|
- ref="selectExpose"
|
|
|
- />
|
|
|
- <ui-floating
|
|
|
- v-if="selectOptions.some(({key}) => key === 'opacity')"
|
|
|
- :refer="opacityOptionEl"
|
|
|
- isTransform
|
|
|
- dire="right-center"
|
|
|
- >
|
|
|
- <div class="floating-range strengthen">
|
|
|
+ <template v-if="model && sceneModel">
|
|
|
+ <ControlPanl
|
|
|
+ :group="[{ items: options }]"
|
|
|
+ v-model="selectOptions"
|
|
|
+ ref="selectExpose"
|
|
|
+ />
|
|
|
+ <ui-floating
|
|
|
+ v-if="selectOptions.some(({key}) => key === 'opacity')"
|
|
|
+ :refer="opacityOptionEl"
|
|
|
+ isTransform
|
|
|
+ dire="right-center"
|
|
|
+ >
|
|
|
+ <div class="floating-range strengthen">
|
|
|
+ <div class="range-content">
|
|
|
+ <ui-input
|
|
|
+ type="range"
|
|
|
+ v-model="model.opacity"
|
|
|
+ v-bind="modelRange.opacityRange"
|
|
|
+ :ctrl="false"
|
|
|
+ :input="false"
|
|
|
+ width="100%"
|
|
|
+ />
|
|
|
+ <span class="num" :style="{left: `${model.opacity}%`}">{{model.opacity}}%</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </ui-floating>
|
|
|
+
|
|
|
+ <div class="right-range floating-range strengthen">
|
|
|
<div class="range-content">
|
|
|
+ <span class="fun-ctrl" @click="model!.bottom += modelRange.bottomRange.step">+</span>
|
|
|
<ui-input
|
|
|
type="range"
|
|
|
- v-model="a"
|
|
|
- v-bind="modelRange.opacityRange"
|
|
|
+ v-model="model.bottom"
|
|
|
+ v-bind="modelRange.bottomRange"
|
|
|
+ :moveCallback="changeRange"
|
|
|
:ctrl="false"
|
|
|
:input="false"
|
|
|
width="100%"
|
|
|
/>
|
|
|
- <span class="num" :style="{left: `${a}%`}">{{a}}%</span>
|
|
|
+ <span class="fun-ctrl" @click="model!.bottom -= modelRange.bottomRange.step">-</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
- </ui-floating>
|
|
|
-
|
|
|
- <div class="right-range floating-range strengthen">
|
|
|
- <div class="range-content">
|
|
|
- <span class="fun-ctrl" @click="a += modelRange.opacityRange.step">+</span>
|
|
|
- <ui-input
|
|
|
- type="range"
|
|
|
- v-model="a"
|
|
|
- v-bind="modelRange.opacityRange"
|
|
|
- :moveCallback="changeRange"
|
|
|
- :ctrl="false"
|
|
|
- :input="false"
|
|
|
- width="100%"
|
|
|
- />
|
|
|
- <span class="fun-ctrl" @click="a -= modelRange.opacityRange.step">-</span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
|
|
|
- <div class="ui-message tip-left">请在当前窗口调整水平方向位置</div>
|
|
|
- <div class="ui-message tip-right">请在当前窗口调整垂直方向位置</div>
|
|
|
+ <div class="ui-message tip-left">请在当前窗口调整水平方向位置</div>
|
|
|
+ <div class="ui-message tip-right">请在当前窗口调整垂直方向位置</div>
|
|
|
+ </template>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
import { ref, computed, watch } from 'vue'
|
|
|
import { ControlPanl } from '@/components/control-panl/'
|
|
|
-import { modelRange } from '@/sdk'
|
|
|
+import { modelRange, getSceneModel } from '@/sdk'
|
|
|
import { diffArrayChange } from '@/utils'
|
|
|
+import { useViewStack } from '@/hook'
|
|
|
+import { autoSaveFuseModels, getFuseModel, leave } from '@/store'
|
|
|
+import { router } from '@/router'
|
|
|
|
|
|
-import type { Items, ControlExpose } from '@/components/control-panl'
|
|
|
+import type { ControlExpose } from '@/components/control-panl'
|
|
|
+
|
|
|
+const model = computed(() => {
|
|
|
+ const modelId = router.currentRoute.value.params.id as string
|
|
|
+ if (modelId) {
|
|
|
+ return getFuseModel(modelId)
|
|
|
+ }
|
|
|
+})
|
|
|
|
|
|
-const options: Items = [
|
|
|
+const sceneModel = computed(() => model.value && getSceneModel(model.value))
|
|
|
+const options = [
|
|
|
{ desc: '移动', icon: 'move', key: 'move' },
|
|
|
{ desc: '旋转', icon: 'flip', key: 'rotate' },
|
|
|
{ desc: '透明度', icon: 'transparency', key: 'opacity' },
|
|
|
]
|
|
|
-const selectOptions = ref<Items>([])
|
|
|
+const selectOptions = ref<typeof options>([])
|
|
|
const selectExpose = ref<ControlExpose>()
|
|
|
const opacityOptionEl = computed(
|
|
|
() => selectExpose.value?.dom?.querySelector('div[data-key="opacity"]')
|
|
|
)
|
|
|
-const a = ref(1)
|
|
|
|
|
|
const changeRange = (sp: ScreenLocalPos, cp: ScreenLocalPos, info: { start: number, locusWidth: number }) =>
|
|
|
info.start + ((sp.y - cp.y) / info.locusWidth)
|
|
|
|
|
|
watch(selectOptions, (nOptions, oOptions = []) => {
|
|
|
const { added, deleted } = diffArrayChange(nOptions, oOptions)
|
|
|
- console.log(added, deleted)
|
|
|
+ const setKeys = ['move', 'rotate']
|
|
|
+ const addOptions = added.filter(option => setKeys.includes(option.key))
|
|
|
+ const delOptions = deleted.filter(option => setKeys.includes(option.key))
|
|
|
+
|
|
|
+ if (sceneModel.value) {
|
|
|
+ if (!addOptions.length && delOptions.length) {
|
|
|
+ sceneModel.value.leaveTransform()
|
|
|
+ } else if (addOptions.length) {
|
|
|
+ if (addOptions[0].key === 'move') {
|
|
|
+ sceneModel.value.enterMoveMode()
|
|
|
+ } else {
|
|
|
+ sceneModel.value.enterRotateMode()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}, { immediate: true })
|
|
|
|
|
|
+useViewStack(() => {
|
|
|
+ if (sceneModel.value) {
|
|
|
+ const model = sceneModel.value
|
|
|
+ model.enterAlignment()
|
|
|
+ return () => {
|
|
|
+ if (selectOptions.value.length) {
|
|
|
+ model.leaveTransform()
|
|
|
+ selectOptions.value = []
|
|
|
+ }
|
|
|
+ model.leaveAlignment()
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ leave()
|
|
|
+ }
|
|
|
+})
|
|
|
+useViewStack(autoSaveFuseModels)
|
|
|
+
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
@@ -114,7 +157,7 @@ watch(selectOptions, (nOptions, oOptions = []) => {
|
|
|
height: 40px;
|
|
|
right: 10px;
|
|
|
top: 50%;
|
|
|
- z-index: 1;
|
|
|
+ z-index: 2;
|
|
|
transform: translateX(40%) rotate(-90deg);
|
|
|
|
|
|
.range-content {
|
|
@@ -132,7 +175,7 @@ watch(selectOptions, (nOptions, oOptions = []) => {
|
|
|
|
|
|
.tip-left,.tip-right {
|
|
|
top: calc(var(--editor-head-height) + var(--header-top) + 11px);
|
|
|
- z-index: 1;
|
|
|
+ z-index: 2;
|
|
|
}
|
|
|
|
|
|
.tip-left {
|