1+ /*
2+ * Copyright 2025 Lambda
3+ *
4+ * This program is free software: you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation, either version 3 of the License, or
7+ * (at your option) any later version.
8+ *
9+ * This program is distributed in the hope that it will be useful,
10+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+ * GNU General Public License for more details.
13+ *
14+ * You should have received a copy of the GNU General Public License
15+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
16+ */
17+
18+ package com.lambda.module.modules.render
19+
20+ import com.lambda.event.events.MouseEvent
21+ import com.lambda.event.events.RenderEvent
22+ import com.lambda.event.listener.SafeListener.Companion.listen
23+ import com.lambda.module.Module
24+ import com.lambda.module.tag.ModuleTag
25+ import java.lang.Math.clamp
26+
27+ object Zoom : Module(
28+ " Zoom" ,
29+ " Zooms the current view" ,
30+ ModuleTag .RENDER
31+ ) {
32+ override val disableOnRelease by setting(" Disable On Release" , true )
33+ private var zoom by setting(" Zoom" , 2f , 1f .. 10f , 0.1f )
34+ private val style by setting(" Style" , ZoomStyle .EaseOut )
35+ private val animationDuration by setting(" Animation Duration" , 1f , 0.1f .. 10f , 0.1f ) { style != ZoomStyle .Instant }
36+ private val scroll by setting(" Scroll" , true )
37+ private val persistentScroll by setting(" Persistent Scroll" , false ) { scroll }
38+ private val sensitivity by setting(" Sensitivity" , 0.4f , 0.1f .. 1f , 0.1f ) { scroll }
39+ @JvmStatic val smoothMovement by setting(" Smooth Movement" , false )
40+
41+ private var extraZoom = 0f
42+ set(value) {
43+ field = value.coerceAtLeast(- zoom + 1 )
44+ }
45+ @JvmStatic val targetZoom: Float
46+ get() = zoom + extraZoom
47+
48+ @JvmStatic var currentZoom = 1f ; private set
49+ private var lastZoomTime = 1L
50+ private val zoomProgress
51+ get() =
52+ clamp((System .currentTimeMillis() - lastZoomTime) / (animationDuration * 1000 ).toDouble(), 0.0 , 1.0 ).toFloat()
53+
54+ init {
55+ listen<MouseEvent .Scroll > { event ->
56+ val yDelta = event.delta.y.toFloat()
57+ val delta = (yDelta * sensitivity) + (((zoom + extraZoom) * sensitivity) * yDelta)
58+ if (persistentScroll) zoom + = delta
59+ else extraZoom + = delta
60+ updateZoomTime()
61+ event.cancel()
62+ }
63+
64+ listen<RenderEvent .Render >(alwaysListen = true ) {
65+ updateCurrentZoom()
66+ }
67+
68+ onEnable {
69+ updateZoomTime()
70+ }
71+ onDisable {
72+ extraZoom = 0f
73+ updateZoomTime()
74+ }
75+ }
76+
77+ private fun updateZoomTime () {
78+ lastZoomTime = System .currentTimeMillis()
79+ }
80+
81+ @JvmStatic
82+ fun updateCurrentZoom () {
83+ val target = if (isEnabled) targetZoom else 1f
84+ if (currentZoom == target) return
85+ currentZoom = when (style) {
86+ ZoomStyle .Instant -> target
87+ ZoomStyle .EaseOut -> easeOut(currentZoom, target, zoomProgress)
88+ ZoomStyle .EaseIn -> easeIn(currentZoom, target, zoomProgress)
89+ }
90+ }
91+
92+ private fun easeOut (start : Float , end : Float , progress : Float ): Float {
93+ val easedT = 1f - (1f - progress) * (1f - progress)
94+ return start + ((end - start) * easedT)
95+ }
96+
97+ private fun easeIn (start : Float , end : Float , progress : Float ): Float {
98+ val easedT = progress * progress
99+ return start + ((end - start) * easedT)
100+ }
101+
102+ private enum class ZoomStyle {
103+ Instant ,
104+ EaseOut ,
105+ EaseIn
106+ }
107+ }
0 commit comments