Lashtw commited on
Commit
47b8dd1
·
verified ·
1 Parent(s): d806a91

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +97 -6
index.html CHANGED
@@ -19,6 +19,9 @@
19
  <link href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.13/cropper.min.css" rel="stylesheet">
20
  <script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.13/cropper.min.js"></script>
21
 
 
 
 
22
  <!-- Google Fonts -->
23
  <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@400;700&display=swap" rel="stylesheet">
24
 
@@ -147,7 +150,7 @@
147
  <!-- Grid Settings -->
148
  <div>
149
  <label class="block text-sm font-bold text-slate-700 mb-2">📐 網格設定</label>
150
- <div class="grid grid-cols-3 gap-2 mb-2">
151
  <button
152
  v-for="conf in gridOptions"
153
  :key="conf.label"
@@ -157,6 +160,14 @@
157
  >
158
  {{ conf.label }}
159
  </button>
 
 
 
 
 
 
 
 
160
  </div>
161
  <!-- Clear All Button -->
162
  <button
@@ -201,7 +212,7 @@
201
  class="py-2 bg-slate-600 hover:bg-slate-700 text-white font-bold rounded-lg shadow-sm active:scale-95 transition-all flex items-center justify-center gap-1 text-sm"
202
  >
203
  <!-- Upload Icon -->
204
- <svg viewBox="0 0 512 512" class="w-4 h-4 fill-current mr-1"><path d="M288 109.3V352c0 17.7-14.3 32-32 32s-32-14.3-32-32V109.3l-73.4 73.4c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3l128-128c12.5-12.5 32.8-12.5 45.3 0l128 128c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L288 109.3zM64 352H192c0 35.3 28.7 64 64 64s64-28.7 64-64H448c35.3 0 64 28.7 64 64v32c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V416c0-35.3 28.7-64 64-64zM432 456c13.3 0 24-10.7 24-24s-10.7-24-24-24s-24 10.7-24 24s10.7 24 24 24z"/></svg>
205
  匯入舊檔
206
  </button>
207
  <input
@@ -374,6 +385,35 @@
374
  </div>
375
  </div>
376
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
377
  </div>
378
 
379
  <!-- =======================
@@ -501,7 +541,6 @@
501
  const currentGrid = ref(gridOptions[1]); // Default 6x8
502
 
503
  // --- Colors ---
504
- // Slate-800 is default
505
  const colors = ['#1e293b', '#ef4444', '#f97316', '#f59e0b', '#22c55e', '#14b8a6', '#3b82f6', '#6366f1', '#a855f7', '#ec4899'];
506
 
507
  // --- Icons (Unified to Unicode Emoji) ---
@@ -552,6 +591,10 @@
552
  const imageUploadInput = ref(null);
553
  const cropperImgRef = ref(null);
554
 
 
 
 
 
555
  // Image Upload & Crop State
556
  const showCropper = ref(false);
557
  const tempImageSrc = ref('');
@@ -562,6 +605,12 @@
562
  const AUTOSAVE_KEY = 'magic_origami_autosave_v1';
563
 
564
  const activePageCells = computed(() => pages.value[activePageId.value - 1].cells);
 
 
 
 
 
 
565
 
566
  // --- Actions ---
567
 
@@ -570,8 +619,7 @@
570
 
571
  const hasContent = pages.value.some(p => p.cells.some(c => c.content !== ''));
572
  if (hasContent) {
573
- alert("若要切換網格設定請清除內容後再切換。");
574
- return;
575
  }
576
 
577
  currentGrid.value = conf;
@@ -587,6 +635,43 @@
587
  viewMode.value = 'overview';
588
  };
589
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
590
  const clearAllContent = () => {
591
  const hasContent = pages.value.some(p => p.cells.some(c => c.content !== ''));
592
  if (!hasContent) {
@@ -1065,7 +1150,13 @@
1065
  cancelCrop,
1066
  confirmCrop,
1067
  applyCustomImageToCell,
1068
- removeCustomImage
 
 
 
 
 
 
1069
  };
1070
  }
1071
  }).mount('#app');
 
19
  <link href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.13/cropper.min.css" rel="stylesheet">
20
  <script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.13/cropper.min.js"></script>
21
 
22
+ <!-- FontAwesome 6 (For Consistent Icons) -->
23
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
24
+
25
  <!-- Google Fonts -->
26
  <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@400;700&display=swap" rel="stylesheet">
27
 
 
150
  <!-- Grid Settings -->
151
  <div>
152
  <label class="block text-sm font-bold text-slate-700 mb-2">📐 網格設定</label>
153
+ <div class="grid grid-cols-2 gap-2 mb-2">
154
  <button
155
  v-for="conf in gridOptions"
156
  :key="conf.label"
 
160
  >
161
  {{ conf.label }}
162
  </button>
163
+ <!-- Custom Grid Button -->
164
+ <button
165
+ @click="openCustomGridModal"
166
+ class="py-2 text-sm border border-dashed border-indigo-300 text-indigo-600 rounded-lg hover:bg-indigo-50 active:scale-95 transition-all font-bold"
167
+ :class="{'bg-indigo-600 text-white border-indigo-600 border-solid': isCustomGridActive}"
168
+ >
169
+ <i class="fa-solid fa-gear mr-1"></i> 自訂網格
170
+ </button>
171
  </div>
172
  <!-- Clear All Button -->
173
  <button
 
212
  class="py-2 bg-slate-600 hover:bg-slate-700 text-white font-bold rounded-lg shadow-sm active:scale-95 transition-all flex items-center justify-center gap-1 text-sm"
213
  >
214
  <!-- Upload Icon -->
215
+ <svg viewBox="0 0 512 512" class="w-4 h-4 fill-current mr-1"><path d="M288 109.3V352c0 17.7-14.3 32-32 32s-32-14.3-32-32V109.3l-73.4 73.4c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3l128-128c12.5-12.5 32.8-12.5 45.3 0l128 128c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L288 109.3zM64 352H192c0 35.3 28.7 64 64 64s64-28.7 64-64H448c35.3 0 64 28.7 64 64v32c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V416c0-35.3 28.7-64 64-64zM432 456c13.3 0 24-10.7 24-24s-10.7-24-24-24s-24 10.7 24 24s10.7 24 24 24z"/></svg>
216
  匯入舊檔
217
  </button>
218
  <input
 
385
  </div>
386
  </div>
387
 
388
+ <!-- Custom Grid Modal -->
389
+ <div v-if="showGridModal" class="absolute inset-0 z-50 bg-slate-900/50 flex items-center justify-center p-4 animate-fade-in">
390
+ <div class="bg-white rounded-xl shadow-2xl w-full max-w-sm overflow-hidden">
391
+ <div class="bg-indigo-600 px-6 py-4">
392
+ <h3 class="text-lg font-bold text-white flex items-center gap-2">
393
+ <i class="fa-solid fa-gear"></i> 自訂網格設定
394
+ </h3>
395
+ </div>
396
+ <div class="p-6 space-y-4">
397
+ <div>
398
+ <label class="block text-sm font-bold text-slate-700 mb-1">列數 (Rows)</label>
399
+ <input type="number" v-model.number="customGridConfig.rows" min="1" max="20" class="w-full border-2 border-slate-200 rounded-lg p-2 focus:border-indigo-500 focus:outline-none">
400
+ </div>
401
+ <div>
402
+ <label class="block text-sm font-bold text-slate-700 mb-1">欄數 (Columns)</label>
403
+ <input type="number" v-model.number="customGridConfig.cols" min="1" max="20" class="w-full border-2 border-slate-200 rounded-lg p-2 focus:border-indigo-500 focus:outline-none">
404
+ </div>
405
+ <p class="text-xs text-slate-500 bg-slate-50 p-2 rounded">
406
+ <i class="fa-solid fa-circle-info mr-1"></i>
407
+ 建議範圍:1 ~ 12,過大可能會影響列印清晰度。
408
+ </p>
409
+ </div>
410
+ <div class="bg-slate-50 px-6 py-4 flex justify-end gap-2 border-t border-slate-100">
411
+ <button @click="showGridModal = false" class="px-4 py-2 text-slate-600 font-bold hover:bg-slate-200 rounded-lg transition-all">取消</button>
412
+ <button @click="confirmCustomGrid" class="px-4 py-2 bg-indigo-600 text-white font-bold rounded-lg hover:bg-indigo-700 transition-all shadow-md">確認套用</button>
413
+ </div>
414
+ </div>
415
+ </div>
416
+
417
  </div>
418
 
419
  <!-- =======================
 
541
  const currentGrid = ref(gridOptions[1]); // Default 6x8
542
 
543
  // --- Colors ---
 
544
  const colors = ['#1e293b', '#ef4444', '#f97316', '#f59e0b', '#22c55e', '#14b8a6', '#3b82f6', '#6366f1', '#a855f7', '#ec4899'];
545
 
546
  // --- Icons (Unified to Unicode Emoji) ---
 
591
  const imageUploadInput = ref(null);
592
  const cropperImgRef = ref(null);
593
 
594
+ // Custom Grid State
595
+ const showGridModal = ref(false);
596
+ const customGridConfig = ref({ rows: 10, cols: 10 });
597
+
598
  // Image Upload & Crop State
599
  const showCropper = ref(false);
600
  const tempImageSrc = ref('');
 
605
  const AUTOSAVE_KEY = 'magic_origami_autosave_v1';
606
 
607
  const activePageCells = computed(() => pages.value[activePageId.value - 1].cells);
608
+
609
+ // Computed for UI style of custom button
610
+ const isCustomGridActive = computed(() => {
611
+ // If current config matches none of the preset labels, it's custom
612
+ return !gridOptions.some(opt => opt.label === currentGrid.value.label);
613
+ });
614
 
615
  // --- Actions ---
616
 
 
619
 
620
  const hasContent = pages.value.some(p => p.cells.some(c => c.content !== ''));
621
  if (hasContent) {
622
+ if(!confirm("切換網格設定將會清空您目前的設計,確定要繼續嗎?")) return;
 
623
  }
624
 
625
  currentGrid.value = conf;
 
635
  viewMode.value = 'overview';
636
  };
637
 
638
+ // Custom Grid Logic
639
+ const openCustomGridModal = () => {
640
+ const hasContent = pages.value.some(p => p.cells.some(c => c.content !== ''));
641
+ if (hasContent) {
642
+ if(!confirm("設定自訂網格將會清空您目前的設計,確定要繼續嗎?")) return;
643
+ }
644
+
645
+ // Set initial values from current grid
646
+ customGridConfig.value.rows = currentGrid.value.rows;
647
+ customGridConfig.value.cols = currentGrid.value.cols;
648
+ showGridModal.value = true;
649
+ };
650
+
651
+ const confirmCustomGrid = () => {
652
+ const r = Math.max(1, Math.min(20, parseInt(customGridConfig.value.rows) || 4));
653
+ const c = Math.max(1, Math.min(20, parseInt(customGridConfig.value.cols) || 4));
654
+
655
+ const customConf = {
656
+ label: `${r}x${c}`,
657
+ rows: r,
658
+ cols: c
659
+ };
660
+
661
+ currentGrid.value = customConf;
662
+ const totalCells = r * c;
663
+
664
+ pages.value = [
665
+ { id: 1, cells: createPageCells(0, r, c) },
666
+ { id: 2, cells: createPageCells(totalCells, r, c) }
667
+ ];
668
+
669
+ selectedCellIndex.value = null;
670
+ activePageId.value = 1;
671
+ viewMode.value = 'overview';
672
+ showGridModal.value = false;
673
+ };
674
+
675
  const clearAllContent = () => {
676
  const hasContent = pages.value.some(p => p.cells.some(c => c.content !== ''));
677
  if (!hasContent) {
 
1150
  cancelCrop,
1151
  confirmCrop,
1152
  applyCustomImageToCell,
1153
+ removeCustomImage,
1154
+ // Custom Grid
1155
+ showGridModal,
1156
+ customGridConfig,
1157
+ openCustomGridModal,
1158
+ confirmCustomGrid,
1159
+ isCustomGridActive
1160
  };
1161
  }
1162
  }).mount('#app');