@@ -23,7 +23,7 @@ import predictor_basic from './predictor.js';
2323import predictor_test from './predictor_test.js' ;
2424import { ppmModelPredict } from './predictor_ppm.js' ;
2525import predictor_ppm_new , {
26- ppmNewGetPredictor ,
26+ ppmNewGetPredictorAsync ,
2727 ppmNewAddCorpus ,
2828 ppmNewSetLearningEnabled ,
2929 ppmNewGetLearningEnabled ,
@@ -41,6 +41,7 @@ import * as LanguageManager from './languageManager.js';
4141
4242const messageLabelText = '' ;
4343const speechAnnouncement = 'Speech is now active.' ;
44+ const legacyRenderIntervalMillis = 400 ;
4445
4546const defaultPredictorList = [ {
4647 'label' : 'PPM (Enhanced)' , 'item' : predictor_ppm_new ,
@@ -58,6 +59,9 @@ export default class UserInterface {
5859 constructor ( parent ) {
5960 this . _parent = parent ;
6061 this . _intervalRender = undefined ;
62+ this . _renderLoopKind = null ;
63+ this . _lastRenderTimestamp = null ;
64+ this . _renderAccumulator = 0 ;
6165
6266 this . _keyboardMode = parent . classList . contains ( 'keyboard' ) ;
6367
@@ -941,6 +945,10 @@ export default class UserInterface {
941945 return this . _currentSpeed . toFixed ( 1 ) ;
942946 }
943947
948+ _normalise_speed ( speed ) {
949+ return speed * ( this . _transitionMillis / legacyRenderIntervalMillis ) ;
950+ }
951+
944952 _longest_common_prefix ( a , b ) {
945953 const max = Math . min ( a . length , b . length ) ;
946954 let i = 0 ;
@@ -1196,7 +1204,7 @@ export default class UserInterface {
11961204 _select_behaviour ( index ) {
11971205 this . _limits . targetRight = ( index === 0 ) ;
11981206 this . _currentSpeed = ( index === 0 ? 0.1 : 0.2 ) ;
1199- this . _pointer . multiplierLeftRight = this . _currentSpeed ;
1207+ this . _pointer . multiplierLeftRight = this . _normalise_speed ( this . _currentSpeed ) ;
12001208 // if (this._speedLeftRightInput !== undefined) {
12011209 const speedLeftRightInput = this . _panels . speed . horizontal . node ;
12021210 if ( speedLeftRightInput !== undefined ) {
@@ -1212,7 +1220,7 @@ export default class UserInterface {
12121220 // Update predictor with language-specific corpus
12131221 // Only works with PPM (Enhanced) predictor
12141222 try {
1215- const predictor = ppmNewGetPredictor ( ) ;
1223+ const predictor = await ppmNewGetPredictorAsync ( ) ;
12161224 if ( predictor ) {
12171225 // Get lexicon for the language
12181226 const lexicon = await LanguageManager . getLexicon ( language . code , 5000 ) ;
@@ -1514,20 +1522,26 @@ export default class UserInterface {
15141522 if ( this . _keyboardMode ) {
15151523 // Can't show settings in input controls in keyboard mode. The input
15161524 // would itself require a keyboard. Set some slower default values.
1517- this . _pointer . multiplierLeftRight = 0.2 ;
1518- this . _pointer . multiplierUpDown = 0.2 ;
1525+ this . _pointer . multiplierLeftRight = this . _normalise_speed ( 0.2 ) ;
1526+ this . _pointer . multiplierUpDown = this . _normalise_speed ( 0.2 ) ;
15191527 this . _select_behaviour ( 1 ) ;
15201528 return ;
15211529 }
15221530
15231531 this . _panels . speed . horizontal . listener = ( value ) => {
15241532 this . _currentSpeed = value ;
1525- this . _pointer . multiplierLeftRight = value ;
1533+ this . _pointer . multiplierLeftRight = this . _normalise_speed ( value ) ;
15261534 this . _sync_quick_controls ( ) ;
15271535 } ;
15281536 this . _select_behaviour ( 0 ) ;
1537+ const initialVerticalSpeed = Number . parseFloat (
1538+ this . _panels . speed . vertical . node . value ,
1539+ ) ;
1540+ if ( ! Number . isNaN ( initialVerticalSpeed ) ) {
1541+ this . _pointer . multiplierUpDown = this . _normalise_speed ( initialVerticalSpeed ) ;
1542+ }
15291543 this . _panels . speed . vertical . listener = ( value ) => {
1530- this . _pointer . multiplierUpDown = value ;
1544+ this . _pointer . multiplierUpDown = this . _normalise_speed ( value ) ;
15311545 } ;
15321546 }
15331547
@@ -1635,8 +1649,44 @@ export default class UserInterface {
16351649
16361650 if ( render_one ( ) && continuous ) {
16371651 this . _stopGoTextNode . nodeValue = 'Started' ;
1638- this . _intervalRender = setInterval (
1639- render_one , this . _transitionMillis ) ;
1652+ if ( typeof window . requestAnimationFrame === 'function' ) {
1653+ this . _renderLoopKind = 'raf' ;
1654+ this . _lastRenderTimestamp = null ;
1655+ this . _renderAccumulator = 0 ;
1656+
1657+ const tick = ( timestamp ) => {
1658+ if ( this . _intervalRender === null ) {
1659+ return ;
1660+ }
1661+
1662+ if ( this . _lastRenderTimestamp === null ) {
1663+ this . _lastRenderTimestamp = timestamp ;
1664+ }
1665+ const elapsed = timestamp - this . _lastRenderTimestamp ;
1666+ this . _lastRenderTimestamp = timestamp ;
1667+
1668+ this . _renderAccumulator = Math . min (
1669+ this . _renderAccumulator + elapsed ,
1670+ this . _transitionMillis * 4 ,
1671+ ) ;
1672+
1673+ while ( this . _renderAccumulator >= this . _transitionMillis ) {
1674+ this . _renderAccumulator -= this . _transitionMillis ;
1675+ if ( ! render_one ( ) ) {
1676+ this . _stop_render ( ) ;
1677+ return ;
1678+ }
1679+ }
1680+
1681+ this . _intervalRender = window . requestAnimationFrame ( tick ) ;
1682+ } ;
1683+
1684+ this . _intervalRender = window . requestAnimationFrame ( tick ) ;
1685+ } else {
1686+ this . _renderLoopKind = 'interval' ;
1687+ this . _intervalRender = setInterval (
1688+ render_one , this . _transitionMillis ) ;
1689+ }
16401690 } else {
16411691 this . _stop_render ( ) ;
16421692 }
@@ -1649,8 +1699,15 @@ export default class UserInterface {
16491699 }
16501700
16511701 if ( this . _intervalRender !== null ) {
1652- clearInterval ( this . _intervalRender ) ;
1702+ if ( this . _renderLoopKind === 'raf' ) {
1703+ window . cancelAnimationFrame ( this . _intervalRender ) ;
1704+ } else {
1705+ clearInterval ( this . _intervalRender ) ;
1706+ }
16531707 this . _intervalRender = null ;
1708+ this . _renderLoopKind = null ;
1709+ this . _lastRenderTimestamp = null ;
1710+ this . _renderAccumulator = 0 ;
16541711 this . _stopGoTextNode . nodeValue = 'Stopped' ;
16551712 if ( this . _quickControls . playButton !== undefined ) {
16561713 this . _quickControls . playButton . textContent = 'Play' ;
0 commit comments