@@ -17,6 +17,7 @@ import ControllerRandom from './controllerrandom.js';
1717import ControllerPointer from './controllerpointer.js' ;
1818import Viewer from './viewer.js' ;
1919import ZoomBox from './zoombox.js' ;
20+ import AutoSpeedControl from './autoSpeedControl.js' ;
2021
2122import predictor_dummy from './predictor_dummy.js' ;
2223import predictor_basic from './predictor.js' ;
@@ -84,6 +85,10 @@ export default class UserInterface {
8485 // document.head.append(this._cssNode);
8586
8687 this . _speedLeftRightInput = undefined ;
88+ this . _baseSpeedHorizontal = 0.1 ;
89+ this . _baseSpeedVertical = 0.2 ;
90+ this . _autoSpeedEnabled = true ;
91+ this . _autoSpeedControl = new AutoSpeedControl ( ) ;
8792
8893 // Spawn and render parameters in mystery SVG units.
8994 this . _limits = new Limits ( ) ;
@@ -539,6 +544,14 @@ export default class UserInterface {
539544 this . _quickControls . speedPlus = this . _create_button (
540545 new Piece ( speedGroup ) , '+' , 'ui-step-button' ,
541546 ) ;
547+ const autoSpeedLabel = speedGroup . appendChild ( document . createElement ( 'span' ) ) ;
548+ autoSpeedLabel . className = 'ui-nav-label' ;
549+ autoSpeedLabel . textContent = 'Auto' ;
550+ this . _quickControls . autoSpeed = speedGroup . appendChild (
551+ document . createElement ( 'input' ) ,
552+ ) ;
553+ this . _quickControls . autoSpeed . type = 'checkbox' ;
554+ this . _quickControls . autoSpeed . className = 'ui-switch' ;
542555
543556 const groupLearning = createGroup ( ) ;
544557 const learningLabel = groupLearning . appendChild ( document . createElement ( 'span' ) ) ;
@@ -949,6 +962,42 @@ export default class UserInterface {
949962 return speed * ( this . _transitionMillis / legacyRenderIntervalMillis ) ;
950963 }
951964
965+ _effective_speed_factor ( ) {
966+ return this . _autoSpeedEnabled ? this . _autoSpeedControl . factor : 1 ;
967+ }
968+
969+ _apply_pointer_speeds ( ) {
970+ if ( this . _pointer === undefined ) {
971+ return ;
972+ }
973+ const factor = this . _effective_speed_factor ( ) ;
974+ this . _pointer . multiplierLeftRight = this . _normalise_speed (
975+ this . _baseSpeedHorizontal * factor ,
976+ ) ;
977+ this . _pointer . multiplierUpDown = this . _normalise_speed (
978+ this . _baseSpeedVertical * factor ,
979+ ) ;
980+ }
981+
982+ _update_auto_speed ( elapsedMillis ) {
983+ if ( ! this . _autoSpeedEnabled || this . _pointer === undefined ) {
984+ return ;
985+ }
986+ if ( ! Object . is ( this . _controller , this . _controllerPointer ) || ! this . _pointer . going ) {
987+ this . _autoSpeedControl . reset ( ) ;
988+ this . _apply_pointer_speeds ( ) ;
989+ return ;
990+ }
991+
992+ this . _autoSpeedControl . update (
993+ this . _pointer . rawX ,
994+ this . _pointer . rawY ,
995+ this . _baseSpeedHorizontal ,
996+ elapsedMillis ,
997+ ) ;
998+ this . _apply_pointer_speeds ( ) ;
999+ }
1000+
9521001 _longest_common_prefix ( a , b ) {
9531002 const max = Math . min ( a . length , b . length ) ;
9541003 let i = 0 ;
@@ -1027,6 +1076,9 @@ export default class UserInterface {
10271076 if ( this . _quickControls . learning !== undefined ) {
10281077 this . _quickControls . learning . checked = this . _learningEnabled ;
10291078 }
1079+ if ( this . _quickControls . autoSpeed !== undefined ) {
1080+ this . _quickControls . autoSpeed . checked = this . _autoSpeedEnabled ;
1081+ }
10301082 if ( this . _quickControls . messagePosition !== undefined ) {
10311083 this . _quickControls . messagePosition . value = this . _messagePosition ;
10321084 }
@@ -1072,6 +1124,11 @@ export default class UserInterface {
10721124 this . _panels . speed . horizontal . set_value ( next ) ;
10731125 } ) ;
10741126 }
1127+ if ( this . _quickControls . autoSpeed !== undefined ) {
1128+ this . _quickControls . autoSpeed . addEventListener ( 'change' , ( event ) => {
1129+ this . _panels . speed . auto . set_value ( event . target . checked ) ;
1130+ } ) ;
1131+ }
10751132
10761133 if ( this . _quickControls . fontSizeMinus !== undefined ) {
10771134 this . _quickControls . fontSizeMinus . addEventListener ( 'click' , ( ) => {
@@ -1204,7 +1261,8 @@ export default class UserInterface {
12041261 _select_behaviour ( index ) {
12051262 this . _limits . targetRight = ( index === 0 ) ;
12061263 this . _currentSpeed = ( index === 0 ? 0.1 : 0.2 ) ;
1207- this . _pointer . multiplierLeftRight = this . _normalise_speed ( this . _currentSpeed ) ;
1264+ this . _baseSpeedHorizontal = this . _currentSpeed ;
1265+ this . _apply_pointer_speeds ( ) ;
12081266 // if (this._speedLeftRightInput !== undefined) {
12091267 const speedLeftRightInput = this . _panels . speed . horizontal . node ;
12101268 if ( speedLeftRightInput !== undefined ) {
@@ -1522,26 +1580,43 @@ export default class UserInterface {
15221580 if ( this . _keyboardMode ) {
15231581 // Can't show settings in input controls in keyboard mode. The input
15241582 // would itself require a keyboard. Set some slower default values.
1525- this . _pointer . multiplierLeftRight = this . _normalise_speed ( 0.2 ) ;
1526- this . _pointer . multiplierUpDown = this . _normalise_speed ( 0.2 ) ;
1583+ this . _baseSpeedHorizontal = 0.2 ;
1584+ this . _baseSpeedVertical = 0.2 ;
1585+ this . _autoSpeedEnabled = false ;
1586+ this . _autoSpeedControl . reset ( ) ;
1587+ this . _apply_pointer_speeds ( ) ;
15271588 this . _select_behaviour ( 1 ) ;
15281589 return ;
15291590 }
15301591
1592+ if ( this . _panels . speed . auto !== undefined ) {
1593+ this . _autoSpeedEnabled = ! ! this . _panels . speed . auto . node . checked ;
1594+ this . _panels . speed . auto . listener = ( checked ) => {
1595+ this . _autoSpeedEnabled = ! ! checked ;
1596+ this . _autoSpeedControl . reset ( ) ;
1597+ this . _apply_pointer_speeds ( ) ;
1598+ } ;
1599+ }
1600+
15311601 this . _panels . speed . horizontal . listener = ( value ) => {
15321602 this . _currentSpeed = value ;
1533- this . _pointer . multiplierLeftRight = this . _normalise_speed ( value ) ;
1603+ this . _baseSpeedHorizontal = value ;
1604+ this . _autoSpeedControl . reset ( ) ;
1605+ this . _apply_pointer_speeds ( ) ;
15341606 this . _sync_quick_controls ( ) ;
15351607 } ;
15361608 this . _select_behaviour ( 0 ) ;
15371609 const initialVerticalSpeed = Number . parseFloat (
15381610 this . _panels . speed . vertical . node . value ,
15391611 ) ;
15401612 if ( ! Number . isNaN ( initialVerticalSpeed ) ) {
1541- this . _pointer . multiplierUpDown = this . _normalise_speed ( initialVerticalSpeed ) ;
1613+ this . _baseSpeedVertical = initialVerticalSpeed ;
1614+ this . _apply_pointer_speeds ( ) ;
15421615 }
15431616 this . _panels . speed . vertical . listener = ( value ) => {
1544- this . _pointer . multiplierUpDown = this . _normalise_speed ( value ) ;
1617+ this . _baseSpeedVertical = value ;
1618+ this . _autoSpeedControl . reset ( ) ;
1619+ this . _apply_pointer_speeds ( ) ;
15451620 } ;
15461621 }
15471622
@@ -1664,6 +1739,7 @@ export default class UserInterface {
16641739 }
16651740 const elapsed = timestamp - this . _lastRenderTimestamp ;
16661741 this . _lastRenderTimestamp = timestamp ;
1742+ this . _update_auto_speed ( elapsed ) ;
16671743
16681744 this . _renderAccumulator = Math . min (
16691745 this . _renderAccumulator + elapsed ,
@@ -1684,8 +1760,12 @@ export default class UserInterface {
16841760 this . _intervalRender = window . requestAnimationFrame ( tick ) ;
16851761 } else {
16861762 this . _renderLoopKind = 'interval' ;
1763+ this . _update_auto_speed ( this . _transitionMillis ) ;
16871764 this . _intervalRender = setInterval (
1688- render_one , this . _transitionMillis ) ;
1765+ ( ) => {
1766+ this . _update_auto_speed ( this . _transitionMillis ) ;
1767+ render_one ( ) ;
1768+ } , this . _transitionMillis ) ;
16891769 }
16901770 } else {
16911771 this . _stop_render ( ) ;
0 commit comments