|
1 | 1 | // third-party |
2 | 2 | import * as React from "react"; |
3 | 3 | import { styled } from "styled-components"; |
4 | | -import gsap from "gsap"; |
5 | | -import { ScrollToPlugin } from "gsap/dist/ScrollToPlugin"; |
6 | 4 |
|
7 | 5 | // local |
8 | 6 | import { Theme, ThemeContext } from "../theme/Theme"; |
9 | 7 | import { AnchorSkin } from "../skins/AnchorSkin"; |
10 | 8 | import { ScrollbarSkin } from "../skins/ScrollbarSkin"; |
11 | 9 | import { SelectionSkin } from "../skins/SelectionSkin"; |
12 | 10 | import { TableSkin } from "../skins/TableSkin"; |
| 11 | +import { EnhancedWheel } from "../utils/EnhancedWheel"; |
13 | 12 | import * as ColorUtils from "../utils/ColorUtils"; |
14 | 13 | import * as MathUtils from "../utils/MathUtils"; |
15 | 14 | import * as REMConvert from "../utils/REMConvert"; |
@@ -82,6 +81,12 @@ export function Group(params: { |
82 | 81 | */ |
83 | 82 | wheelHorizontal?: boolean, |
84 | 83 |
|
| 84 | + /** |
| 85 | + * For vertically-scrollable groups, makes vertical scrolling through |
| 86 | + * the mouse wheel more faster and smoother. |
| 87 | + */ |
| 88 | + wheelVertical?: boolean, |
| 89 | + |
85 | 90 | contextMenu?: React.MouseEventHandler<HTMLDivElement>, |
86 | 91 | click?: React.MouseEventHandler<HTMLDivElement>, |
87 | 92 | mouseOver?: React.MouseEventHandler<HTMLDivElement>, |
@@ -139,61 +144,33 @@ export function Group(params: { |
139 | 144 | "opacity " + COMMON_DELAY + "ms " + params.easePosition |
140 | 145 | } |
141 | 146 |
|
142 | | - // Handle mouse wheel |
143 | | - React.useEffect(() => { |
144 | | - const div_el = div.current!; |
145 | | - let added_handler = false; |
146 | | - if (params.wheelHorizontal) { |
147 | | - div_el.addEventListener("wheel", wheel, { passive: false }); |
148 | | - added_handler = true; |
149 | | - } |
150 | | - return () => { |
151 | | - if (added_handler) { |
152 | | - div_el.removeEventListener("wheel", wheel); |
| 147 | + // Handle mouse wheel (horizontal) |
| 148 | + React.useEffect(() => { |
| 149 | + const div_el = div.current!; |
| 150 | + let enhanced_wheel = null; |
| 151 | + if (params.wheelHorizontal) { |
| 152 | + enhanced_wheel = new EnhancedWheel(div_el, "horizontal"); |
153 | 153 | } |
154 | | - }; |
155 | | - }, [params.wheelHorizontal]); |
156 | | - const last_wheel_timestamp = React.useRef<number>(-1); |
157 | | - const wheel_multiplier = React.useRef<number>(2); |
158 | | - const gsap_wheel_tween = React.useRef<null | gsap.core.Tween>(null); |
159 | | - const wheel = (e: WheelEvent): void => { |
160 | | - const div = e.currentTarget as HTMLDivElement; |
161 | | - // deltaMode == DOM_DELTA_PIXEL |
162 | | - if (e.deltaMode == 0) { |
163 | | - if (e.deltaX || e.deltaY == 0) return; |
164 | | - |
165 | | - e.preventDefault(); |
166 | | - // increase scroll depending on wheel-roll duration |
167 | | - if (last_wheel_timestamp.current != -1) { |
168 | | - const last_roll_recent = last_wheel_timestamp.current > Date.now() - 250; |
169 | | - if (last_roll_recent) { |
170 | | - wheel_multiplier.current *= 1.2; |
171 | | - wheel_multiplier.current = MathUtils.clamp(wheel_multiplier.current, 1, 16); |
172 | | - } else { |
173 | | - wheel_multiplier.current = 2; |
| 154 | + return () => { |
| 155 | + if (enhanced_wheel) { |
| 156 | + enhanced_wheel.destroy(); |
174 | 157 | } |
175 | | - } else { |
176 | | - wheel_multiplier.current = 2; |
177 | | - } |
178 | | - const delta = e.deltaY * wheel_multiplier.current; |
179 | | - let target_scroll = div.scrollLeft + delta; |
180 | | - target_scroll = MathUtils.clamp(target_scroll, 0, div.scrollWidth); |
181 | | - if (gsap_wheel_tween.current) { |
182 | | - gsap_wheel_tween.current!.kill(); |
183 | | - gsap_wheel_tween.current = null; |
| 158 | + }; |
| 159 | + }, [params.wheelHorizontal]); |
| 160 | + |
| 161 | + // Handle mouse wheel (vertical) |
| 162 | + React.useEffect(() => { |
| 163 | + const div_el = div.current!; |
| 164 | + let enhanced_wheel = null; |
| 165 | + if (params.wheelVertical) { |
| 166 | + enhanced_wheel = new EnhancedWheel(div_el, "vertical"); |
184 | 167 | } |
185 | | - gsap.registerPlugin(ScrollToPlugin); |
186 | | - gsap_wheel_tween.current = gsap.to(div, { |
187 | | - scrollLeft: target_scroll, |
188 | | - duration: 0.3, |
189 | | - ease: "power1.out", |
190 | | - }); |
191 | | - gsap_wheel_tween.current!.then(() => { |
192 | | - gsap_wheel_tween.current = null; |
193 | | - }); |
194 | | - last_wheel_timestamp.current = Date.now(); |
195 | | - } |
196 | | - }; |
| 168 | + return () => { |
| 169 | + if (enhanced_wheel) { |
| 170 | + enhanced_wheel.destroy(); |
| 171 | + } |
| 172 | + }; |
| 173 | + }, [params.wheelVertical]); |
197 | 174 |
|
198 | 175 | // Layout |
199 | 176 | return ( |
|
0 commit comments