feat: add background color picker and update related functionality in DesignerToolbar
This commit is contained in:
@@ -9,8 +9,10 @@ const props = defineProps<{
|
|||||||
onImportImage: (file: File) => Promise<void>;
|
onImportImage: (file: File) => Promise<void>;
|
||||||
onFillChange: (fill: string) => void;
|
onFillChange: (fill: string) => void;
|
||||||
onStrokeChange: (stroke: string) => void;
|
onStrokeChange: (stroke: string) => void;
|
||||||
|
onBackgroundChange: (background: string) => void;
|
||||||
activeFill: string | null;
|
activeFill: string | null;
|
||||||
activeStroke: string | null;
|
activeStroke: string | null;
|
||||||
|
activeBackground: string;
|
||||||
canStyleSelection: boolean;
|
canStyleSelection: boolean;
|
||||||
zoom: number;
|
zoom: number;
|
||||||
minZoom: number;
|
minZoom: number;
|
||||||
@@ -28,6 +30,7 @@ const emit = defineEmits<{
|
|||||||
const fileInput = ref<HTMLInputElement | null>(null);
|
const fileInput = ref<HTMLInputElement | null>(null);
|
||||||
const fillValue = ref(props.activeFill ?? "#111827");
|
const fillValue = ref(props.activeFill ?? "#111827");
|
||||||
const strokeValue = ref(props.activeStroke ?? "#3b82f6");
|
const strokeValue = ref(props.activeStroke ?? "#3b82f6");
|
||||||
|
const backgroundValue = ref(props.activeBackground ?? "#ffffff");
|
||||||
const zoomSliderValue = ref(Math.round(props.zoom * 100));
|
const zoomSliderValue = ref(Math.round(props.zoom * 100));
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@@ -44,6 +47,13 @@ watch(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.activeBackground,
|
||||||
|
(next) => {
|
||||||
|
backgroundValue.value = next ?? "#ffffff";
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.zoom,
|
() => props.zoom,
|
||||||
(next) => {
|
(next) => {
|
||||||
@@ -88,6 +98,13 @@ const handleStrokeChange = (event: Event) => {
|
|||||||
props.onStrokeChange(value);
|
props.onStrokeChange(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleBackgroundChange = (event: Event) => {
|
||||||
|
const input = event.target as HTMLInputElement;
|
||||||
|
const value = input.value;
|
||||||
|
backgroundValue.value = value;
|
||||||
|
props.onBackgroundChange(value);
|
||||||
|
};
|
||||||
|
|
||||||
const handleZoomInput = (event: Event) => {
|
const handleZoomInput = (event: Event) => {
|
||||||
const input = event.target as HTMLInputElement;
|
const input = event.target as HTMLInputElement;
|
||||||
const value = Number(input.value);
|
const value = Number(input.value);
|
||||||
@@ -141,6 +158,15 @@ const zoomLabel = computed(() => `${Math.round(props.zoom * 100)}%`);
|
|||||||
|
|
||||||
<!-- Color Pickers Group -->
|
<!-- Color Pickers Group -->
|
||||||
<div class="flex items-center gap-2 border-r border-slate-700/50 pr-3">
|
<div class="flex items-center gap-2 border-r border-slate-700/50 pr-3">
|
||||||
|
<label class="flex items-center gap-1.5" title="Canvas Background">
|
||||||
|
<span class="text-xs text-slate-400">Canvas</span>
|
||||||
|
<input
|
||||||
|
type="color"
|
||||||
|
class="h-8 w-12 cursor-pointer rounded border border-slate-700/70 bg-slate-800/80 p-0.5"
|
||||||
|
:value="backgroundValue"
|
||||||
|
@input="handleBackgroundChange"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
<label class="flex items-center gap-1.5" title="Fill Color">
|
<label class="flex items-center gap-1.5" title="Fill Color">
|
||||||
<span class="text-xs text-slate-400">Fill</span>
|
<span class="text-xs text-slate-400">Fill</span>
|
||||||
<input
|
<input
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ const {
|
|||||||
canStyleSelection,
|
canStyleSelection,
|
||||||
setActiveFillColor,
|
setActiveFillColor,
|
||||||
setActiveStrokeColor,
|
setActiveStrokeColor,
|
||||||
|
setBackgroundColor,
|
||||||
zoomLevel,
|
zoomLevel,
|
||||||
minZoom,
|
minZoom,
|
||||||
maxZoom,
|
maxZoom,
|
||||||
@@ -406,8 +407,10 @@ const handleCheckout = async () => {
|
|||||||
:on-import-image="addImageFromFile"
|
:on-import-image="addImageFromFile"
|
||||||
:on-fill-change="setActiveFillColor"
|
:on-fill-change="setActiveFillColor"
|
||||||
:on-stroke-change="setActiveStrokeColor"
|
:on-stroke-change="setActiveStrokeColor"
|
||||||
|
:on-background-change="setBackgroundColor"
|
||||||
:active-fill="activeFillColor"
|
:active-fill="activeFillColor"
|
||||||
:active-stroke="activeStrokeColor"
|
:active-stroke="activeStrokeColor"
|
||||||
|
:active-background="selectedTemplate.backgroundColor"
|
||||||
:can-style-selection="canStyleSelection"
|
:can-style-selection="canStyleSelection"
|
||||||
:zoom="zoomLevel"
|
:zoom="zoomLevel"
|
||||||
:min-zoom="minZoom"
|
:min-zoom="minZoom"
|
||||||
|
|||||||
@@ -753,6 +753,20 @@ export const useSlipmatDesigner = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const setBackgroundColor = (color: string) => {
|
||||||
|
const bgCircle = backgroundCircle.value;
|
||||||
|
if (!bgCircle || !canvas.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bgCircle.set({ fill: color });
|
||||||
|
selectedTemplate.value = {
|
||||||
|
...selectedTemplate.value,
|
||||||
|
backgroundColor: color,
|
||||||
|
};
|
||||||
|
canvas.value.requestRenderAll();
|
||||||
|
schedulePreviewRefresh();
|
||||||
|
};
|
||||||
|
|
||||||
watch(selectedTemplate, () => {
|
watch(selectedTemplate, () => {
|
||||||
resetZoom();
|
resetZoom();
|
||||||
applyTemplateToCanvas();
|
applyTemplateToCanvas();
|
||||||
@@ -788,6 +802,7 @@ export const useSlipmatDesigner = () => {
|
|||||||
addImageFromFile,
|
addImageFromFile,
|
||||||
setActiveFillColor,
|
setActiveFillColor,
|
||||||
setActiveStrokeColor,
|
setActiveStrokeColor,
|
||||||
|
setBackgroundColor,
|
||||||
setZoom,
|
setZoom,
|
||||||
zoomIn,
|
zoomIn,
|
||||||
zoomOut,
|
zoomOut,
|
||||||
|
|||||||
Reference in New Issue
Block a user