@@ -923,31 +923,41 @@ public void SetTransform(Vector2 newTranslation, Vector2 newScale)
923923
924924 public void EnforceScaleAndRange ( )
925925 {
926- // Minimum scale might also be constrained by maximum range
927- float constrainedHScaleMin = rect . width / m_HScaleMin ;
928- float constrainedVScaleMin = rect . height / m_VScaleMin ;
929- if ( hRangeMax != Mathf . Infinity && hRangeMin != Mathf . NegativeInfinity )
930- constrainedHScaleMin = Mathf . Min ( constrainedHScaleMin , hRangeMax - hRangeMin ) ;
931- if ( vRangeMax != Mathf . Infinity && vRangeMin != Mathf . NegativeInfinity )
932- constrainedVScaleMin = Mathf . Min ( constrainedVScaleMin , vRangeMax - vRangeMin ) ;
933-
934926 Rect oldArea = m_LastShownAreaInsideMargins ;
935927 Rect newArea = shownAreaInsideMargins ;
936928 if ( newArea == oldArea )
937929 return ;
938930
939- float epsilon = 0.00001f ;
940931 float minChange = 0.01f ;
941932
942933 if ( ! Mathf . Approximately ( newArea . width , oldArea . width ) )
943934 {
944- float constrainedValue = newArea . width < oldArea . width - epsilon ? rect . width / m_HScaleMax : constrainedHScaleMin ;
945- constrainedValue = GetWidthInsideMargins ( constrainedValue , true ) ;
946- float xLerp = Mathf . InverseLerp ( oldArea . width , newArea . width , constrainedValue ) ;
935+ float constrainedWidth = newArea . width ;
936+ if ( newArea . width < oldArea . width )
937+ {
938+ // The shown area decreasing in size means the scale is increasing. This happens e.g. while zooming in.
939+ // Only the max scale restricts the shown area size here, range has no influence.
940+ constrainedWidth = GetWidthInsideMargins ( drawRect . width / m_HScaleMax , false ) ;
941+ }
942+ else
943+ {
944+ constrainedWidth = GetWidthInsideMargins ( drawRect . width / m_HScaleMin , false ) ;
945+
946+ if ( hRangeMax != Mathf . Infinity && hRangeMin != Mathf . NegativeInfinity )
947+ {
948+ // range only has an influence if it is enforced, i.e. not infinity
949+ float denum = hRangeMax - hRangeMin ;
950+ if ( denum < kMinWidth ) denum = kMinWidth ;
951+
952+ constrainedWidth = Mathf . Min ( constrainedWidth , denum ) ;
953+ }
954+ }
955+
956+ float xLerp = Mathf . InverseLerp ( oldArea . width , newArea . width , constrainedWidth ) ;
947957 float newWidth = Mathf . Lerp ( oldArea . width , newArea . width , xLerp ) ;
948958 float widthChange = Mathf . Abs ( newWidth - newArea . width ) ;
949959 newArea = new Rect (
950- // only affect the position if there was any significant change in width (the unit is in pixels so technically anything under 0.05f would already be impossible to see)
960+ // only affect the position if there was any significant change in width
951961 // this fixes an issue where if width was only different due to rounding issues, position changes are ignored as xLerp comes back 0 (or very nearly 0)
952962 widthChange > minChange ? Mathf . Lerp ( oldArea . x , newArea . x , xLerp ) : newArea . x ,
953963 newArea . y ,
@@ -957,14 +967,32 @@ public void EnforceScaleAndRange()
957967 }
958968 if ( ! Mathf . Approximately ( newArea . height , oldArea . height ) )
959969 {
960- float constrainedValue = newArea . height < oldArea . height - epsilon ? rect . height / m_VScaleMax : constrainedVScaleMin ;
961- constrainedValue = GetHeightInsideMargins ( constrainedValue , true ) ;
962- float yLerp = Mathf . InverseLerp ( oldArea . height , newArea . height , constrainedValue ) ;
970+ float constrainedHeight = newArea . height ;
971+ if ( newArea . height < oldArea . height )
972+ {
973+ // The shown area decreasing in size means the scale is increasing. This happens e.g. while zooming in.
974+ // Only the max scale restricts the shown area size here, range has no influence.
975+ constrainedHeight = GetHeightInsideMargins ( drawRect . height / m_VScaleMax , false ) ;
976+ }
977+ else
978+ {
979+ constrainedHeight = GetHeightInsideMargins ( drawRect . height / m_VScaleMin , false ) ;
980+
981+ if ( vRangeMax != Mathf . Infinity && vRangeMin != Mathf . NegativeInfinity )
982+ {
983+ // range only has an influence if it is enforced, i.e. not infinity
984+ float denum = vRangeMax - vRangeMin ;
985+ if ( denum < kMinHeight ) denum = kMinHeight ;
986+ constrainedHeight = Mathf . Min ( constrainedHeight , denum ) ;
987+ }
988+ }
989+
990+ float yLerp = Mathf . InverseLerp ( oldArea . height , newArea . height , constrainedHeight ) ;
963991 float newHeight = Mathf . Lerp ( oldArea . height , newArea . height , yLerp ) ;
964992 float heightChange = Mathf . Abs ( newHeight - newArea . height ) ;
965993 newArea = new Rect (
966994 newArea . x ,
967- // only affect the position if there was any significant change in height (the unit is in pixels so technically anything under 0.05f would already be impossible to see)
995+ // only affect the position if there was any significant change in height
968996 // this fixes an issue where if height was only different due to rounding issues, position changes are ignored as yLerp comes back 0 (or very nearly 0)
969997 heightChange > minChange ? Mathf . Lerp ( oldArea . y , newArea . y , yLerp ) : newArea . y ,
970998 newArea . width ,
@@ -983,7 +1011,7 @@ public void EnforceScaleAndRange()
9831011 newArea . y = vRangeMax - newArea . height ;
9841012
9851013 shownAreaInsideMarginsInternal = newArea ;
986- m_LastShownAreaInsideMargins = newArea ;
1014+ m_LastShownAreaInsideMargins = shownAreaInsideMargins ;
9871015 }
9881016
9891017 public float PixelToTime ( float pixelX , Rect rect )
0 commit comments