242 lines
5.2 KiB
Vue
242 lines
5.2 KiB
Vue
<script setup>
|
||
import { ref } from "vue";
|
||
import CanvasEditor from "./CanvasEditor/index.vue";
|
||
import RedGreenModeExample from "./RedGreenModeExample.vue";
|
||
import ExistsImageList from "@/component/Canvas/ExistsImageList/index.vue";
|
||
|
||
// 当前显示的组件
|
||
const canvasEditor = ref();
|
||
const currentView = ref("canvasEditor"); // 默认显示红绿图示例
|
||
|
||
const clothingImageUrl = "/src/assets/work/3.PNG";
|
||
|
||
// 切换视图
|
||
function switchView(view) {
|
||
currentView.value = view;
|
||
}
|
||
|
||
// 定义编辑器配置
|
||
const editorConfig = {
|
||
width: 800,
|
||
height: 600,
|
||
backgroundColor: "#f8f8f8",
|
||
};
|
||
|
||
const imageData = [
|
||
{
|
||
name: "风景照片",
|
||
type: "风景",
|
||
imgList: [
|
||
{ url: "/src/assets/work/1.PNG", name: "山景" },
|
||
{ url: "/src/assets/work/2.PNG", name: "海景" },
|
||
],
|
||
},
|
||
{
|
||
name: "人物照片",
|
||
type: "人物",
|
||
imgList: [
|
||
{ url: "/src/assets/work/3.PNG", name: "肖像1" },
|
||
{ url: "/src/assets/work/5.PNG", name: "肖像2" },
|
||
],
|
||
},
|
||
{
|
||
name: "衣服照片",
|
||
type: "衣服",
|
||
imgList: [
|
||
{ url: "/src/assets/work/3.PNG", name: "肖像1" },
|
||
{ url: "/src/assets/work/5.PNG", name: "肖像2" },
|
||
],
|
||
},
|
||
{
|
||
name: "裤子照片",
|
||
type: "裤子",
|
||
imgList: [
|
||
{ url: "/src/assets/work/IMG_0001.PNG", name: "肖像1" },
|
||
{ url: "/src/assets/work/IMG_0008.PNG", name: "肖像2" },
|
||
],
|
||
},
|
||
];
|
||
|
||
const handleImageSelect = (selectedImage) => {
|
||
console.log("选中的图片:", selectedImage);
|
||
// selectedImage 包含:url, name, categoryName, categoryType, originalItem
|
||
};
|
||
|
||
const getJSON = () => {
|
||
if (canvasEditor.value) {
|
||
const json = canvasEditor.value.getJSON();
|
||
console.log("获取的JSON数据:", json);
|
||
localStorage.setItem("redGreenModeJSON", json);
|
||
}
|
||
};
|
||
|
||
const loadJSON = () => {
|
||
if (canvasEditor.value) {
|
||
const currentJSON = localStorage.getItem("redGreenModeJSON");
|
||
canvasEditor.value.loadJSON(currentJSON);
|
||
console.log("加载的JSON数据:", currentJSON);
|
||
}
|
||
};
|
||
|
||
const changeFixedImage = () => {
|
||
canvasEditor.value.changeFixedImage(clothingImageUrl);
|
||
};
|
||
</script>
|
||
|
||
<template>
|
||
<div class="app-container">
|
||
<!-- <div class="canvas-wrapper-btns">
|
||
<div @click="changeFixedImage">更换底图</div>
|
||
<div @click="getJSON">获取JSON</div>
|
||
<div @click="loadJSON">读取JSON</div>
|
||
</div> -->
|
||
<!-- 内容区域 -->
|
||
<div class="app-content">
|
||
<div
|
||
style="
|
||
position: fixed;
|
||
top: 0px;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
z-index: 999;
|
||
"
|
||
>
|
||
<div class="view-switcher">
|
||
<div
|
||
class="switch-btn"
|
||
:class="{ active: currentView === 'redGreenExample' }"
|
||
@click="switchView('redGreenExample')"
|
||
>
|
||
红绿图模式示例
|
||
</div>
|
||
<div
|
||
class="switch-btn"
|
||
:class="{ active: currentView === 'canvasEditor' }"
|
||
@click="switchView('canvasEditor')"
|
||
>
|
||
普通画布编辑器
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- 红绿图模式示例 -->
|
||
<RedGreenModeExample
|
||
v-if="currentView === 'redGreenExample'"
|
||
key="redGreenExample"
|
||
/>
|
||
|
||
<!-- 普通画布编辑器 -->
|
||
<CanvasEditor
|
||
ref="canvasEditor"
|
||
key="canvasEditor"
|
||
v-if="currentView === 'canvasEditor'"
|
||
:config="editorConfig"
|
||
:clothingImageUrl="clothingImageUrl"
|
||
:clothing-image-opts="{
|
||
imageMode: 'contains', // 设置底图包含在画布内
|
||
}"
|
||
>
|
||
<template #existsImageList>
|
||
<ExistsImageList :list="imageData" @select="handleImageSelect" />
|
||
</template>
|
||
</CanvasEditor>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<style scoped lang="less">
|
||
* {
|
||
margin: 0;
|
||
padding: 0;
|
||
box-sizing: border-box;
|
||
}
|
||
.canvas-wrapper-btns {
|
||
position: fixed;
|
||
top: 10px;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
z-index: 1000;
|
||
display: flex;
|
||
gap: 10px;
|
||
}
|
||
html,
|
||
body {
|
||
height: 100%;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.app-container {
|
||
height: 100vh;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.view-switcher {
|
||
display: flex;
|
||
gap: 8px;
|
||
|
||
.switch-btn {
|
||
padding: 8px 16px;
|
||
border: 1px solid #ddd;
|
||
border-radius: 6px;
|
||
background: white;
|
||
cursor: pointer;
|
||
font-size: 14px;
|
||
transition: all 0.2s;
|
||
|
||
&:hover {
|
||
border-color: #007bff;
|
||
background: #f8f9fa;
|
||
}
|
||
|
||
&.active {
|
||
border-color: #007bff;
|
||
background: #007bff;
|
||
color: white;
|
||
}
|
||
}
|
||
}
|
||
|
||
.app-header {
|
||
position: fixed;
|
||
top: 10px;
|
||
right: 10px;
|
||
z-index: 1000;
|
||
background: rgba(255, 255, 255, 0.95);
|
||
padding: 8px;
|
||
border-radius: 8px;
|
||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||
backdrop-filter: blur(10px);
|
||
}
|
||
|
||
.app-content {
|
||
flex: 1;
|
||
height: 100vh;
|
||
}
|
||
|
||
/* 深色模式适配 */
|
||
@media (prefers-color-scheme: dark) {
|
||
.app-header {
|
||
background: rgba(45, 45, 45, 0.95);
|
||
|
||
.view-switcher .switch-btn {
|
||
background: #3d3d3d;
|
||
border-color: #555;
|
||
color: #e0e0e0;
|
||
|
||
&:hover {
|
||
border-color: #007bff;
|
||
background: #444;
|
||
}
|
||
|
||
&.active {
|
||
background: #007bff;
|
||
color: white;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style>
|