Files
FiDA_Front/src/components/Canvas/DepthCanvas/components/details-panel/fill-repeat.vue
2026-03-18 17:25:19 +08:00

211 lines
5.1 KiB
Vue

<template>
<div class="fill-repeat h">
<div>
<div class="title">Image</div>
<div class="content">
<img :src="object.info.fill.source" alt="" />
</div>
</div>
<div>
<div class="title">Sttings</div>
<div class="content">
<div>
<div class="label">Rotation</div>
<div class="value">
<depth-input
v-model="angle"
type="number"
@input="inputFillTransform"
@change="changeFillTransform"
/>
</div>
</div>
<div>
<div class="label">Scale</div>
<div class="value">
<depth-slider
v-model="scale"
:min="10"
:max="1000"
:tipFormatter="(v) => v + '%'"
@input="inputFillTransform"
@change="changeFillTransform"
/>
</div>
</div>
<div>
<div class="label">Opacity</div>
<div class="value">
<depth-slider
v-model="opacity"
:min="0"
:max="100"
:tipFormatter="(v) => v + '%'"
@input="inputOpacity"
@change="changeOpacity"
/>
</div>
</div>
<div>
<div class="label">Gap X</div>
<div class="value">
<depth-slider
v-model="gapX"
:min="0"
:max="1000"
:tipFormatter="(v) => v + 'px'"
@input="inputFillGap"
@change="changeFillGap"
/>
</div>
</div>
<div>
<div class="label">Gap Y</div>
<div class="value">
<depth-slider
v-model="gapY"
:min="0"
:max="1000"
:tipFormatter="(v) => v + 'px'"
@input="inputFillGap"
@change="changeFillGap"
/>
</div>
</div>
<div>
<div class="label">Offset</div>
<div class="value">
<depth-offset-tool
v-model="offset"
:show-dish="false"
@input="inputFillTransform"
@change="changeFillTransform"
/>
</div>
</div>
<div class="offset-tool-dish">
<depth-offset-tool
v-model="offset"
:show-input="false"
@input="inputFillTransform"
@change="changeFillTransform"
/>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, inject, computed, nextTick, onBeforeUnmount } from 'vue'
import DepthOffsetTool from '../tools/depth-offset-tool.vue'
import DepthSlider from '../tools/depth-slider.vue'
import DepthInput from '../tools/depth-input.vue'
import { getTransformScaleAngle } from '../../manager/ObjectManager'
const objectManager = inject('objectManager') as any
const stateManager = inject('stateManager') as any
const props = defineProps({
object: {
type: Object,
default: () => ({})
}
})
const id = computed(() => props.object.info.id)
const angle = ref(0)
const scale = ref(100)
const gapX = ref(0)
const gapY = ref(0)
const offset = ref({ x: 0, y: 0 })
const opacity = ref(100)
const updateData = async () => {
await nextTick()
const fill = props.object.fill
angle.value = getTransformScaleAngle(fill?.patternTransform).angle
scale.value = Math.round(getTransformScaleAngle(fill?.patternTransform).scale * 100)
gapX.value = props.object.info.fill.gapX
gapY.value = props.object.info.fill.gapY
offset.value = {
x: Math.round((fill.offsetX / props.object.width) * 100),
y: Math.round((fill.offsetY / props.object.height) * 100)
}
opacity.value = Math.round(props.object.opacity * 100)
}
updateData()
const inputFillTransform = () => setFillTransform(false)
const changeFillTransform = () => setFillTransform(true)
const setFillTransform = (isRecord: boolean) => {
const options = {
scale: scale.value / 100,
angle: angle.value,
offsetX: props.object.width * (offset.value.x / 100),
offsetY: props.object.height * (offset.value.y / 100)
}
objectManager.updateFillRepeatTransform(id.value, options, isRecord)
}
const inputFillGap = () => setFillGap(false)
const changeFillGap = () => setFillGap(true)
const setFillGap = (isRecord: boolean) => {
const options = {
gapX: gapX.value,
gapY: gapY.value
}
objectManager.updateFillRepeatGap(id.value, options, isRecord)
}
const inputOpacity = () => setOpacity(false)
const changeOpacity = () => setOpacity(true)
const setOpacity = (isRecord: boolean) => {
const options = {
opacity: opacity.value / 100
}
objectManager.updateProperty(id.value, options, isRecord)
}
stateManager.event.add('canvas:undo', updateData)
stateManager.event.add('canvas:redo', updateData)
onBeforeUnmount(() => {
stateManager.event.remove('canvas:undo', updateData)
stateManager.event.remove('canvas:redo', updateData)
})
</script>
<style lang="less" scoped>
.fill-repeat {
> div {
> .content {
> img {
display: block;
width: 55%;
height: auto;
margin: 0 auto;
}
> div {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 1.6rem;
&:last-child {
margin-bottom: 0;
}
> .label {
min-width: 6rem;
margin-right: 0.8rem;
font-size: 1.2rem;
}
> .value {
flex: 1;
}
}
> .offset-tool-dish {
display: flex;
align-items: center;
justify-content: center;
}
}
}
}
</style>