Changeset c581e5e in Klonkt


Ignore:
Timestamp:
08/20/2026 07:25:24 AM (3 weeks ago)
Author:
Claude (agent) <aiclaude@…>
Branches:
main
Children:
22d2dba5
Parents:
520c993
git-author:
Robin <roboburr@…> (08/20/2026 02:56:12 AM)
git-committer:
Claude (agent) <aiclaude@…> (08/20/2026 07:25:24 AM)
Message:

proef: lenis ook op touch

Location:
src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/assets/css/style.css

    r520c993 rc581e5e  
    25562556   -- want welke van de twee prettiger leest hangt af van wat je schrijft. */
    25572557body[data-reader-pages="1"] .feed-reader .read-post { min-height: 100svh; }
     2558/* OP MOBIEL ALTIJD, wat de instelling ook zegt (Robin, 20-8). Op een telefoon is
     2559   een bericht per scherm de vorm die werkt -- je veegt van bericht naar bericht.
     2560   Op desktop blijft het een keuze, want daar lees je in een kolom naast veel
     2561   witruimte en is een doorlopende stroom vaak prettiger. */
     2562@media (hover: none) and (pointer: coarse) {
     2563    .feed-reader .read-post { min-height: 100svh; }
     2564}
    25582565
    25592566/* Een lijn tussen twee berichten: zonder grens is een stroom een lange brij. */
  • src/assets/js/mod/read.js

    r520c993 rc581e5e  
    143143 */
    144144const OP_DESKTOP = window.matchMedia('(hover: hover) and (pointer: fine)');
     145// PROEF (20-8): Lenis ook op touch. Robin meldde op mobiel drie dingen -- de
     146// header niet zichtbaar bij laden, snappen dat soms te ver gaat, en horizontaal
     147// kunnen scrollen. De eerste twee komen van de NATIVE snap: die vangt al bij het
     148// laden, en zijn uitloop vliegt bij een flick over een grens heen. Lenis zet de
     149// native snap uit en doet het zelf, dus die twee kunnen ermee verdwijnen.
     150//
     151// De prijs is echt: syncTouch betekent dat Lenis het VINGERSCROLLEN overneemt
     152// van iOS -- momentum, rubber-band en het wegschuiven van de adresbalk worden
     153// dan een benadering in JavaScript. De makers waarschuwen daar zelf voor op
     154// iOS < 16. Dit staat er dus als proef, niet als besluit: voelt het niet goed,
     155// dan is OP_TOUCH weer false zetten de hele terugweg.
     156const OP_TOUCH = window.matchMedia('(hover: none) and (pointer: coarse)');
    145157const VENDOR_V = 1;   // ophogen als de bestanden in /assets/js/vendor wijzigen
    146158
     
    149161
    150162async function startLenis() {
    151   if (lenis || !OP_DESKTOP.matches) return;
     163  if (lenis || !(OP_DESKTOP.matches || OP_TOUCH.matches)) return;
    152164  const [L, S] = await Promise.all([
    153165    import(`/assets/vendor/lenis.mjs?v=${VENDOR_V}`),
     
    165177    smoothWheel: true,
    166178    lerp: 0.2,
    167     syncTouch: false,   // op touch blijft alles van het systeem
     179    // Alleen op touch overneemt hij het vingerscrollen; op desktop hoeft dat niet.
     180    syncTouch: OP_TOUCH.matches,
     181    // TOUCH-SPECIFIEK, want de standaardwaarden voelen op een telefoon traag.
     182    //
     183    // Waar dat zit is precies aan te wijzen. In Lenis staat
     184    // `lerp: d ? syncTouchLerp : 1`, waarbij d "de vinger is net losgelaten"
     185    // betekent. Tijdens het SLEPEN is de lerp dus 1 -- de inhoud volgt je vinger
     186    // exact, net als iOS, en daar is niets mis mee. De traagheid zit in de glijder
     187    // NA het loslaten: die gebruikt syncTouchLerp, en dat staat standaard op
     188    // 0.075. Dat dempt zo langzaam uit dat de pagina nog seconden naijlt.
     189    //
     190    // TWEE KNOPPEN, en ze doen iets anders -- dat verwarde ik eerst:
     191    //
     192    //   touchInertiaMultiplier   hoe VER een veeg je brengt
     193    //   syncTouchLerp            hoe snel de glijder UITDEMPT
     194    //
     195    // Eerste ronde zette ik de multiplier op 25 (korter dan de standaard 35),
     196    // omdat ik "te traag" las als "hij ijlt te lang na". Robin bedoelde het
     197    // omgekeerde: een veeg moet je VERDER brengen, zoals op iOS -- daar draagt
     198    // een flick een heel eind. Dus juist omhoog, ruim boven de standaard.
     199    //
     200    // De lerp gaat mee terug naar 0.1: tussen de trage standaard (0.075, dat
     201    // seconden naijlt) en de kordate 0.15 in. Met een langere weg af te leggen
     202    // mag de demping wat zachter, anders komt hij te abrupt tot stilstand.
     203    // Waar we na een paar rondes proberen op uitkwamen, met de betekenis erbij
     204    // omdat de tweede knop contra-intuitief is:
     205    //
     206    //   touchInertiaMultiplier 70   hoe VER een veeg draagt (standaard 35).
     207    //                               25 en 45 waren allebei te kort.
     208    //   syncTouchLerp 0.05          hoe snel hij zijn doel BENADERT. Hoger = eerder
     209    //                               aankomen en dus abrupt stoppen; LAGER = langer
     210    //                               onderweg blijven. Robin: "te stroef bij het
     211    //                               loslaten, mag echt een tijdje doorscrollen".
     212    //                               Dus omlaag, niet omhoog -- 0.15 en 0.1 kapten
     213    //                               de uitloop af.
     214    // syncTouchLerp 0.25: VIER KEER de vorige waarde, en ruim boven de standaard
     215    // van 0.075. Ik heb hem vier rondes lang de verkeerde kant op gedraaid omdat
     216    // ik "stroef" las als "hij stopt te vroeg" -- maar het betekende STROPERIG.
     217    // Een lage lerp benadert het doel langzaam en geeft dus een kruipende
     218    // uitloop; hoog betekent er vlot naartoe. Met de multiplier op 70 blijft de
     219    // AFSTAND groot, dus je gaat ver EN snel: dat is hoe een flick op iOS voelt.
     220    //
     221    // Kort samengevat, want dit is twee keer misgegaan:
     222    //   syncTouchLerp hoger  = sneller weg, korter narollen
     223    //   multiplier hoger     = verder komen
     224    ...(OP_TOUCH.matches ? { syncTouchLerp: 0.25, touchInertiaMultiplier: 70 } : {}),
    168225    autoRaf: true,
    169226  });
     
    171228    type: 'proximity',
    172229    distanceThreshold: '12%',   // de vangzone, hier WEL instelbaar
    173     debounce: 60,               // niet de standaard 500: dat voelt als te laat
    174     duration: 0.4,              // in totaal onder de halve seconde
     230    // Hoe lang na de laatste scrollbeweging hij mag vangen. De standaard is 500
     231    // en dat voelt als te laat. Op touch nog korter dan op desktop, want daar
     232    // eindigt een veeg in een lange, trage staart -- en juist dan wil je dat de
     233    // snap er snel bij is in plaats van te wachten tot de laatste pixel stil ligt.
     234    //
     235    // LET OP DE SPANNING: een vloeiendere uitloop (lagere syncTouchLerp) maakt
     236    // die staart langer, en stelt de snap dus uit. Deze twee getallen houden
     237    // elkaar in evenwicht; draai je aan de een, kijk dan ook naar de ander.
     238    // OP TOUCH JUIST LANG, en dat is het omgekeerde van wat ik vorige ronde deed.
     239    // Tussen je vinger loslaten en het op gang komen van de uitloop zit een korte
     240    // stilte in de scrollbeweging. Met 25ms viel de snap precies in dat gat: hij
     241    // greep op het moment van loslaten en knipte de veeg af -- wat aanvoelt als
     242    // "stroef bij het loslaten", en het werd er dan ook erger van. 200ms laat de
     243    // uitloop eerst zijn werk doen.
     244    debounce: OP_TOUCH.matches ? 200 : 60,
     245    // Op touch korter: een telefoon vraagt om directer antwoord dan een muis, en
     246    // de snap komt daar aan het eind van een lange uitloop -- dan mag hij kort.
     247    duration: OP_TOUCH.matches ? 0.18 : 0.4,
    175248    // Vlot weg, dan steeds langzamer aankomen (Robin, 20-8). easeOutQuart: op de
    176249    // helft van de tijd is 94% van de weg af, en de rest dempt zacht uit.
  • src/services/i18n.js

    r520c993 rc581e5e  
    3333    'switch.solo': 'Solo',
    3434    'switch.circle': 'Cirkels',
    35     'switch.grid': 'Grid', 'switch.reader': 'Lezen', 'switch.timeline': 'Tijdlijn', 'read.to_top': 'Terug naar boven', 'read.pinned': 'Vastgepind', 'asite.reader_full_page': 'Lezen: elk bericht een eigen scherm',
     35    'switch.grid': 'Grid', 'switch.reader': 'Lezen', 'switch.timeline': 'Tijdlijn', 'read.to_top': 'Terug naar boven', 'read.pinned': 'Vastgepind', 'asite.reader_full_page': 'Lezen op desktop: elk bericht een eigen scherm (op mobiel altijd)',
    3636    'asite.feed_alt': 'Tweede weergave', 'asite.feed_alt_reader': 'Lezen', 'asite.feed_alt_timeline': 'Tijdlijn', 'asite.feed_alt_auto': 'Lezen op mobiel, Tijdlijn op desktop',
    3737    'switch.reader_solo_only': 'Lezen kan alleen in Solo — in de cirkel staan berichten van anderen',
     
    10491049    'switch.solo': 'Solo',
    10501050    'switch.circle': 'Circles',
    1051     'switch.grid': 'Grid', 'switch.reader': 'Reader', 'switch.timeline': 'Timeline', 'read.to_top': 'Back to top', 'read.pinned': 'Pinned', 'asite.reader_full_page': 'Reader: one screen per post',
     1051    'switch.grid': 'Grid', 'switch.reader': 'Reader', 'switch.timeline': 'Timeline', 'read.to_top': 'Back to top', 'read.pinned': 'Pinned', 'asite.reader_full_page': 'Reader on desktop: one screen per post (always on mobile)',
    10521052    'asite.feed_alt': 'Second view', 'asite.feed_alt_reader': 'Reader', 'asite.feed_alt_timeline': 'Timeline', 'asite.feed_alt_auto': 'Reader on mobile, Timeline on desktop',
    10531053    'switch.reader_solo_only': 'Reader is Solo only — a circle shows other people\u2019s posts',
     
    20562056    'switch.solo': 'Solo',
    20572057    'switch.circle': 'Zirkel',
    2058     'switch.grid': 'Raster', 'switch.reader': 'Lesen', 'switch.timeline': 'Zeitleiste', 'read.to_top': 'Nach oben', 'read.pinned': 'Angeheftet', 'asite.reader_full_page': 'Lesen: ein Bildschirm pro Beitrag',
     2058    'switch.grid': 'Raster', 'switch.reader': 'Lesen', 'switch.timeline': 'Zeitleiste', 'read.to_top': 'Nach oben', 'read.pinned': 'Angeheftet', 'asite.reader_full_page': 'Lesen am Desktop: ein Bildschirm pro Beitrag (mobil immer)',
    20592059    'asite.feed_alt': 'Zweite Ansicht', 'asite.feed_alt_reader': 'Lesen', 'asite.feed_alt_timeline': 'Zeitleiste', 'asite.feed_alt_auto': 'Lesen mobil, Zeitleiste am Desktop',
    20602060    'switch.reader_solo_only': 'Lesen gibt es nur in Solo — im Zirkel stehen Beitr\u00e4ge anderer',
  • src/views/shell.ejs

    r520c993 rc581e5e  
    222222
    223223<!-- v9 stylesheet (full palette system) -->
    224 <link rel="stylesheet" href="/assets/css/style.css?v=83">
     224<link rel="stylesheet" href="/assets/css/style.css?v=84">
    225225<script>
    226226/* iOS safe-area, built by hand. env(safe-area-inset-top) resolves to 0 on this iOS in
     
    505505  // Eén nummer voor de hele map. Te vaak bumpen kost één download; te weinig
    506506  // bumpen kost een bugfix die nooit aankomt.
    507   var MOD_V = 21;
     507  var MOD_V = 29;
    508508
    509509  // name -> 1 (aan het laden) of de module-namespace (geladen). Een module
Note: See TracChangeset for help on using the changeset viewer.