player icon indicating copy to clipboard operation
player copied to clipboard

Plyr's clickToPlay is triggered when scrolling on mobile

Open ciriousjoker opened this issue 2 months ago • 0 comments

Current Behavior:

Scrolling on mobile pauses the video.

Expected Behavior:

Scrolling on mobile shouldn't trigger play/pause behavior.

Steps To Reproduce:

Sample code
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
    <title>Vidstack + Plyr layout · Mobile demo</title>

    <!-- Plyr layout styles from Vidstack CDN -->
    <link rel="stylesheet" href="https://cdn.vidstack.io/player.css" />
    <link rel="stylesheet" href="https://cdn.vidstack.io/plyr.css" />

    <!-- Register Vidstack web components with Plyr layout via CDN -->
    <script src="https://cdn.vidstack.io/player" type="module"></script>

    <!-- NOTE: With this import, it works, but clickToPlay doesnt work at all. -->
    <!-- <script src="https://cdn.vidstack.io/plyr" type="module"></script> -->

    <script src="https://cdn.vidstack.io/icons" type="module"></script>
  </head>
  <body>
    <div style="height: 512px"></div>

    <video id="target"></video>

    <div style="height: 512px"></div>
    <div style="height: 512px"></div>

    <script type="module">
      import { PlyrLayout, VidstackPlayer } from "https://cdn.vidstack.io/player";

      const player = await VidstackPlayer.create({
        target: "#target",
        title: "Sprite Fight",
        src: "https://files.vidstack.io/sprite-fight/720p.mp4",
        layout: new PlyrLayout({
          controls: ["play-large", "play", "progress", "mute+volume", "fullscreen"],
          clickToPlay: true,
          // clickToPlay: false,
          clickToFullscreen: true,
        }),
        playsInline: true,
        load: "eager",
      });
    </script>
  </body>
</html>

Environment:

Anything Else?

    <script src="https://cdn.vidstack.io/player" type="module"></script>

    <!-- NOTE: With this import, it works, but clickToPlay doesnt work at all. -->
    <!-- <script src="https://cdn.vidstack.io/plyr" type="module"></script> -->

This is particularly annoying on Angular, since the docs tell you to import from vidstack/global/player and that vidstack/global/plyr is just for compatibility without any functional changes. Importing from vidstack/global/plyr is the same as https://cdn.vidstack.io/plyr.

Either way, the fix would probably be to react to clicks instead of pointerup, since pointerup counts as a click when scrolling the videoplayer.

<media-gesture class="plyr__gesture" event="pointerup" action="toggle:paused"></media-gesture>

I have no idea how to reproduce this in an Angular build, since I cannot import the cdn stuff there and using the old Plyr() constructor has other issues, like having native video controls permanently visible...

ciriousjoker avatar Oct 20 '25 01:10 ciriousjoker