1 | import { Vector2 } from '../types'
|
---|
2 |
|
---|
3 | export function clamp(v: number, min: number, max: number) {
|
---|
4 | return Math.max(min, Math.min(v, max))
|
---|
5 | }
|
---|
6 |
|
---|
7 | export const V = {
|
---|
8 | toVector<T>(v: T | [T, T] | undefined, fallback?: T | [T, T]): [T, T] {
|
---|
9 | if (v === undefined) v = fallback as T | [T, T]
|
---|
10 | return Array.isArray(v) ? v : [v, v]
|
---|
11 | },
|
---|
12 | add(v1: Vector2, v2: Vector2): Vector2 {
|
---|
13 | return [v1[0] + v2[0], v1[1] + v2[1]]
|
---|
14 | },
|
---|
15 | sub(v1: Vector2, v2: Vector2): Vector2 {
|
---|
16 | return [v1[0] - v2[0], v1[1] - v2[1]]
|
---|
17 | },
|
---|
18 | addTo(v1: Vector2, v2: Vector2) {
|
---|
19 | v1[0] += v2[0]
|
---|
20 | v1[1] += v2[1]
|
---|
21 | },
|
---|
22 | subTo(v1: Vector2, v2: Vector2) {
|
---|
23 | v1[0] -= v2[0]
|
---|
24 | v1[1] -= v2[1]
|
---|
25 | }
|
---|
26 | }
|
---|
27 |
|
---|
28 | // Based on @aholachek ;)
|
---|
29 | // https://twitter.com/chpwn/status/285540192096497664
|
---|
30 | // iOS constant = 0.55
|
---|
31 |
|
---|
32 | // https://medium.com/@nathangitter/building-fluid-interfaces-ios-swift-9732bb934bf5
|
---|
33 |
|
---|
34 | function rubberband(distance: number, dimension: number, constant: number) {
|
---|
35 | if (dimension === 0 || Math.abs(dimension) === Infinity) return Math.pow(distance, constant * 5)
|
---|
36 | return (distance * dimension * constant) / (dimension + constant * distance)
|
---|
37 | }
|
---|
38 |
|
---|
39 | export function rubberbandIfOutOfBounds(position: number, min: number, max: number, constant = 0.15) {
|
---|
40 | if (constant === 0) return clamp(position, min, max)
|
---|
41 | if (position < min) return -rubberband(min - position, max - min, constant) + min
|
---|
42 | if (position > max) return +rubberband(position - max, max - min, constant) + max
|
---|
43 | return position
|
---|
44 | }
|
---|
45 |
|
---|
46 | export function computeRubberband(bounds: [Vector2, Vector2], [Vx, Vy]: Vector2, [Rx, Ry]: Vector2): Vector2 {
|
---|
47 | const [[X0, X1], [Y0, Y1]] = bounds
|
---|
48 | return [rubberbandIfOutOfBounds(Vx, X0, X1, Rx), rubberbandIfOutOfBounds(Vy, Y0, Y1, Ry)]
|
---|
49 | }
|
---|