Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/assets/js/mod/read.js

    r9173265 re48ec78  
    448448    if (punten[vooruit].value - nu <= vangZone()) echtGaNaar(vooruit);
    449449  };
     450
     451  // OP TOUCH DOET DE MODULE-EIGEN TRIGGER HET NIET, en dat is meetbaar in de
     452  // vendor-bron, geen vermoeden. Drie feiten op een rij:
     453  //
     454  //   1. lenis geeft 'virtual-scroll' door met de RUWE vingerdelta, VOOR hij
     455  //      de uitloop uitrekent (teken * |snelheid|^touchInertiaExponent).
     456  //   2. lenis-snap negeert elke touchmove en beoordeelt dus EEN keer per
     457  //      gebaar, op touchend, met `scroll + rawDelta` -- de plek waar je
     458  //      vinger LOSLIET.
     459  //   3. de uitloop draagt daarna nog honderden pixels verder.
     460  //
     461  // De snapbeslissing valt dus op een positie die de scroll meteen verlaat.
     462  // Op desktop klopt dezelfde som wel: wieldelta's zijn klein en de
     463  // smoothWheel-uitloop is kort, dus voorspelling en landing liggen bijeen.
     464  // Vandaar: op touch de module-trigger eraf en zelf beoordelen tegen
     465  // lenis.targetScroll -- die wordt synchroon bij touchend gezet en IS het
     466  // exacte landingspunt van de uitloop.
     467  if (OP_TOUCH.matches) {
     468    // Hoe lang het richten naar de lijn duurt, in seconden. De ene knop voor
     469    // "snapperiger": 0.18 is direct, 0.3 is landen, 0.5 is zweven.
     470    const SNAP_DUUR = 0.22;
     471    lenis.off('virtual-scroll', snap.onSnapDebounced);
     472    let raakTimer = null;
     473    let vertrek = 0;   // scrollpositie bij loslaten: punten daarachter zijn
     474                       // de bovenkant van het HUIDIGE bericht, nooit grijpen
     475    lenis.on('virtual-scroll', (e) => {
     476      const soort = e.event && e.event.type;
     477      if (soort === 'touchstart' || soort === 'touchmove') { clearTimeout(raakTimer); return; }
     478      if (soort !== 'touchend') return;
     479      vertrek = lenis.scroll;
     480      clearTimeout(raakTimer);
     481      // TIMEOUT 0, geen 150ms. Dit event komt binnen VOOR lenis zelf de
     482      // touchend verwerkt (de emit staat in de bron boven de verwerking), dus
     483      // targetScroll is hier nog het oude doel. Een tik later is de uitloop
     484      // gestart en staat targetScroll op de echte landing -- en dan sturen we
     485      // hem meteen bij, in plaats van de uitloop 150ms te laten lopen en er
     486      // dan een aparte snap-animatie overheen te zetten.
     487      raakTimer = setTimeout(() => {
     488        if (!laatsteRichtingOmlaag || snap.isStopped) return;
     489        const doel = lenis.targetScroll;   // de echte landing, niet de raakdelta
     490        const punten = snap.computeSnaps();
     491        // De EERSTE grens voorbij het loslaatpunt, niet de dichtstbijzijnde bij
     492        // de landing. Robins regel (24-8): wordt het target voorbijgescrolld,
     493        // dan landen we alsnog OP het target. De zone werkt dus alleen aan de
     494        // korte kant -- kom je er niet eens bij in de buurt, dan lees je gewoon
     495        // binnen een lang bericht en blijft alles vrij. Eroverheen, hoe ver
     496        // ook, betekent grijpen. Een harde veeg komt daarmee altijd precies
     497        // een bericht verder, nooit twee: dat is het bladeren.
     498        let eerste = -1;
     499        punten.forEach((punt, i) => {
     500          if (punt.value > vertrek + 2 && (eerste < 0 || punt.value < punten[eerste].value)) eerste = i;
     501        });
     502        if (eerste < 0) return;            // niets meer voor je: vrij uitscrollen
     503        // HET RICHTEN IS DE SNAP (Robins regel, 24-8): de lopende uitloop
     504        // krijgt het nieuwe doel, er komt geen tweede animatie overheen.
     505        //
     506        // MET EEN VASTE DUUR, niet met de lerp van de uitloop. Die lerp-vorm
     507        // (0.09) is boterzacht maar heeft een exponentiele staart van ruim een
     508        // halve seconde -- Robin wilde het korter en beslister (24-8). Een
     509        // duur eindigt ECHT, op een instelbaar moment, zoals iOS-paging: vlot
     510        // weg, stevig landen. Zelfde easing-familie als de desktop-snap.
     511        // SNAP_DUUR is de enige knop: korter is snapperiger, langer is zachter.
     512        if (doel >= punten[eerste].value - vangZone()) {
     513          lenis.scrollTo(punten[eerste].value, {
     514            duration: SNAP_DUUR,
     515            easing: (t) => 1 - Math.pow(1 - t, 4),
     516            force: true,
     517            userData: { initiator: 'snap' },
     518          });
     519        }
     520      }, 0);
     521    });
     522  }
     523
    450524  // Native snappen uit: twee mechanismen op dezelfde scroller vechten.
    451525  document.documentElement.style.scrollSnapType = 'none';
Note: See TracChangeset for help on using the changeset viewer.