合并画布代码

This commit is contained in:
X1627315083
2025-06-18 11:05:23 +08:00
parent 903c0ebdf5
commit 9c7fae36eb
118 changed files with 23633 additions and 8201 deletions

View File

@@ -17,6 +17,7 @@ provide("brushStore", BrushStore);
const toolManager = inject("toolManager");
const layerManager = inject("layerManager");
const isShowLayerPanel = inject("isShowLayerPanel", ref(false));
const props = defineProps({
activeTool: String,
@@ -24,6 +25,7 @@ const props = defineProps({
canvasHeight: Number,
canvasColor: String,
brushSize: Number,
enabledRedGreenMode: Boolean,
});
const emit = defineEmits([
@@ -40,9 +42,9 @@ const showBrushPanel = ref(false);
const brushPanelRef = ref(null);
// 计算属性
const shouldShowBrushSettings = computed(() => {
return props.activeTool === OperationType.DRAW;
});
// const shouldShowBrushSettings = computed(() => {
// return props.activeTool === OperationType.DRAW;
// });
function updateCanvasSize() {
if (!layerManager) {
@@ -86,6 +88,11 @@ function updateCanvasColor() {
// 切换笔刷面板显示状态
function toggleBrushPanel() {
// 如果笔刷没有激活 则激活笔刷工具
if (toolManager?.activeTool !== OperationType.DRAW) {
toolManager.setToolWithCommand(OperationType.DRAW);
}
showBrushPanel.value = !showBrushPanel.value;
}
@@ -176,16 +183,37 @@ function syncBrushStoreToManager() {
// 点击外部时关闭笔刷面板
function handleClickOutside(event) {
if (
showBrushPanel.value &&
brushPanelRef.value &&
!brushPanelRef.value.contains(event.target) &&
!event.target.closest(".brush-selector")
) {
showBrushPanel.value = false;
// if (isShowLayerPanel.value) {
// // 如果点击的是图层面板或其内部元素,则不关闭
// if (event.target.closest(".layers-panel")) {
// return;
// }
// // 关闭图层面板
// isShowLayerPanel.value = false;
// }
if (showBrushPanel.value) {
// 检查是否点击了笔刷选择器按钮
if (event.target.closest(".brush-selector")) {
return;
}
// 检查是否点击了笔刷面板或其内部元素
if (event.target.closest(".brush-panel")) {
return;
}
// 如果都不是,则关闭面板
if (showBrushPanel.value) {
showBrushPanel.value = false;
}
}
}
function showLayerPanel() {
isShowLayerPanel.value = !isShowLayerPanel.value;
}
onMounted(() => {
// 获取工具管理器和笔刷管理器
const brushManager = toolManager?.brushManager;
@@ -229,94 +257,51 @@ onMounted(() => {
<template>
<div class="canvas-header">
<span class="canvas-title">Canvas</span>
<!-- 默认设置 -->
<div
v-if="
<div class="canvas-header-wrapper">
<span class="canvas-title">Canvas</span>
<!-- 默认设置 -->
<!-- v-if="
!activeTool ||
activeTool === OperationType.SELECT ||
activeTool === OperationType.PAN
"
class="canvas-settings"
>
<div class="setting-group">
<span class="setting-label">Width</span>
<input
type="text"
:value="canvasWidth"
class="setting-input"
@input="$emit('update:canvasWidth', Number($event.target.value))"
@change="updateCanvasSize"
/>
</div>
<div class="setting-group">
<span class="setting-label">Height</span>
<input
type="text"
:value="canvasHeight"
class="setting-input"
@input="$emit('update:canvasHeight', Number($event.target.value))"
@change="updateCanvasSize"
/>
</div>
<div class="setting-group">
<span class="setting-label">Color</span>
<div class="color-picker-wrapper">
" -->
<div class="canvas-settings" v-if="!props.enabledRedGreenMode">
<div class="setting-group">
<span class="setting-label">Width</span>
<input
type="color"
:value="canvasColor"
class="color-picker"
@input="$emit('update:canvasColor', $event.target.value)"
@change="updateCanvasColor"
type="text"
:value="canvasWidth"
class="setting-input"
@input="$emit('update:canvasWidth', Number($event.target.value))"
@change="updateCanvasSize"
/>
<span class="color-dropdown">▼</span>
</div>
<div class="setting-group">
<span class="setting-label">Height</span>
<input
type="text"
:value="canvasHeight"
class="setting-input"
@input="$emit('update:canvasHeight', Number($event.target.value))"
@change="updateCanvasSize"
/>
</div>
<div class="setting-group">
<span class="setting-label">Color</span>
<div class="color-picker-wrapper">
<input
type="color"
:value="canvasColor"
class="color-picker"
@input="$emit('update:canvasColor', $event.target.value)"
@change="updateCanvasColor"
/>
<span class="color-dropdown"></span>
</div>
</div>
</div>
</div>
<!-- 绘图工具设置 -->
<div v-if="shouldShowBrushSettings" class="canvas-settings">
<!-- 简化的笔刷控制UI -->
<!-- <div class="setting-group">
<span class="setting-label">大小:</span>
<input
type="range"
:value="BrushStore.state.size"
min="0.5"
max="100"
step="0.5"
class="size-slider"
@input="handleBrushSizeChange"
/>
<span class="size-value">{{ BrushStore.state.size }}px</span>
</div> -->
<div class="setting-group">
<span class="setting-label">笔刷:</span>
<div class="brush-selector" @click="toggleBrushPanel">
<div
class="brush-preview"
:style="{
backgroundColor: BrushStore.state.color,
height: BrushStore.state.type === 'marker' ? '4px' : '2px',
opacity: BrushStore.state.opacity,
}"
></div>
<span class="brush-dropdown">▼</span>
</div>
<!-- 笔刷面板 -->
<div
v-if="showBrushPanel"
class="brush-panel-container"
ref="brushPanelRef"
>
<BrushPanel />
</div>
</div>
<div class="setting-group">
<span class="setting-label">颜色:</span>
<div class="color-picker-wrapper">
<input
@@ -327,64 +312,71 @@ onMounted(() => {
/>
<span class="color-dropdown"></span>
</div>
</div>
</div>
<!-- 文本工具设置 -->
<div v-if="activeTool === OperationType.TEXT" class="canvas-settings">
<div class="setting-group">
<span class="setting-label">Font:</span>
<select class="font-select">
<option value="Arial">Arial</option>
<option value="Times New Roman">Times New Roman</option>
<option value="Courier New">Courier New</option>
</select>
</div>
<div class="setting-group">
<span class="setting-label">Size:</span>
<input
type="number"
class="setting-input"
value="16"
min="8"
max="72"
/>
</div>
<div class="setting-group">
<span class="setting-label">Color:</span>
<div class="color-picker-wrapper">
<input type="color" class="color-picker" value="#000000" />
<span class="color-dropdown">▼</span>
</div>
</div>
</div>
<!-- 上传工具设置 -->
<div v-if="activeTool === OperationType.UPLOAD" class="canvas-settings">
<div class="setting-group">
<span class="setting-label">Upload Type:</span>
<select class="setting-select">
<option value="image">Image</option>
<option value="vector">Vector Graphics</option>
</select>
</div>
</div> -->
</div>
<!-- 导出设置 -->
<div class="setting-group export-group">
<!-- <div class="setting-group export-group">
<span class="export-model-select">exportModel.select:</span>
<span class="export-model-dropdown"></span>
</div> -->
<!-- 绘图工具设置 -->
<div class="canvas-settings gap-20" v-if="!props.enabledRedGreenMode">
<div
class="btn"
:class="{ active: showBrushPanel }"
@click="toggleBrushPanel"
>
<!-- <span class="setting-label">笔刷:</span>/ -->
<div class="brush-selector">
<SvgIcon name="CBrushTop" size="22"></SvgIcon>
<!-- <div
class="brush-preview"
:style="{
backgroundColor: BrushStore.state.color,
height: BrushStore.state.type === 'marker' ? '4px' : '2px',
opacity: BrushStore.state.opacity,
}"
></div> -->
<!-- <span class="brush-dropdown"></span> -->
</div>
<!-- 笔刷面板 -->
<div
v-if="showBrushPanel"
class="brush-panel-container"
ref="brushPanelRef"
>
<Teleport to="body">
<BrushPanel />
</Teleport>
</div>
</div>
<div
class="btn"
:class="{ active: isShowLayerPanel }"
@click="showLayerPanel"
>
<SvgIcon name="CLayout" size="26"></SvgIcon>
</div>
</div>
</div>
</template>
<style scoped>
<style scoped lang="less">
.canvas-header {
display: flex;
align-items: center;
padding: 10px 20px;
border-bottom: 1px solid #e0e0e0;
user-select: none;
height: 52px;
overflow: hidden;
width: 100%;
.canvas-header-wrapper {
display: flex;
align-items: center;
flex: auto;
}
}
.canvas-title {
@@ -393,19 +385,44 @@ onMounted(() => {
margin-right: 30px;
display: flex;
align-items: center;
}
.canvas-title::before {
content: "⟳";
margin-right: 5px;
font-size: 14px;
color: #333;
// &:before {
// // /* content: "⟳";
// // margin-right: 5px;
// // font-size: 14px; */
// }
}
.canvas-settings {
display: flex;
align-items: center;
gap: 15px;
flex: 1;
gap: 8px;
color: #213547;
.btn {
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 4px;
overflow: hidden;
cursor: pointer;
background-color: #f0f0f0;
&.active,
&:active {
background-color: #e6f7ff;
color: #1890ff;
}
&:hover {
background-color: #e6f7ff;
// color: #1890ff;
}
}
}
.gap-20 {
gap: 20px;
}
.setting-group {
@@ -476,15 +493,15 @@ onMounted(() => {
}
.brush-selector {
display: flex;
align-items: center;
border: 1px solid #ddd;
border-radius: 4px;
padding: 5px;
cursor: pointer;
background-color: white;
width: 80px;
justify-content: space-between;
// display: flex;
// align-items: center;
// border: 1px solid #ddd;
// border-radius: 4px;
// padding: 5px;
// cursor: pointer;
// background-color: white;
// width: 80px;
// justify-content: space-between;
}
.brush-preview {