Yes, we use a Joy-Con to change slides. Here's how… | HTTP 203

Поділитися
Вставка
  • Опубліковано 12 вер 2024
  • Jake and Surma use a Joy-Con as a slide clicker because they're cheapskates. Here's how it works, and the coding patterns they use.
    Final code → goo.gle/304bT0L
    Why passing Boolean to filter makes Jake nervous → goo.gle/3bWg29r
    Gamepad tester → goo.gle/3D07GK0
    Spec change to add events → goo.gle/3qhmi4d
    When Jake and Surma did MULTIPLAYER slide clickers → goo.gle/3j8xeNI
    Haptic actuators, touch pads, and 'pose' in the gamepad extensions API → goo.gle/3kgz4vJ
    More videos in the HTTP 203 series → goo.gle/HTTP203
    Subscribe to Google Chrome Developers here → goo.gle/Chrome...
    Also, if you enjoyed this, you might like the HTTP203 podcast → goo.gle/HTTP20...
    #HTTP203 #ChromeDeveloper #WebDev

КОМЕНТАРІ • 73

  • @EmNudge
    @EmNudge 2 роки тому +60

    Fun fact, most slide clickers are just keyboards with a PageUp and PageDown button. Had to add event listeners for those to make them work with them for my JS slides library.

    • @jakearchibald
      @jakearchibald 2 роки тому +9

      Yep! Remote controls for camera phones operate in exactly the same way. Or at least, the one that came with the selfie-stick I bought works in that way (yes I bought a selfie stick, don't judge me, it was for a charity thing)

    • @sharedgametimer
      @sharedgametimer 2 роки тому +2

      @@jakearchibald Really? I find most selfie clickers to mimic Volume buttons, and struggling to capture those in JS. I've tried. Can hack it on android using Tasker, but iOS is hopeless. Windows I think works.

  • @KylePolansky
    @KylePolansky 2 роки тому +14

    "Wait a minute. What are you guys using to advance the slides? Is that a JoyCon?"

  • @wmhilton-old
    @wmhilton-old 2 роки тому +22

    Very cool! I'm totally gonna add random gamepad Easter eggs to my websites now.

  • @ColinRichardson
    @ColinRichardson 2 роки тому +34

    I actually have a bug open with Chromium for the Gamepad API.. My hardware had more than 32 buttons.. But Chrome has limited it to 32. Matt Reynolds was originally looking at this.. but I think he has fallen asleep and nothing has moved about this...
    If you wanna give him a poke for me, that would be great

    • @jakearchibald
      @jakearchibald 2 роки тому +5

      What's the bug number?

    • @ColinRichardson
      @ColinRichardson 2 роки тому

      @@jakearchibald bug number 1245013
      I had originally thought it was an OS limitation. But noticed it works with Firefox

  • @rishabhanand4270
    @rishabhanand4270 2 роки тому +9

    while (true) do look scary. I mean imagine having couple of those in a project, and if something goes wrong, even though irrelevant, people would think about them. It took me a "while" to get used to them while doing redux saga implementations.

    • @31redorange08
      @31redorange08 2 роки тому

      Rust has the keyword `loop` for infinite loops.

  • @SamuelSarette
    @SamuelSarette 2 роки тому +2

    The biggest pain with the button presses not having an event, is that you can't use them as user gesture for sound activation

  • @chinmayk8004
    @chinmayk8004 2 роки тому +4

    The director's cut makes me wanna go back and see the thumbnail :)

  • @BobFrTube
    @BobFrTube 2 роки тому +3

    The API I really want is a "TV" type remote control and, more importantly, one that is adopted by the streaming services. This would transform how we watch content (AKA watch TV) because the browser UX is far better than the specialized smart TV boxes which must be priced low -- we can't buy to maximize value.

    • @jakearchibald
      @jakearchibald 2 роки тому +3

      I did some work on set top boxes once and the remote was exposed as a keyboard. Is this what you mean, or are you talking about spatial navigation too?

    • @BobFrTube
      @BobFrTube 2 роки тому +1

      ​@@jakearchibaldYes, I should've emphasized that the real issue is indeed spatial navigation.
      I'm curious about your STB experience and why they aren't just browser engines. I know it used to be price but the value/price ratio has changed.
      The simple observation is that while a browser allows for a far better viewing experience than a traditional smart TV or external box (Roku, Android TV, etc.), adoption is hobbled by the difficulty in using a small pointer to navigate from the couch, especially using a remote. I should be able to use the arrow keys as a super-tab going to the next item in the appropriate direction as with the STBs. It seems trivial but navigation is everything. Google is in the position to establish a convention such as a directional tab (with a JS shim). I believe it would be quickly adopted in streaming browser apps.
      Having an IR or BT shim for existing controllers would be nice but simply having a convention would encourage a new generation of controllers as well as apps in smartphones as controllers. Apps have other advantages such as a keyboard when I need it.
      This is a bit long for a UA-cam comment, but I can go into more detail in email if you’re interested. I’ve also written about this in my column in the IEEE Consumer Electronics Magazine.

    • @jakearchibald
      @jakearchibald 2 роки тому +1

      @@BobFrTube I don't have a ton of knowledge here, but I'm pretty sure Chromium has some kind of spatial navigation system, as LG contributed it for their WebOS TV UI

    • @dassurma
      @dassurma 2 роки тому +1

      I think Presentation API wanted to solve this. Not sure if that is still being pursued tho.

    • @BobFrTube
      @BobFrTube 2 роки тому

      @@dassurma I looked at the API and, while it has been around for a while it doesn't seem to have much activity.

  • @lucacasonato
    @lucacasonato 2 роки тому +4

    So Jake, awesome animation!

  • @sokrates297
    @sokrates297 2 роки тому +13

    Cool slide animations, absolutely love them! but how does that Joy-Con controller work to change slides?? 🤔

  • @CarlStrumpfer
    @CarlStrumpfer 2 роки тому +1

    Interesting to see the interlacing (vertical lines) on this video. It's especially apparent when Jake waves his hands around. Hard to imagine why this would show up.

    • @jakearchibald
      @jakearchibald 2 роки тому +1

      See the other comments about this

  • @hblahbl
    @hblahbl 2 роки тому +1

    Promisified request anim frame and while true loop look nice together, much more readable than recursion calls

  • @jonathan-._.-
    @jonathan-._.- 2 роки тому +2

    oO the state.map(()=>false) seems kinda weird
    i mean you could jsut use an empty array and it has the same effect (less readable tho)
    I'd prefer new Array(state.length).fill(false)

    • @jakearchibald
      @jakearchibald 2 роки тому +1

      I mention in the episode that relying on undefined might be ok, but I got into the habit of using correct types through TypeScript. As for Array(state.length)… that works too, but if possible I try to avoid code that involves a holey array at any point.

  • @SmujMaiku
    @SmujMaiku 2 роки тому

    0:36 That was me! I did that once! I did go out and hobbled my own solution in a chrome extension last year. I'll be interested to see gyro/accel support added, that would be great

  • @andydwd
    @andydwd 2 роки тому +1

    I wonder if it would be possible to do something similar with Oculus Quest controllers and then use them in web VR

  • @Surefire99
    @Surefire99 2 роки тому +2

    Suppose you're creating a buzz-in style trivia game and you want to see who buzzed in first. Running on a 60Hz system you'll poll at less than .01 second resolution. So for good players there would be a significant chance that it looks like they buzzed in at the same time when really there could be over a 16ms difference. And there would be no actual way to determine this other than polling faster than RAF. Do I have that right? So then the question becomes how do you handle ties? it seems like the first device connected would always win the tie breaker because they would come first in the loop. Now I'm curious how video game consoles handle this.

    • @jakearchibald
      @jakearchibald 2 роки тому +3

      This is why we need a proper events based system, since events have a timestamp. Gamepads have a last-updated timestamp, but of course that might not match up with the button.

  • @MagicProductNews
    @MagicProductNews 2 роки тому +1

    What software is used to make the slide decks?

  • @dustinpoissant
    @dustinpoissant 2 роки тому +2

    They should make an API that allows us to use out phone (browser) as a bluetooth controller for another device

    • @TheNewton
      @TheNewton 2 роки тому

      Exactly what I'm looking for, make my phone a mouse accessory, remote control for video/music, or a 9keypad for laptops. Etcetera

    • @jakearchibald
      @jakearchibald 2 роки тому +1

      I don't think it's possible without a server to bridge the gap between the phone and the other device, and I don't imagine folks would be happy with all their clicks being sent via a Google server.

    • @SirusStarTV
      @SirusStarTV 2 роки тому

      I wanted to use my phone as Bluetooth gamepad and there was an app for that on google play but it's paid :(
      But later found out that the android TV that i have doesn't support bluetooth, even if i had real bluetooth gamepad i wouldn't be able to connect.

    • @akauppi2
      @akauppi2 2 роки тому

      I think that exists. Maybe not as any kind of controller, but serial over Bluetooth.

  • @chasejohnson7686
    @chasejohnson7686 2 роки тому

    7:10 Why do I often see the pattern in HTTP 203 that passing callbacks of just functions are wrapped in another lambda like `() => f()` instead of just `f`

  • @Martin958
    @Martin958 Рік тому

    Hello, do you know if this method of using the Gamepad API could help to isolate out aimbots and cheat buttons? Even if those buttons are disguised as normal inputs by physically modding the controller?

  • @ManuelsWorld
    @ManuelsWorld 2 роки тому +4

    I was just about to write, how did you do these animations?

    • @jakearchibald
      @jakearchibald 2 роки тому +4

      hah! We might do an episode of that at some point

  • @mikem0898
    @mikem0898 2 роки тому +1

    Very good and pragmatic introduction to the API, however I don't think I understood why would we want to await for a new frame (looking at the code without any context of how it's used) - especially why it's located between gamepad "discovery" and it's input processing

    • @JonnyPowell
      @JonnyPowell 2 роки тому +1

      if a gamepad is connected, gamepads.length !== 0, so the whole loop would become a tight loop (which is why they said while(true) might be scary) and just lock up the UI. That await means this loop runs at most once per frame. The pre-async alternative would be a refactor where all this code is inside a function which recursively calls requestAnimationFrame, which might be what you’re used to. The context you’re asking for is just that this code is called from the main thread.

    • @mikem0898
      @mikem0898 2 роки тому

      @@JonnyPowell Thank you for your comprehensive answer - what threw me off was indeed awaiting on the next frame request (instead of recurisve calling with callback) and that it's just a way to break the while(true) from blocking the event loop - I guess I just took too much interest in "why next frame exactly and in that place in code" instead of asking myself "how not to block the thread on that while(true)?"

    • @Surefire99
      @Surefire99 2 роки тому

      @@JonnyPowell so the requestAnimationFrame isn't required? It's just a method to throttle poling to something reasonable?

    • @jakearchibald
      @jakearchibald 2 роки тому +3

      It's polling. You need to wait on something async else you'll block any further rendering in the tab, essentially locking it up. requestAnimationFrame is an ideal way to yield back to rendering.
      Also, I think the gamepad API is designed to be polled by raf. Imagine you pressed and released a button between frames - I think browsers persist that button down until the next frame, but it isn't really covered by the spec.

  • @davilinkicefire
    @davilinkicefire 2 роки тому +1

    Nice video. I was wondering if you did consider the WebHID API, it look more like you want, Event driven API instead of pulling API.

    • @jakearchibald
      @jakearchibald 2 роки тому +6

      I haven't played with WebHID yet. However, the gamepad API has much better browser support, so it seems like a better fit for this use-case.

  • @dustinpoissant
    @dustinpoissant 2 роки тому +1

    Nice episode, i assuing some librbaries with come out soon that fix this api

    • @jakearchibald
      @jakearchibald 2 роки тому

      See the description for the code in this episode

  • @chinmayk8004
    @chinmayk8004 2 роки тому +1

    Now, how about the presentation itself?

  • @rinodrummer-dev
    @rinodrummer-dev 2 роки тому +1

    I just have a question: what are the `await new Promise()` for?
    I mean, why? And what will the resolve callback be?

    • @IceMetalPunk
      @IceMetalPunk 2 роки тому +6

      Since it's in an async function, it will pause the function (including pausing the loop) until the promise resolves. The Promise constructor takes a callback which has two arguments, also callbacks: the resolve callback and the reject callback. In this case, they're just calling the resolve callback, with no arguments, when a gamepad is connected. So that promise will only resolve once a gamepad is connected, and until then, the outer async function will just pause and wait without blocking anything outside itself.

    • @jakearchibald
      @jakearchibald 2 роки тому +4

      There are two of them in this code. It causes the async function to pause until the promise resolves. The first one waits for an event ("gamepadconnected"), the second one waits for requestAnimationFrame

    • @jakearchibald
      @jakearchibald 2 роки тому +1

      Here's a guide on async/await in general developers.google.com/web/fundamentals/primers/async-functions

  • @avi12
    @avi12 2 роки тому

    Could it work for Oculus Touch controllers?

  • @samuel.00
    @samuel.00 2 роки тому +3

    what's up with the interlaced video

    • @jakearchibald
      @jakearchibald 2 роки тому +1

      I replied to another comment on this with a bit more detail. Like we kinda suggest in the intro, this was a cursed recording session with all kinds of problems.

  • @octubre_lilaka
    @octubre_lilaka 2 роки тому

    This is also possible with webHID, right?

  • @TheZarlo
    @TheZarlo 2 роки тому

    is it me or are parts of the video interlaced?

    • @jakearchibald
      @jakearchibald 2 роки тому +4

      Yes, ugh, I noticed this too on the wide shot, but apparently it couldn't be fixed. This was a cursed day of recording. We recorded 5 episodes and 3 were lost due to equipment failures, and the remaining two have some weirdness. So frustrating. We're back in the studio soon to rerecord the other three soon.

  • @TheNewton
    @TheNewton 2 роки тому

    Suggestions for simplest method to use a smartphone for this?

    • @jakearchibald
      @jakearchibald 2 роки тому

      There are apps that turn your phone into a gamepad, but they require a server component on the PC. Last time I did this myself, I used a websocket server.

  • @MrMagic1163
    @MrMagic1163 2 роки тому

    Unfortunately steam controllers don't work with this :(

  • @YOUTUBEACEHBERDIKARI
    @YOUTUBEACEHBERDIKARI 2 роки тому

    Luar biasa👌👌👍

  • @jonathan-._.-
    @jonathan-._.- 2 роки тому

    if there werent any gamepads and then once connects the gamepads variable should still be an empty array

    • @31redorange08
      @31redorange08 2 роки тому

      But in the next iteration it's not.

    • @jonathan-._.-
      @jonathan-._.- 2 роки тому

      @@31redorange08 yeah but they were like "we know we have at least one ... ua-cam.com/video/pIIHJ-NIyes/v-deo.html

    • @31redorange08
      @31redorange08 2 роки тому +2

      @@jonathan-._.- Oh, yeah. At least none would've been correct. 😀

    • @jakearchibald
      @jakearchibald 2 роки тому

      Yeah, that's fair, it may have disconnected while waiting for the frame.

    • @31redorange08
      @31redorange08 2 роки тому

      @@jakearchibald That's not the point. The array is still empty after the event fired. There's no mutating access to it.

  • @jonathan-._.-
    @jonathan-._.- 2 роки тому

    sha(brand + id )

  • @himanshupant1546
    @himanshupant1546 2 роки тому +3

    I am one of those people who comment. Hehehehe, I planned this.