@@ -91,6 +91,36 @@ export const calculateBounds = (
9191 return bounds ;
9292} ;
9393
94+ export function clamp ( v : number , min : number , max : number ) {
95+ return Math . max ( min , Math . min ( v , max ) ) ;
96+ }
97+
98+ // Based on @aholachek ;)
99+ // https://twitter.com/chpwn/status/285540192096497664
100+ // iOS constant = 0.55
101+
102+ // https://medium.com/@nathangitter /building-fluid-interfaces-ios-swift-9732bb934bf5
103+
104+ function rubberband ( distance : number , dimension : number , constant : number ) {
105+ if ( dimension === 0 || Math . abs ( dimension ) === Infinity )
106+ return distance ** ( constant * 5 ) ;
107+ return ( distance * dimension * constant ) / ( dimension + constant * distance ) ;
108+ }
109+
110+ export function rubberbandIfOutOfBounds (
111+ position : number ,
112+ min : number ,
113+ max : number ,
114+ constant = 0.15 ,
115+ ) {
116+ if ( constant === 0 ) return clamp ( position , min , max ) ;
117+ if ( position < min )
118+ return - rubberband ( min - position , max - min , constant ) + min ;
119+ if ( position > max )
120+ return + rubberband ( position - max , max - min , constant ) + max ;
121+ return position ;
122+ }
123+
94124/**
95125 * Keeps value between given bounds, used for limiting view to given boundaries
96126 * 1# eg. boundLimiter(2, 0, 3, true) => 2
@@ -140,15 +170,26 @@ export function getMouseBoundedPosition(
140170 paddingY = paddingValueY ;
141171 }
142172
143- const x = boundLimiter (
173+ const rubberbandX = rubberbandIfOutOfBounds (
144174 positionX ,
175+ minPositionX ,
176+ maxPositionX ,
177+ ) ;
178+ const rubberbandY = rubberbandIfOutOfBounds (
179+ positionY ,
180+ minPositionY ,
181+ maxPositionY ,
182+ ) ;
183+
184+ const x = boundLimiter (
185+ rubberbandX ,
145186 minPositionX - paddingX ,
146187 maxPositionX + paddingX ,
147188 limitToBounds ,
148189 ) ;
149190
150191 const y = boundLimiter (
151- positionY ,
192+ rubberbandY ,
152193 minPositionY - paddingY ,
153194 maxPositionY + paddingY ,
154195 limitToBounds ,
0 commit comments