feat: enhance designer canvas with multi-view support and model viewer integration
Some checks failed
Deploy Production / deploy (push) Failing after 1m11s
Some checks failed
Deploy Production / deploy (push) Failing after 1m11s
- Added canvasId prop to DesignerCanvas for identifying multiple canvases. - Implemented active view selection (front, top, left, right) in designer page. - Updated DesignerCanvas to maintain aspect ratio and dimensions based on view. - Integrated @google/model-viewer for 3D model rendering on the index page. - Refactored useSlipmatDesigner to manage multiple canvases and their states. - Added LAMESA.glb model file for 3D representation. - Updated package.json and package-lock.json to include @google/model-viewer dependency.
This commit is contained in:
@@ -18,6 +18,7 @@ const {
|
||||
previewUrl,
|
||||
registerCanvas,
|
||||
unregisterCanvas,
|
||||
setActiveCanvas,
|
||||
addTextbox,
|
||||
addShape,
|
||||
addImageFromFile,
|
||||
@@ -41,6 +42,14 @@ const {
|
||||
resetZoom,
|
||||
} = useSlipmatDesigner();
|
||||
|
||||
// Active view selector for multi-canvas design
|
||||
const activeView = ref<'front' | 'top' | 'left' | 'right'>('front');
|
||||
|
||||
const setActiveView = (view: 'front' | 'top' | 'left' | 'right') => {
|
||||
activeView.value = view;
|
||||
setActiveCanvas(view);
|
||||
};
|
||||
|
||||
const DESIGN_PRICE_USD = 39.99;
|
||||
|
||||
const { user, backendUser, initAuth, isLoading } = useAuth();
|
||||
@@ -376,13 +385,13 @@ const handleCheckout = async () => {
|
||||
<section class="mt-10 flex flex-col gap-8 lg:grid lg:grid-cols-[320px_minmax(0,1fr)] lg:gap-6">
|
||||
<!-- Left Sidebar - Template Picker and Preview (together on desktop, separate on mobile) -->
|
||||
<div class="contents lg:block lg:space-y-6">
|
||||
<div class="order-1">
|
||||
<!-- <div class="order-1">
|
||||
<TemplatePicker
|
||||
:templates="templates"
|
||||
:selected-template-id="selectedTemplate.id"
|
||||
@select="handleTemplateSelect"
|
||||
/>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<div class="order-3">
|
||||
<DesignerPreview
|
||||
@@ -396,6 +405,23 @@ const handleCheckout = async () => {
|
||||
|
||||
<!-- Designer Canvas - Second on mobile, right column on desktop -->
|
||||
<div class="order-2 flex flex-col gap-6 lg:order-0">
|
||||
<!-- View Selector Tabs -->
|
||||
<div class="flex gap-2 rounded-lg border border-slate-200 bg-slate-50 p-2">
|
||||
<button
|
||||
v-for="view in ['front', 'top', 'left', 'right']"
|
||||
:key="view"
|
||||
@click="setActiveView(view as 'front' | 'top' | 'left' | 'right')"
|
||||
:class="[
|
||||
'flex-1 rounded-md px-4 py-2 text-sm font-semibold capitalize transition-all',
|
||||
activeView === view
|
||||
? 'bg-white text-slate-900 shadow-sm'
|
||||
: 'text-slate-600 hover:text-slate-900'
|
||||
]"
|
||||
>
|
||||
{{ view }} View
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="rounded-3xl border border-slate-200 bg-white shadow-xl"
|
||||
>
|
||||
@@ -420,17 +446,55 @@ const handleCheckout = async () => {
|
||||
:on-zoom-out="zoomOut"
|
||||
:on-zoom-reset="resetZoom"
|
||||
/>
|
||||
<div class="p-6">
|
||||
<DesignerCanvas
|
||||
:size="displaySize"
|
||||
:background-color="selectedTemplate.backgroundColor"
|
||||
:register-canvas="registerCanvas"
|
||||
:unregister-canvas="unregisterCanvas"
|
||||
/>
|
||||
<div class="p-6 space-y-4">
|
||||
<!-- Canvas for each view -->
|
||||
<div v-show="activeView === 'front'" class="canvas-container">
|
||||
<h3 class="mb-2 text-sm font-semibold text-slate-700">Front View</h3>
|
||||
<DesignerCanvas
|
||||
canvas-id="front"
|
||||
:size="displaySize"
|
||||
:background-color="selectedTemplate.backgroundColor"
|
||||
:register-canvas="registerCanvas"
|
||||
:unregister-canvas="unregisterCanvas"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-show="activeView === 'top'" class="canvas-container">
|
||||
<h3 class="mb-2 text-sm font-semibold text-slate-700">Top View</h3>
|
||||
<DesignerCanvas
|
||||
canvas-id="top"
|
||||
:size="displaySize"
|
||||
:background-color="selectedTemplate.backgroundColor"
|
||||
:register-canvas="registerCanvas"
|
||||
:unregister-canvas="unregisterCanvas"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-show="activeView === 'left'" class="canvas-container">
|
||||
<h3 class="mb-2 text-sm font-semibold text-slate-700">Left View</h3>
|
||||
<DesignerCanvas
|
||||
canvas-id="left"
|
||||
:size="displaySize"
|
||||
:background-color="selectedTemplate.backgroundColor"
|
||||
:register-canvas="registerCanvas"
|
||||
:unregister-canvas="unregisterCanvas"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-show="activeView === 'right'" class="canvas-container">
|
||||
<h3 class="mb-2 text-sm font-semibold text-slate-700">Right View</h3>
|
||||
<DesignerCanvas
|
||||
canvas-id="right"
|
||||
:size="displaySize"
|
||||
:background-color="selectedTemplate.backgroundColor"
|
||||
:register-canvas="registerCanvas"
|
||||
:unregister-canvas="unregisterCanvas"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<p class="mt-4 text-sm text-slate-600">
|
||||
Safe zone and bleed guides update automatically when you switch
|
||||
templates. Use the toolbar to layer text, shapes, and imagery
|
||||
inside the design area.
|
||||
Design each view of your table jersey separately. Switch between views using the tabs above.
|
||||
Safe zone and bleed guides update automatically when you switch templates.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user