116 lines
6.8 KiB
Vue
116 lines
6.8 KiB
Vue
<template>
|
||
<!-- 7. 导出资源:导出参数与资源输出操作。 -->
|
||
<div class="group">
|
||
<div class="group-head" @click="toggle('export')">
|
||
<span class="caret">{{ collapsed.export ? '▸' : '▾' }}</span><span>{{ $t('export.title') }}</span>
|
||
<button class="group-reset" data-matomo-event="export.reset" :title="$t('export.reset')" @click.stop="resetModule('export')">{{ $t('common.reset') }}</button>
|
||
</div>
|
||
<div class="group-body export-settings" v-show="sectionOpen('export')">
|
||
<label class="export-field">
|
||
<span>{{ $t('export.imagesPath') }}</span>
|
||
<input v-model.trim="exportSettings.imagesPath" class="inp export-input" type="text" placeholder="./images/" />
|
||
</label>
|
||
|
||
<label class="export-field">
|
||
<span>{{ $t('export.spineVersion') }}</span>
|
||
<select v-model="exportSettings.spineVersion" class="inp export-input">
|
||
<option value="3.8">Spine 3.8</option>
|
||
<option value="4.0">Spine 4.0</option>
|
||
<option value="4.1">Spine 4.1</option>
|
||
<option value="4.2">Spine 4.2</option>
|
||
<option value="4.3">Spine 4.3</option>
|
||
</select>
|
||
</label>
|
||
|
||
<label class="export-field">
|
||
<span>{{ $t('export.keyframeCurve') }}</span>
|
||
<select v-model="exportSettings.keyframeCurve" class="inp export-input">
|
||
<option value="linear">{{ $t('export.linear') }}</option>
|
||
<option value="bezier">{{ $t('export.smoothBezier') }}</option>
|
||
</select>
|
||
</label>
|
||
<div class="export-help">{{ $t('export.bezierHelp') }}</div>
|
||
<div v-if="exportSettings.spineVersion === '3.8'" class="export-help">{{ $t('export.spine38Help') }}</div>
|
||
|
||
<div class="export-fps-row">
|
||
<label class="export-field export-fps-field">
|
||
<span>{{ $t('export.fps') }}</span>
|
||
<input v-model.number="exportSettings.fps" class="inp export-input" type="number" min="1" max="240" step="1" @change="normalizeExportFps" />
|
||
</label>
|
||
<label class="export-checkbox"><input v-model="exportSettings.omitFps" type="checkbox" />{{ $t('export.omitFps') }}</label>
|
||
</div>
|
||
<div class="export-help">{{ $t('export.fpsHelp') }}</div>
|
||
|
||
<div class="export-switches">
|
||
<label class="switch-row export-switch">
|
||
<input v-model="exportSettings.integerFrameAlignment" type="checkbox" />
|
||
<span class="switch-ui"></span><span>{{ $t('export.integerFrames') }}</span>
|
||
</label>
|
||
<label class="switch-row export-switch">
|
||
<input v-model="exportSettings.bonePool" type="checkbox" />
|
||
<span class="switch-ui"></span><span>{{ $t('export.bonePool') }}</span>
|
||
</label>
|
||
<label class="switch-row export-switch export-switch-last">
|
||
<input v-model="exportSettings.excludeEmptyAnimations" type="checkbox" />
|
||
<span class="switch-ui"></span><span>{{ $t('export.excludeEmpty') }}</span>
|
||
</label>
|
||
</div>
|
||
<div class="export-resource-actions">
|
||
<ParticleExportFooter />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import NumSlider from '../NumSlider.vue'
|
||
import CurveEditor from '../CurveEditor.vue'
|
||
import ParticleAttributeControl from '../ParticleAttributeControl.vue'
|
||
import ColorGradientEditor from '../ColorGradientEditor.vue'
|
||
import ImageResourceCard from '../ImageResourceCard.vue'
|
||
import SpineObjectPanel from '../../spine/SpineObjectPanel.vue'
|
||
import ParticleExportFooter from './ParticleExportFooter.vue'
|
||
import { useParticlePanelContext } from './particlePanelContext'
|
||
const { exportSettings, collapsed, toggle, sectionOpen, resetModule, normalizeExportFps, select } = useParticlePanelContext()
|
||
</script>
|
||
|
||
<style scoped>
|
||
.group { border: 1px solid #2a2a3c; border-radius: 8px; margin-bottom: 10px; overflow: hidden; }
|
||
.group-head {
|
||
display: flex; align-items: center; gap: 6px; padding: 7px 10px; cursor: pointer;
|
||
font-size: 12px; font-weight: 600; color: #ccd; background: #191924; user-select: none;
|
||
}
|
||
.group-head:hover { background: #20202e; }
|
||
.group-reset {
|
||
margin-left: auto; height: 22px; padding: 0 7px; border: 1px solid #3a465f; border-radius: 5px;
|
||
background: #252d3d; color: #9eabc3; font-size: 10px; line-height: 20px; cursor: pointer;
|
||
}
|
||
.group-reset:hover { border-color: #7774ff; background: #45426f; color: #fff; }
|
||
.group-body { padding: 8px 10px 12px; }
|
||
.caret { display: inline-block; width: 12px; color: #667; font-size: 11px; }
|
||
.row { display: flex; align-items: center; gap: 8px; margin: 6px 0; font-size: 12px; color: #aab; }
|
||
.row > span:first-child { width: 60px; flex-shrink: 0; color: #8a93bb; }
|
||
.inp { flex: 1; min-width: 0; padding: 3px 5px; background: #1a1a28; border: 1px solid #2e2e44; border-radius: 5px; color: #dde; font-size: 12px; }
|
||
.placeholder { color: #667; font-size: 11px; padding: 6px 0; }
|
||
.export-settings { padding-top: 3px; }
|
||
.export-field { display: flex; flex-direction: column; gap: 6px; margin: 10px 0 13px; color: #9ca8bf; font-size: 11px; font-weight: 600; }
|
||
.export-input { width: 100%; min-height: 34px; box-sizing: border-box; padding: 6px 9px; color: #e3e7f2; background: #141a29; border-color: #35445f; }
|
||
.export-fps-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 12px; align-items: end; }
|
||
.export-fps-field { margin-bottom: 5px; }
|
||
.export-checkbox { display: flex; align-items: center; gap: 7px; min-height: 34px; margin-bottom: 5px; color: #aeb8cc; font-size: 11px; white-space: nowrap; }
|
||
.export-checkbox input { width: 17px; height: 17px; margin: 0; accent-color: #625ff1; }
|
||
.export-help { margin: -6px 0 14px; color: #66758e; font-size: 10px; line-height: 1.5; }
|
||
.export-switches { display: grid; gap: 13px; margin: 4px 0 7px; padding-top: 2px; }
|
||
.export-switch { font-weight: 600; }
|
||
.export-switch-last { margin-top: 13px; }
|
||
.export-resource-actions { margin-top: 14px; padding-top: 12px; border-top: 1px solid #2d3950; }
|
||
.inp.tiny { width: 46px; flex: 0 0 46px; text-align: center; }
|
||
.switch-row { display: flex; align-items: center; gap: 9px; color: #b8c1d5; font-size: 12px; cursor: pointer; }
|
||
.switch-row input { position: absolute; opacity: 0; pointer-events: none; }
|
||
.switch-ui { position: relative; width: 32px; height: 18px; border-radius: 10px; background: #354258; transition: background .16s ease; }
|
||
.switch-ui::after { content: ''; position: absolute; left: 2px; top: 2px; width: 14px; height: 14px; border-radius: 50%; background: #fff; transition: transform .16s ease; }
|
||
.switch-row input:checked + .switch-ui { background: #625ff1; }
|
||
.switch-row input:checked + .switch-ui::after { transform: translateX(14px); }
|
||
.switch-row input:disabled + .switch-ui { opacity: 0.45; cursor: not-allowed; }
|
||
</style>
|