Skip to content

Commit 6522940

Browse files
refactor: replace zoom slider with +/- buttons in QuickButton components
1 parent fd14070 commit 6522940

File tree

4 files changed

+24
-194
lines changed

4 files changed

+24
-194
lines changed

src/components/Navbar/QuickButton/QuickButton.vue

Lines changed: 4 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -70,89 +70,17 @@
7070
<i style="color: #ddd" class="fas fa-expand-arrows-alt"></i>
7171
</button>
7272
</div>
73-
<!-- Zoom slider: 1-100% mapped to internal zoom scale via setZoomFromSlider API -->
73+
<!-- Zoom controls: +/- buttons -->
7474
<div class="zoom-controls">
75-
<button class="zoom-button-decrement" @click="decrementZoom" title="Zoom Out">−</button>
76-
<input
77-
type="range"
78-
v-model.number="displayZoomPercent"
79-
@input="onZoomSliderInput"
80-
min="1"
81-
max="100"
82-
step="1"
83-
class="zoom-slider"
84-
title="Zoom Level"
85-
/>
86-
<button class="zoom-button-increment" @click="incrementZoom" title="Zoom In">+</button>
87-
<span class="zoom-label">{{ displayZoomPercent }}%</span>
75+
<button class="zoom-button-decrement" @click="decrement" title="Zoom Out">−</button>
76+
<button class="zoom-button-increment" @click="increment" title="Zoom In">+</button>
8877
</div>
8978
</div>
9079
<div id="exitView"></div>
9180
</template>
9281

9382
<script lang="ts" setup>
94-
import { ref, onMounted } from 'vue'
95-
import { saveOnline, saveOffline, deleteSelectedItem, createSaveAsImgPrompt, zoomToFit, undoit, redoit, view } from './QuickButton'
96-
// @ts-ignore - simulator functions are not typed
97-
import { setZoomFromSlider, getZoomSliderValue } from '../../../simulator/src/listeners'
98-
99-
const DISPLAY_ZOOM_MIN = 1
100-
const DISPLAY_ZOOM_MAX = 100
101-
const DISPLAY_ZOOM_DEFAULT = 50
102-
const DISPLAY_ZOOM_STEP = 5
103-
104-
const INTERNAL_ZOOM_MIN = 0
105-
const INTERNAL_ZOOM_MAX = 200
106-
107-
const displayZoomPercent = ref(100)
108-
109-
const clampZoomPercent = (value: number): number => {
110-
return Math.max(DISPLAY_ZOOM_MIN, Math.min(DISPLAY_ZOOM_MAX, value))
111-
}
112-
113-
const convertInternalToDisplayZoom = (internalValue: number): number => {
114-
return Math.round((internalValue / INTERNAL_ZOOM_MAX) * 100)
115-
}
116-
117-
const convertDisplayToInternalZoom = (displayPercent: number): number => {
118-
return (displayPercent / 100) * INTERNAL_ZOOM_MAX
119-
}
120-
121-
const initializeZoomSlider = () => {
122-
try {
123-
const currentInternalZoom = getZoomSliderValue(INTERNAL_ZOOM_MIN, INTERNAL_ZOOM_MAX)
124-
const currentDisplayZoom = convertInternalToDisplayZoom(currentInternalZoom)
125-
displayZoomPercent.value = clampZoomPercent(currentDisplayZoom)
126-
} catch (error) {
127-
console.warn('Could not initialize zoom slider:', error)
128-
displayZoomPercent.value = DISPLAY_ZOOM_DEFAULT
129-
}
130-
}
131-
132-
const updateSimulatorZoom = () => {
133-
try {
134-
const internalZoomValue = convertDisplayToInternalZoom(displayZoomPercent.value)
135-
setZoomFromSlider(internalZoomValue, INTERNAL_ZOOM_MIN, INTERNAL_ZOOM_MAX)
136-
} catch (error) {
137-
console.warn('Could not apply zoom:', error)
138-
}
139-
}
140-
141-
const incrementZoom = () => {
142-
displayZoomPercent.value = clampZoomPercent(displayZoomPercent.value + DISPLAY_ZOOM_STEP)
143-
updateSimulatorZoom()
144-
}
145-
146-
const decrementZoom = () => {
147-
displayZoomPercent.value = clampZoomPercent(displayZoomPercent.value - DISPLAY_ZOOM_STEP)
148-
updateSimulatorZoom()
149-
}
150-
151-
const onZoomSliderInput = () => {
152-
updateSimulatorZoom()
153-
}
154-
155-
onMounted(initializeZoomSlider)
83+
import { saveOnline, saveOffline, deleteSelectedItem, createSaveAsImgPrompt, zoomToFit, undoit, redoit, view, increment, decrement } from './QuickButton'
15684
15785
function dragover(): void {
15886
const quickBtn: HTMLElement | null = document.querySelector('.quick-btn')
@@ -340,11 +268,6 @@ function dragover(): void {
340268
text-align: right;
341269
}
342270
343-
.zoom-button-decrement:hover,
344-
.zoom-button-increment:hover {
345-
opacity: 0.7;
346-
}
347-
348271
@media (max-width: 991px) {
349272
.quick-btn-save-online {
350273
background: url(../../../styles/css/assets/shorcuts/save-online.svg) center/cover;

src/components/Navbar/QuickButton/QuickButtonMobile.vue

Lines changed: 4 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -80,123 +80,24 @@
8080
<Hamburger2 v-if="simulatorMobileStore.showMobileView" :navbar-data="navbarData" />
8181
</nav>
8282
</div>
83-
<!-- Zoom slider: 1-100% mapped to internal zoom scale via setZoomFromSlider API -->
83+
<!-- Zoom controls: +/- buttons -->
8484
<div class="slider-container">
8585
<div class="zoom-controls">
86-
<button class="zoom-button-decrement" @click="decrementZoom" title="Zoom Out">−</button>
87-
<input
88-
type="range"
89-
v-model.number="displayZoomPercent"
90-
@input="onZoomSliderInput"
91-
min="1"
92-
max="100"
93-
step="1"
94-
class="zoom-slider"
95-
title="Zoom Level"
96-
/>
97-
<button class="zoom-button-increment" @click="incrementZoom" title="Zoom In">+</button>
98-
<span class="zoom-label">{{ displayZoomPercent }}%</span>
86+
<button class="zoom-button-decrement" @click="decrement" title="Zoom Out">−</button>
87+
<button class="zoom-button-increment" @click="increment" title="Zoom In">+</button>
9988
</div>
10089
</div>
10190
</div>
10291
<div id="exitView"></div>
10392
</template>
10493

10594
<script lang="ts" setup>
106-
import { ref, onMounted } from 'vue'
10795
import Hamburger2 from '../Hamburger/Hamburger2.vue'
10896
import navbarData from '../../../assets/constants/Navbar/NAVBAR_DATA.json'
10997
import { useSimulatorMobileStore } from '../../../store/simulatorMobileStore'
110-
import { saveOnline, saveOffline, deleteSelectedItem, createSaveAsImgPrompt, zoomToFit, undoit, redoit, view } from './QuickButton'
111-
// @ts-ignore - simulator functions are not typed
112-
import { setZoomFromSlider, getZoomSliderValue } from '../../../simulator/src/listeners'
98+
import { saveOnline, saveOffline, deleteSelectedItem, createSaveAsImgPrompt, zoomToFit, undoit, redoit, view, increment, decrement } from './QuickButton'
11399
114100
const simulatorMobileStore = useSimulatorMobileStore()
115-
116-
// Display zoom constants (user-facing percentage values)
117-
const DISPLAY_ZOOM_MIN = 1
118-
const DISPLAY_ZOOM_MAX = 100
119-
const DISPLAY_ZOOM_DEFAULT = 50
120-
const DISPLAY_ZOOM_STEP = 5
121-
122-
// Internal zoom constants (simulator scale range)
123-
const INTERNAL_ZOOM_MIN = 0
124-
const INTERNAL_ZOOM_MAX = 200
125-
126-
// Current zoom level displayed to user (1-100%)
127-
const displayZoomPercent = ref(DISPLAY_ZOOM_DEFAULT)
128-
129-
/**
130-
* Clamp zoom percentage to valid display range
131-
*/
132-
const clampZoomPercent = (value: number): number => {
133-
return Math.max(DISPLAY_ZOOM_MIN, Math.min(DISPLAY_ZOOM_MAX, value))
134-
}
135-
136-
/**
137-
* Convert internal zoom value (0-200) to display percentage (1-100%)
138-
*/
139-
const convertInternalToDisplayZoom = (internalValue: number): number => {
140-
return Math.round((internalValue / INTERNAL_ZOOM_MAX) * 100)
141-
}
142-
143-
/**
144-
* Convert display percentage (1-100%) to internal zoom value (0-200)
145-
*/
146-
const convertDisplayToInternalZoom = (displayPercent: number): number => {
147-
return (displayPercent / 100) * INTERNAL_ZOOM_MAX
148-
}
149-
150-
/**
151-
* Initialize zoom slider with current simulator zoom level
152-
*/
153-
const initializeZoomSlider = () => {
154-
try {
155-
const currentInternalZoom = getZoomSliderValue(INTERNAL_ZOOM_MIN, INTERNAL_ZOOM_MAX)
156-
const currentDisplayZoom = convertInternalToDisplayZoom(currentInternalZoom)
157-
displayZoomPercent.value = clampZoomPercent(currentDisplayZoom)
158-
} catch (error) {
159-
console.warn('Could not initialize zoom slider:', error)
160-
displayZoomPercent.value = DISPLAY_ZOOM_DEFAULT
161-
}
162-
}
163-
164-
/**
165-
* Update simulator zoom based on current display percentage
166-
*/
167-
const updateSimulatorZoom = () => {
168-
try {
169-
const internalZoomValue = convertDisplayToInternalZoom(displayZoomPercent.value)
170-
setZoomFromSlider(internalZoomValue, INTERNAL_ZOOM_MIN, INTERNAL_ZOOM_MAX)
171-
} catch (error) {
172-
console.warn('Could not apply zoom:', error)
173-
}
174-
}
175-
176-
/**
177-
* Increase zoom level by one step
178-
*/
179-
const incrementZoom = () => {
180-
displayZoomPercent.value = clampZoomPercent(displayZoomPercent.value + DISPLAY_ZOOM_STEP)
181-
updateSimulatorZoom()
182-
}
183-
184-
/**
185-
* Decrease zoom level by one step
186-
*/
187-
const decrementZoom = () => {
188-
displayZoomPercent.value = clampZoomPercent(displayZoomPercent.value - DISPLAY_ZOOM_STEP)
189-
updateSimulatorZoom()
190-
}
191-
192-
/**
193-
* Handle slider input event - updates zoom in real-time as user drags
194-
*/
195-
const onZoomSliderInput = () => {
196-
updateSimulatorZoom()
197-
}
198-
199-
onMounted(initializeZoomSlider)
200101
</script>
201102

202103
<style scoped>

src/simulator/src/embedListeners.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,13 +178,15 @@ export default function startListeners() {
178178
if (e.key == 'Meta' || e.key == 'Control') {
179179
simulationArea.controlDown = true;
180180
}
181-
// zoom in: Cmd/Ctrl + '+' or '='
182-
if (simulationArea.controlDown && (e.keyCode == 187 || e.KeyCode == 171 || e.key == '+' || e.key == '=')) {
181+
// Zoom in: Cmd/Ctrl + '+' or Cmd/Ctrl + '='
182+
// (On US keyboards, '+' is Shift+'=', so we accept both to handle with/without Shift)
183+
if (simulationArea.controlDown && (e.keyCode == 187 || e.keyCode == 171 || e.key == '+' || e.key == '=')) {
183184
e.preventDefault();
184185
ZoomIn();
185186
}
186-
// zoom out: Cmd/Ctrl + '-'
187-
if (simulationArea.controlDown && (e.keyCode == 189 || e.Keycode == 173 || e.key == '-' || e.key == '_')) {
187+
// Zoom out: Cmd/Ctrl + '-'
188+
// (Only '-', not '_', since '_' requires Shift and could cause confusion)
189+
if (simulationArea.controlDown && (e.keyCode == 189 || e.keyCode == 173 || e.key == '-')) {
188190
e.preventDefault();
189191
ZoomOut();
190192
}

src/simulator/src/listeners.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -419,8 +419,10 @@ export default function startListeners() {
419419
simulationArea.controlDown = true
420420
}
421421

422-
// Keyboard zoom shortcuts (in addition to existing scroll/trackpad zoom)
423-
// zoom in: Cmd/Ctrl + '+' or '=' (calls existing ZoomIn function)
422+
// Keyboard zoom shortcuts
423+
// Zoom in: Cmd/Ctrl + '+' or Cmd/Ctrl + '='
424+
// (On US keyboards, '+' is Shift+'=', so we accept both to handle with/without Shift)
425+
// Also accepts keyCode 107 for numpad '+'
424426
if (
425427
(simulationArea.controlDown &&
426428
(e.keyCode == 187 || e.keyCode == 171 || e.key == '+' || e.key == '=')) ||
@@ -429,10 +431,12 @@ export default function startListeners() {
429431
e.preventDefault()
430432
ZoomIn()
431433
}
432-
// zoom out: Cmd/Ctrl + '-' or '_' (calls existing ZoomOut function)
434+
// Zoom out: Cmd/Ctrl + '-'
435+
// (Only '-', not '_', since '_' requires Shift and could cause confusion)
436+
// Also accepts keyCode 109 for numpad '-'
433437
if (
434438
(simulationArea.controlDown &&
435-
(e.keyCode == 189 || e.keyCode == 173 || e.key == '-' || e.key == '_')) ||
439+
(e.keyCode == 189 || e.keyCode == 173 || e.key == '-')) ||
436440
e.keyCode == 109
437441
) {
438442
e.preventDefault()
@@ -778,8 +782,8 @@ export default function startListeners() {
778782
})
779783
})
780784

781-
// zoomSliderListeners() disabled - slider removed to prevent accidental zoom from swipes/scroll
782-
// Zoom is now controlled by +/- buttons only (which call ZoomIn/ZoomOut directly)
785+
// zoomSliderListeners() (jQuery-based) disabled here - zoom slider handling has moved to Vue
786+
// Vue components (QuickButton.vue / QuickButtonMobile.vue) now manage the zoom slider and +/- buttons
783787
if (!embed) {
784788
setupTimingListeners()
785789
}

0 commit comments

Comments
 (0)