feat: 1.固定图层缩略图(完成)
2.工具栏新增插槽(完成) 3.loadJSON的元素顺序回发生错误
This commit is contained in:
@@ -3,25 +3,14 @@ import { ref } from "vue";
|
||||
import CanvasEditor from "./CanvasEditor/index.vue";
|
||||
import RedGreenModeExample from "./RedGreenModeExample.vue";
|
||||
import ExistsImageList from "@/component/Canvas/ExistsImageList/index.vue";
|
||||
import ToolButton from "@/component/Canvas/ExistsImageList/ToolButton.vue";
|
||||
|
||||
// 当前显示的组件
|
||||
const canvasEditor = ref();
|
||||
const currentView = ref("canvasEditor"); // 默认显示红绿图示例
|
||||
const currentView = ref("canvasEditor"); // 默认显示红绿图示例 canvasEditor redGreenExample
|
||||
|
||||
const clothingImageUrl = "/src/assets/work/3.PNG";
|
||||
|
||||
// 切换视图
|
||||
function switchView(view) {
|
||||
currentView.value = view;
|
||||
}
|
||||
|
||||
// 定义编辑器配置
|
||||
const editorConfig = {
|
||||
width: 800,
|
||||
height: 600,
|
||||
backgroundColor: "#f8f8f8",
|
||||
};
|
||||
|
||||
const imageData = [
|
||||
{
|
||||
name: "风景照片",
|
||||
@@ -62,70 +51,118 @@ const handleImageSelect = (selectedImage) => {
|
||||
// selectedImage 包含:url, name, categoryName, categoryType, originalItem
|
||||
};
|
||||
|
||||
const getJSON = () => {
|
||||
// 切换视图
|
||||
function switchView(view) {
|
||||
currentView.value = view;
|
||||
}
|
||||
|
||||
// 定义编辑器配置
|
||||
const editorConfig = {
|
||||
width: 800,
|
||||
height: 600,
|
||||
backgroundColor: "#ffffff", // 画布背景色
|
||||
};
|
||||
|
||||
const exportImage = () => {
|
||||
if (canvasEditor.value) {
|
||||
const json = canvasEditor.value.getJSON();
|
||||
console.log("获取的JSON数据:", json);
|
||||
localStorage.setItem("redGreenModeJSON", json);
|
||||
canvasEditor.value.exportImage({
|
||||
isContainFixed: true, // 是否导出底图
|
||||
isContainBg: false, // 是否导出背景
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const loadJSON = () => {
|
||||
if (canvasEditor.value) {
|
||||
const currentJSON = localStorage.getItem("redGreenModeJSON");
|
||||
canvasEditor.value.loadJSON(currentJSON);
|
||||
console.log("加载的JSON数据:", currentJSON);
|
||||
const changeCanvas = (command) => {
|
||||
console.log(command);
|
||||
};
|
||||
|
||||
const loadImageUrlToLayer = async () => {
|
||||
try {
|
||||
const imageUrl =
|
||||
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABrQAAAZNCAYAAACENbGaAAAAAXNSR0IArs4c6QAAIABJREFUeF7s3Yt208YaBtCflkuhhXLv+z/e4X6HQiFnfbYmTIwDsRM7srS91ixJY8WW9kjjVh8jXS";
|
||||
const layerId = await canvasEditor?.value?.addImageToLayer?.(imageUrl);
|
||||
console.log("新图层ID:", layerId);
|
||||
} catch (error) {
|
||||
console.error("加载图片到图层失败:", error);
|
||||
}
|
||||
};
|
||||
|
||||
// 自定义工具配置相关
|
||||
const customToolsList = ref([
|
||||
{
|
||||
id: "exportPNG",
|
||||
title: "导出PNG", //导出画布图片
|
||||
action: exportAsPNG,
|
||||
icon: { name: "CExport", size: "24" },
|
||||
class: "export-btn",
|
||||
},
|
||||
{
|
||||
id: "saveCanvas",
|
||||
title: "保存画布",
|
||||
action: saveCanvas,
|
||||
icon: { name: "CBottom", size: "24" },
|
||||
class: "save-btn",
|
||||
},
|
||||
|
||||
{
|
||||
id: "readCanvas",
|
||||
title: "读取画布",
|
||||
action: canvasProject,
|
||||
icon: { name: "CMiniMap", size: "24" },
|
||||
class: "clear-btn",
|
||||
},
|
||||
]);
|
||||
|
||||
// 自定义工具方法
|
||||
function exportAsPNG() {
|
||||
console.log("导出PNG");
|
||||
// 实现导出PNG逻辑
|
||||
exportImage();
|
||||
}
|
||||
|
||||
function saveCanvas() {
|
||||
console.log("保存项目");
|
||||
// 实现保存画布逻辑
|
||||
const json = canvasEditor.value.getJSON();
|
||||
localStorage.setItem("canvasProject", json);
|
||||
}
|
||||
|
||||
function canvasProject() {
|
||||
console.log("读取项目");
|
||||
// 实现读取画布逻辑
|
||||
const json = localStorage.getItem("canvasProject");
|
||||
if (json) {
|
||||
console.log("读取的项目JSON:", JSON.parse(json)?.layers);
|
||||
canvasEditor.value.loadJSON(json);
|
||||
} else {
|
||||
console.warn("没有找到保存的画布项目");
|
||||
}
|
||||
}
|
||||
|
||||
// 处理自定义工具点击
|
||||
const handleCustomToolClick = (tool) => {
|
||||
tool.action();
|
||||
};
|
||||
|
||||
const changeImageUrl = "/src/assets/work/1.PNG";
|
||||
|
||||
const changeFixedImage = () => {
|
||||
canvasEditor.value.changeFixedImage(clothingImageUrl);
|
||||
canvasEditor.value.changeFixedImage(changeImageUrl, {
|
||||
imageMode: "contains", // 设置底图包含在画布内
|
||||
});
|
||||
};
|
||||
</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"
|
||||
/>
|
||||
>
|
||||
</RedGreenModeExample>
|
||||
|
||||
<!-- 普通画布编辑器 -->
|
||||
<CanvasEditor
|
||||
@@ -137,10 +174,47 @@ const changeFixedImage = () => {
|
||||
:clothing-image-opts="{
|
||||
imageMode: 'contains', // 设置底图包含在画布内
|
||||
}"
|
||||
@change-canvas="changeCanvas"
|
||||
isFixedErasable
|
||||
showFixedLayer
|
||||
>
|
||||
<template #existsImageList>
|
||||
<ExistsImageList :list="imageData" @select="handleImageSelect" />
|
||||
</template>
|
||||
|
||||
<!-- 使用插槽添加自定义工具栏按钮 -->
|
||||
<template #customTools="{ toolButtonProps }">
|
||||
<!-- 分隔线 -->
|
||||
<div class="tool-separator"></div>
|
||||
|
||||
<!-- 自定义工具按钮 -->
|
||||
<ToolButton
|
||||
v-for="tool in customToolsList"
|
||||
:key="tool.id"
|
||||
:tool="tool"
|
||||
:active-tool="toolButtonProps.activeTool"
|
||||
@click="handleCustomToolClick"
|
||||
/>
|
||||
|
||||
<!-- 也可以直接使用普通的按钮 -->
|
||||
<div class="custom-tool-btn" @click="loadImageUrlToLayer">
|
||||
<span>🎨</span>
|
||||
<div class="tool-tooltip">添加画布图片</div>
|
||||
</div>
|
||||
|
||||
<div class="custom-tool-btn" @click="switchView('redGreenExample')">
|
||||
<span>红</span>
|
||||
<div class="tool-tooltip">红绿图模式</div>
|
||||
</div>
|
||||
<div class="custom-tool-btn" @click="switchView('canvasEditor')">
|
||||
<span>普</span>
|
||||
<div class="tool-tooltip">普通模式</div>
|
||||
</div>
|
||||
<div class="custom-tool-btn" @click="changeFixedImage">
|
||||
<span>更</span>
|
||||
<div class="tool-tooltip">更换底图</div>
|
||||
</div>
|
||||
</template>
|
||||
</CanvasEditor>
|
||||
</div>
|
||||
</div>
|
||||
@@ -216,6 +290,65 @@ body {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
/* 自定义工具按钮样式 */
|
||||
.tool-separator {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background-color: #e0e0e0;
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.custom-tool-btn {
|
||||
position: relative;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: none;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.custom-tool-btn:hover {
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
.custom-tool-btn:hover .tool-tooltip {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.tool-tooltip {
|
||||
display: none;
|
||||
position: absolute;
|
||||
left: 100%;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
color: white;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
margin-left: 8px;
|
||||
white-space: nowrap;
|
||||
font-size: 12px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.tool-tooltip:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 100%;
|
||||
margin-top: -5px;
|
||||
border-width: 5px;
|
||||
border-style: solid;
|
||||
border-color: transparent rgba(0, 0, 0, 0.7) transparent transparent;
|
||||
}
|
||||
|
||||
/* 深色模式适配 */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.app-header {
|
||||
|
||||
Reference in New Issue
Block a user