rails-mermaid_erd 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 27a3b346f33bfc899475fc0c00f6c512bf8ba1e1e028c3518c24496e5eb3e016
4
- data.tar.gz: d0317f33acd321ed8b9a3b2bc5bb818b02593bba6c002925973f629fbfc110c7
3
+ metadata.gz: 7f3cfe23f8fa1343b2bd8a3ac5d47c1967613ce7a832d65de858b363402db0b1
4
+ data.tar.gz: 146d83e00452b8c56cbf8c4c6e0aebd62f99b3224e6b7e3062b4889b55bf0723
5
5
  SHA512:
6
- metadata.gz: '09d7df6654042f5a327a18cf9ddfb7f4c43bb41717ff3ed937cb5dc95aed8d502d983000c2b31970370e2532fba62acda6506d9ff5dd0c073ae1f1db1fc7705c'
7
- data.tar.gz: 020f4ba3e58cfbbe8cd77a28414138073ba248eccfdef2ec3a55cf19a068ffa8913f1dc526bc2c5b7a23e35faca7265db4bbce34dee86d4f2e3f78feff737129
6
+ metadata.gz: 2c68987537096806829a9709f477dd8cc8a0108291387ff670796d2c41c4a900fe0f1a55902381b12d582d4e66d77f2b0421d929dfc72060a10d5b9ed020c4a6
7
+ data.tar.gz: 04cbecd36399c810f0846e1d4c4275922acfeb1ec2bcf426440f08902db6b4b051368f57ec57a0f8259108d9f727b77d0760ee0f817aee8122e4f3952dcfcc58
@@ -1,3 +1,3 @@
1
1
  module RailsMermaidErd
2
- VERSION = "0.5.1"
2
+ VERSION = "0.6.0"
3
3
  end
@@ -230,7 +230,20 @@
230
230
  </div>
231
231
  <div v-show="tab === 'erd'" class="px-4 w-full min-h-[calc(100vh-56px-32px-56px)] relative overflow-hidden">
232
232
  <div class="absolute inset-0" :style="zoomStyle" ref="zoomArea">
233
- <div id="preview"></div>
233
+ <div id="preview" :class="{ 'cursor-grab': isSpacePressed, 'cursor-grabbing': isDragging }"></div>
234
+ </div>
235
+
236
+ <div class="absolute bottom-0 left-1/2 -translate-x-1/2 p-4">
237
+ <div class="bg-gray-800 text-white text-[10px] px-3 py-1.5 rounded inline-flex items-center space-x-6">
238
+ <div class="inline-flex items-center">
239
+ <span class="font-medium">{{i18n[language]["controls"]["movement"]}}:</span>
240
+ <span class="ml-1 text-white/60">{{i18n[language]["controls"]["space_drag"]}} / {{i18n[language]["controls"]["middle_drag"]}}</span>
241
+ </div>
242
+ <div class="inline-flex items-center">
243
+ <span class="font-medium">{{i18n[language]["controls"]["zoom"]}}:</span>
244
+ <span class="ml-1 text-white/60">{{i18n[language]["controls"]["mouse_wheel"]}} / {{i18n[language]["controls"]["pinch"]}}</span>
245
+ </div>
246
+ </div>
234
247
  </div>
235
248
 
236
249
  <div class="absolute bottom-0 right-0 p-4 space-x-4 flex">
@@ -247,7 +260,6 @@
247
260
  <button class="text-xs py-1 px-2 rounded hover:bg-white focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-gray-900 bg-gray-400 text-gray-900" @click="moveRight">→</button>
248
261
  </div>
249
262
  </div>
250
-
251
263
  </div>
252
264
  <textarea v-show="tab === 'code'" class="px-4 bg-gray-900 text-gray-300 font-mono w-full text-xs min-h-[calc(100vh-56px-32px-56px)] border-0 focus:ring-0" readonly v-model="mermaidErd"></textarea>
253
265
  </div>
@@ -302,6 +314,14 @@
302
314
  erd: 'ERD',
303
315
  code: 'Code',
304
316
  },
317
+ controls: {
318
+ movement: 'Movement',
319
+ zoom: 'Zoom',
320
+ space_drag: 'Space + Mouse Drag',
321
+ middle_drag: 'Middle Click + Drag',
322
+ mouse_wheel: 'Mouse Wheel',
323
+ pinch: 'Pinch In/Out',
324
+ }
305
325
  },
306
326
  ja: {
307
327
  actions: {
@@ -336,6 +356,14 @@
336
356
  erd: 'ER図',
337
357
  code: 'コード',
338
358
  },
359
+ controls: {
360
+ movement: '移動方法',
361
+ zoom: '拡大/縮小',
362
+ space_drag: 'スペースキー + マウスドラッグ',
363
+ middle_drag: '中クリック + ドラッグ',
364
+ mouse_wheel: 'マウスホイール',
365
+ pinch: 'ピンチイン/アウト',
366
+ }
339
367
  }
340
368
  }
341
369
  </script>
@@ -362,6 +390,155 @@
362
390
  const posX = Vue.ref(0)
363
391
  const posY = Vue.ref(0)
364
392
  const zoomArea = Vue.ref(null)
393
+ // Manage space key press state
394
+ const isSpacePressed = Vue.ref(false)
395
+ // Manage dragging state
396
+ const isDragging = Vue.ref(false)
397
+ let startX = 0
398
+ let startY = 0
399
+ // Record distance between two touch points
400
+ let lastTouchDistance = 0
401
+ // Record mouse position
402
+ let lastMouseX = 0
403
+ let lastMouseY = 0
404
+
405
+ // Calculate distance between two touch points
406
+ const getDistance = (touches) => {
407
+ return Math.hypot(
408
+ touches[0].clientX - touches[1].clientX,
409
+ touches[0].clientY - touches[1].clientY
410
+ )
411
+ }
412
+
413
+ // Calculate center point of two touch positions
414
+ const getTouchCenter = (touches) => {
415
+ return {
416
+ x: (touches[0].clientX + touches[1].clientX) / 2,
417
+ y: (touches[0].clientY + touches[1].clientY) / 2
418
+ }
419
+ }
420
+
421
+ // Handle touch start
422
+ const handleTouchStart = (e) => {
423
+ if (e.touches.length === 2) {
424
+ e.preventDefault()
425
+ lastTouchDistance = getDistance(e.touches)
426
+ }
427
+ }
428
+
429
+ // Handle touch move (pinch in/out for zoom)
430
+ const handleTouchMove = (e) => {
431
+ if (e.touches.length === 2) {
432
+ e.preventDefault()
433
+ const preview = document.getElementById('preview')
434
+ if (!preview.contains(e.target)) {
435
+ return
436
+ }
437
+
438
+ const newDistance = getDistance(e.touches)
439
+ const delta = (newDistance - lastTouchDistance) * 0.01
440
+ lastTouchDistance = newDistance
441
+
442
+ const center = getTouchCenter(e.touches)
443
+ const rect = preview.getBoundingClientRect()
444
+ const touchX = center.x - rect.left
445
+ const touchY = center.y - rect.top
446
+
447
+ const x = touchX / scale.value - posX.value
448
+ const y = touchY / scale.value - posY.value
449
+
450
+ const newScale = Math.min(Math.max(scale.value + delta, 0.5), 3)
451
+ if (newScale === scale.value) return
452
+
453
+ posX.value = touchX / newScale - x
454
+ posY.value = touchY / newScale - y
455
+ scale.value = newScale
456
+ }
457
+ }
458
+
459
+ // Handle touch end
460
+ const handleTouchEnd = (e) => {
461
+ if (e.touches.length < 2) {
462
+ lastTouchDistance = 0
463
+ }
464
+ }
465
+
466
+ // Handle key down (space key for drag mode toggle)
467
+ const handleKeyDown = (e) => {
468
+ if (e.code === 'Space' && !isSpacePressed.value) {
469
+ if (document.activeElement.tagName === 'INPUT' || document.activeElement.tagName === 'TEXTAREA') {
470
+ return
471
+ }
472
+ isSpacePressed.value = true
473
+ e.preventDefault()
474
+ }
475
+ }
476
+
477
+ // Handle key up
478
+ const handleKeyUp = (e) => {
479
+ if (e.code === 'Space') {
480
+ isSpacePressed.value = false
481
+ isDragging.value = false
482
+ }
483
+ }
484
+
485
+ // Handle mouse down (start dragging)
486
+ const handleMouseDown = (e) => {
487
+ if (isSpacePressed.value || e.button === 1) {
488
+ isDragging.value = true
489
+ lastMouseX = e.clientX
490
+ lastMouseY = e.clientY
491
+ e.preventDefault()
492
+ }
493
+ }
494
+
495
+ // Handle mouse move (movement while dragging)
496
+ const handleMouseMove = (e) => {
497
+ if (isDragging.value) {
498
+ const dx = (e.clientX - lastMouseX) / scale.value
499
+ const dy = (e.clientY - lastMouseY) / scale.value
500
+ posX.value += dx
501
+ posY.value += dy
502
+ lastMouseX = e.clientX
503
+ lastMouseY = e.clientY
504
+ e.preventDefault()
505
+ }
506
+ }
507
+
508
+ // Handle mouse up (end dragging)
509
+ const handleMouseUp = (e) => {
510
+ if (e.button === 1) {
511
+ e.preventDefault()
512
+ }
513
+ isDragging.value = false
514
+ }
515
+
516
+ // Handle mouse wheel (zoom)
517
+ const handleWheel = (e) => {
518
+ const preview = document.getElementById('preview')
519
+ if (!preview.contains(e.target)) {
520
+ return
521
+ }
522
+
523
+ e.preventDefault()
524
+
525
+ const rect = preview.getBoundingClientRect()
526
+ const mouseX = e.clientX - rect.left
527
+ const mouseY = e.clientY - rect.top
528
+
529
+ // Calculate relative coordinates based on mouse position
530
+ const x = mouseX / scale.value - posX.value
531
+ const y = mouseY / scale.value - posY.value
532
+
533
+ // Change scale
534
+ const delta = e.deltaY < 0 ? 0.1 : -0.1
535
+ const newScale = Math.min(Math.max(scale.value + delta, 0.5), 3)
536
+
537
+ // Calculate new position with new scale
538
+ posX.value = mouseX / newScale - x
539
+ posY.value = mouseY / newScale - y
540
+ scale.value = newScale
541
+ }
365
542
 
366
543
  const zoomStyle = Vue.computed(() => {
367
544
  return {
@@ -613,6 +790,28 @@
613
790
  setLanguage(window.navigator.language)
614
791
  restoreFromHash()
615
792
  reRender()
793
+
794
+ window.addEventListener('keydown', handleKeyDown)
795
+ window.addEventListener('keyup', handleKeyUp)
796
+ window.addEventListener('mousedown', handleMouseDown)
797
+ window.addEventListener('mousemove', handleMouseMove)
798
+ window.addEventListener('mouseup', handleMouseUp)
799
+ window.addEventListener('wheel', handleWheel, { passive: false })
800
+ window.addEventListener('touchstart', handleTouchStart, { passive: false })
801
+ window.addEventListener('touchmove', handleTouchMove, { passive: false })
802
+ window.addEventListener('touchend', handleTouchEnd)
803
+ })
804
+
805
+ Vue.onUnmounted(() => {
806
+ window.removeEventListener('keydown', handleKeyDown)
807
+ window.removeEventListener('keyup', handleKeyUp)
808
+ window.removeEventListener('mousedown', handleMouseDown)
809
+ window.removeEventListener('mousemove', handleMouseMove)
810
+ window.removeEventListener('mouseup', handleMouseUp)
811
+ window.removeEventListener('wheel', handleWheel)
812
+ window.removeEventListener('touchstart', handleTouchStart)
813
+ window.removeEventListener('touchmove', handleTouchMove)
814
+ window.removeEventListener('touchend', handleTouchEnd)
616
815
  })
617
816
 
618
817
  window.addEventListener('hashchange', () => {
@@ -656,7 +855,9 @@
656
855
  moveUp,
657
856
  moveDown,
658
857
  moveLeft,
659
- moveRight
858
+ moveRight,
859
+ isSpacePressed,
860
+ isDragging
660
861
  }
661
862
  }
662
863
  }
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-mermaid_erd
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - 肥溜め
8
8
  - "\U0001F4A9"
9
- autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2024-11-24 00:00:00.000000000 Z
11
+ date: 2024-12-28 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: rails
@@ -95,7 +94,6 @@ dependencies:
95
94
  - - ">="
96
95
  - !ruby/object:Gem::Version
97
96
  version: '0'
98
- description:
99
97
  email: []
100
98
  executables: []
101
99
  extensions: []
@@ -116,7 +114,6 @@ licenses:
116
114
  metadata:
117
115
  homepage_uri: https://github.com/koedame/rails-mermaid_erd
118
116
  source_code_uri: https://github.com/koedame/rails-mermaid_erd
119
- post_install_message:
120
117
  rdoc_options: []
121
118
  require_paths:
122
119
  - lib
@@ -131,8 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
131
128
  - !ruby/object:Gem::Version
132
129
  version: '0'
133
130
  requirements: []
134
- rubygems_version: 3.5.22
135
- signing_key:
131
+ rubygems_version: 3.6.2
136
132
  specification_version: 4
137
133
  summary: Generate Mermaid ERD for Ruby on Rails
138
134
  test_files: []