protae5544 commited on
Commit
7f36aec
·
verified ·
1 Parent(s): a9a1599

ปรับตำแหน้งฟิลด์ไม่ได้

Browse files
Files changed (1) hide show
  1. script.js +57 -37
script.js CHANGED
@@ -100,13 +100,14 @@ function setupGlobalListeners() {
100
  document.getElementById('zoom-in').addEventListener('click', zoomIn);
101
  document.getElementById('zoom-out').addEventListener('click', zoomOut);
102
  document.getElementById('current-pg').addEventListener('change', (e) => goToPage(e.target.value));
103
-
104
  // Property Controls
105
  ['prop-x', 'prop-y', 'prop-size', 'prop-weight', 'prop-color'].forEach(id => {
106
- document.getElementById(id)?.addEventListener('input', updateFieldFromInputs);
 
 
 
107
  });
108
-
109
- // Modals
110
  document.querySelectorAll('.close-modal, #btn-qr-cancel').forEach(btn => {
111
  btn.addEventListener('click', (e) => {
112
  const modal = e.target.closest('.fixed.z-\\[200\\]'); // Select modal wrapper
@@ -265,7 +266,6 @@ function switchTab(tab) {
265
  state.scale = 1;
266
  updateZoomDisplay();
267
  }
268
-
269
  // --- Design Mode & Drag & Drop ---
270
  function toggleDesignMode() {
271
  state.designMode = !state.designMode;
@@ -303,6 +303,7 @@ function updateFieldPositionsFromState() {
303
  });
304
  }
305
  }
 
306
  function selectField(id) {
307
  if (!state.designMode) return;
308
  deselectField();
@@ -318,8 +319,8 @@ function selectField(id) {
318
  if (controls) controls.style.display = 'block';
319
 
320
  document.getElementById('prop-id').textContent = id;
321
- document.getElementById('prop-x').value = parseFloat(el.style.left);
322
- document.getElementById('prop-y').value = parseFloat(el.style.top);
323
 
324
  if (el.tagName === 'IMG') {
325
  document.getElementById('prop-size').parentElement.style.display = 'none';
@@ -332,7 +333,7 @@ function selectField(id) {
332
 
333
  document.getElementById('prop-size').value = parseFloat(el.style.fontSize) || 14;
334
  document.getElementById('prop-weight').value = el.style.fontWeight || 'normal';
335
- document.getElementById('prop-color').value = rgbToHex(el.style.color);
336
  }
337
  }
338
  }
@@ -343,35 +344,45 @@ function deselectField() {
343
  if (el) el.classList.remove('selected');
344
  }
345
  state.selectedFieldId = null;
346
- document.getElementById('no-field-selected').style.display = 'block';
347
- document.getElementById('field-controls').style.display = 'none';
 
 
348
  }
349
 
350
  function updateFieldFromInputs() {
351
  if (!state.selectedFieldId) return;
352
  const el = document.getElementById(state.selectedFieldId);
 
 
353
  const x = parseFloat(document.getElementById('prop-x').value) || 0;
354
  const y = parseFloat(document.getElementById('prop-y').value) || 0;
355
 
356
  el.style.left = x + 'px';
357
  el.style.top = y + 'px';
358
 
359
- state.fieldConfig[state.selectedFieldId] = { ...state.fieldConfig[state.selectedFieldId], top: y+'px', left: x+'px' };
 
 
 
 
 
 
360
 
361
  if (el.tagName !== 'IMG') {
362
- const size = document.getElementById('prop-size').value;
363
- const color = document.getElementById('prop-color').value;
364
- const weight = document.getElementById('prop-weight').value;
365
 
366
  el.style.fontSize = size + 'px';
367
  el.style.color = color;
368
  el.style.fontWeight = weight;
369
 
370
- state.fieldConfig[state.selectedFieldId] = {
371
- ...state.fieldConfig[state.selectedFieldId],
372
- fontSize: size+'px', color, fontWeight: weight
373
- };
374
  }
 
375
  saveFieldConfig();
376
  }
377
 
@@ -397,14 +408,16 @@ function onMouseMove(e) {
397
  const parent = dragInfo.el.parentElement;
398
  const pRect = parent.getBoundingClientRect();
399
 
400
- // Calculate new position relative to parent, compensating for zoom if any (assuming page transform origin top center)
401
- // Since .page has transform, we need to adjust coordinates or use unscaled logic
402
- // Simplified: Assuming 1:1 for now, or accounting for page scale
403
  let scale = state.scale;
404
 
405
  let newLeft = (e.clientX - pRect.left - dragInfo.offsetX) / scale;
406
  let newTop = (e.clientY - pRect.top - dragInfo.offsetY) / scale;
407
 
 
 
 
 
408
  dragInfo.el.style.left = newLeft + 'px';
409
  dragInfo.el.style.top = newTop + 'px';
410
 
@@ -418,17 +431,16 @@ function onMouseMove(e) {
418
  function onMouseUp() {
419
  if (dragInfo.active && dragInfo.el) {
420
  // Save config on drop
421
- state.fieldConfig[dragInfo.el.id] = {
422
- ...state.fieldConfig[dragInfo.el.id],
423
- left: dragInfo.el.style.left,
424
- top: dragInfo.el.style.top
425
- };
426
  saveFieldConfig();
427
  }
428
  dragInfo.active = false;
429
  dragInfo.el = null;
430
  }
431
-
432
  // --- Layout Config ---
433
  function saveFieldConfig() {
434
  localStorage.setItem('pdf_field_config', JSON.stringify(state.fieldConfig));
@@ -438,14 +450,18 @@ function saveFieldConfig() {
438
  function loadFieldConfig() {
439
  const saved = localStorage.getItem('pdf_field_config');
440
  if (saved) {
441
- state.fieldConfig = JSON.parse(saved);
442
- Object.keys(state.fieldConfig).forEach(id => {
443
- const el = document.getElementById(id);
444
- const cfg = state.fieldConfig[id];
445
- if (el && cfg) {
446
- Object.assign(el.style, cfg);
447
- }
448
- });
 
 
 
 
449
  }
450
  loadLayoutFromStorage();
451
  }
@@ -495,6 +511,7 @@ function saveLayoutToStorage() {
495
  });
496
 
497
  state.currentLayoutConfig = layoutData;
 
498
  return layoutData;
499
  }
500
 
@@ -502,8 +519,9 @@ function loadLayoutFromStorage() {
502
  const saved = localStorage.getItem('pdf_layout_config');
503
  if (saved) {
504
  try {
505
- state.currentLayoutConfig = JSON.parse(saved);
506
- applyLayoutConfig(state.currentLayoutConfig);
 
507
  state.isLayoutLoaded = true;
508
  } catch (e) {
509
  console.warn('Failed to load layout config:', e);
@@ -512,6 +530,8 @@ function loadLayoutFromStorage() {
512
  }
513
 
514
  function applyLayoutConfig(config) {
 
 
515
  // Apply field configurations
516
  Object.keys(config.fields).forEach(fieldId => {
517
  const fieldConfig = config.fields[fieldId];
 
100
  document.getElementById('zoom-in').addEventListener('click', zoomIn);
101
  document.getElementById('zoom-out').addEventListener('click', zoomOut);
102
  document.getElementById('current-pg').addEventListener('change', (e) => goToPage(e.target.value));
 
103
  // Property Controls
104
  ['prop-x', 'prop-y', 'prop-size', 'prop-weight', 'prop-color'].forEach(id => {
105
+ const el = document.getElementById(id);
106
+ if (el) {
107
+ el.addEventListener('input', updateFieldFromInputs);
108
+ }
109
  });
110
+ // Modals
 
111
  document.querySelectorAll('.close-modal, #btn-qr-cancel').forEach(btn => {
112
  btn.addEventListener('click', (e) => {
113
  const modal = e.target.closest('.fixed.z-\\[200\\]'); // Select modal wrapper
 
266
  state.scale = 1;
267
  updateZoomDisplay();
268
  }
 
269
  // --- Design Mode & Drag & Drop ---
270
  function toggleDesignMode() {
271
  state.designMode = !state.designMode;
 
303
  });
304
  }
305
  }
306
+
307
  function selectField(id) {
308
  if (!state.designMode) return;
309
  deselectField();
 
319
  if (controls) controls.style.display = 'block';
320
 
321
  document.getElementById('prop-id').textContent = id;
322
+ document.getElementById('prop-x').value = parseFloat(el.style.left) || 0;
323
+ document.getElementById('prop-y').value = parseFloat(el.style.top) || 0;
324
 
325
  if (el.tagName === 'IMG') {
326
  document.getElementById('prop-size').parentElement.style.display = 'none';
 
333
 
334
  document.getElementById('prop-size').value = parseFloat(el.style.fontSize) || 14;
335
  document.getElementById('prop-weight').value = el.style.fontWeight || 'normal';
336
+ document.getElementById('prop-color').value = rgbToHex(el.style.color) || '#000000';
337
  }
338
  }
339
  }
 
344
  if (el) el.classList.remove('selected');
345
  }
346
  state.selectedFieldId = null;
347
+ const noSel = document.getElementById('no-field-selected');
348
+ const controls = document.getElementById('field-controls');
349
+ if (noSel) noSel.style.display = 'block';
350
+ if (controls) controls.style.display = 'none';
351
  }
352
 
353
  function updateFieldFromInputs() {
354
  if (!state.selectedFieldId) return;
355
  const el = document.getElementById(state.selectedFieldId);
356
+ if (!el) return;
357
+
358
  const x = parseFloat(document.getElementById('prop-x').value) || 0;
359
  const y = parseFloat(document.getElementById('prop-y').value) || 0;
360
 
361
  el.style.left = x + 'px';
362
  el.style.top = y + 'px';
363
 
364
+ // Update state.fieldConfig
365
+ if (!state.fieldConfig[state.selectedFieldId]) {
366
+ state.fieldConfig[state.selectedFieldId] = {};
367
+ }
368
+
369
+ state.fieldConfig[state.selectedFieldId].top = y + 'px';
370
+ state.fieldConfig[state.selectedFieldId].left = x + 'px';
371
 
372
  if (el.tagName !== 'IMG') {
373
+ const size = document.getElementById('prop-size').value || '14';
374
+ const color = document.getElementById('prop-color').value || '#000000';
375
+ const weight = document.getElementById('prop-weight').value || 'normal';
376
 
377
  el.style.fontSize = size + 'px';
378
  el.style.color = color;
379
  el.style.fontWeight = weight;
380
 
381
+ state.fieldConfig[state.selectedFieldId].fontSize = size + 'px';
382
+ state.fieldConfig[state.selectedFieldId].color = color;
383
+ state.fieldConfig[state.selectedFieldId].fontWeight = weight;
 
384
  }
385
+
386
  saveFieldConfig();
387
  }
388
 
 
408
  const parent = dragInfo.el.parentElement;
409
  const pRect = parent.getBoundingClientRect();
410
 
411
+ // Calculate new position relative to parent, compensating for zoom
 
 
412
  let scale = state.scale;
413
 
414
  let newLeft = (e.clientX - pRect.left - dragInfo.offsetX) / scale;
415
  let newTop = (e.clientY - pRect.top - dragInfo.offsetY) / scale;
416
 
417
+ // Ensure non-negative positions
418
+ newLeft = Math.max(0, newLeft);
419
+ newTop = Math.max(0, newTop);
420
+
421
  dragInfo.el.style.left = newLeft + 'px';
422
  dragInfo.el.style.top = newTop + 'px';
423
 
 
431
  function onMouseUp() {
432
  if (dragInfo.active && dragInfo.el) {
433
  // Save config on drop
434
+ if (!state.fieldConfig[dragInfo.el.id]) {
435
+ state.fieldConfig[dragInfo.el.id] = {};
436
+ }
437
+ state.fieldConfig[dragInfo.el.id].left = dragInfo.el.style.left;
438
+ state.fieldConfig[dragInfo.el.id].top = dragInfo.el.style.top;
439
  saveFieldConfig();
440
  }
441
  dragInfo.active = false;
442
  dragInfo.el = null;
443
  }
 
444
  // --- Layout Config ---
445
  function saveFieldConfig() {
446
  localStorage.setItem('pdf_field_config', JSON.stringify(state.fieldConfig));
 
450
  function loadFieldConfig() {
451
  const saved = localStorage.getItem('pdf_field_config');
452
  if (saved) {
453
+ try {
454
+ state.fieldConfig = JSON.parse(saved);
455
+ Object.keys(state.fieldConfig).forEach(id => {
456
+ const el = document.getElementById(id);
457
+ const cfg = state.fieldConfig[id];
458
+ if (el && cfg) {
459
+ Object.assign(el.style, cfg);
460
+ }
461
+ });
462
+ } catch (e) {
463
+ console.warn('Failed to load field config:', e);
464
+ }
465
  }
466
  loadLayoutFromStorage();
467
  }
 
511
  });
512
 
513
  state.currentLayoutConfig = layoutData;
514
+ localStorage.setItem('pdf_layout_config', JSON.stringify(layoutData));
515
  return layoutData;
516
  }
517
 
 
519
  const saved = localStorage.getItem('pdf_layout_config');
520
  if (saved) {
521
  try {
522
+ const parsed = JSON.parse(saved);
523
+ state.currentLayoutConfig = parsed;
524
+ applyLayoutConfig(parsed);
525
  state.isLayoutLoaded = true;
526
  } catch (e) {
527
  console.warn('Failed to load layout config:', e);
 
530
  }
531
 
532
  function applyLayoutConfig(config) {
533
+ if (!config || !config.fields) return;
534
+
535
  // Apply field configurations
536
  Object.keys(config.fields).forEach(fieldId => {
537
  const fieldConfig = config.fields[fieldId];