【问题标题】:Why is placing an html5 canvas over a video not covering the video, instead the canvas shows no colored background, video freezes to a single frame为什么将 html5 画布放在不覆盖视频的视频上,而不是画布显示没有彩色背景,视频冻结为单帧
【发布时间】:2021-07-02 05:57:06
【问题描述】:

我希望你能给我几分钟的时间。我正在尝试实现一个深色背景画布来掩盖其背景中的视频,下面的代码应该能够通过填充样式和源来做到这一点,但由于某种原因它不是,你有一个想法如何解决这个问题?

let canvas = useRef(null);
    const size = useWindowSize();
    const { currentTheme } = useGlobalStateContext()

    useEffect(() => {
        let renderingElement = canvas.current;
        let drawingElement = renderingElement.cloneNode();

        let drawingCtx = drawingElement.getContext("2d");
        let renderingCtx = drawingElement.getContext("2d");

        let lastX;
        let lastY;

        let moving = false;

        renderingCtx.globalCompositeOperation = "source-over"
        renderingCtx.fillStyle = currentTheme === "dark" ? "#000000" : "#ffffff";
        renderingCtx.fillRect(0,0, size.width, size.height)
        console.log(renderingCtx)

    }, [])
  return (
    <Banner>
      <Video>
        <video
          height="100%"
          width="100%"
          loop
          autoPlay
          src={require("../../assets/video/video.mp4")}
        />
      </Video>
      <Canvas
        height={size.height}
        width={size.width}
        ref={canvas}
      />
      <BannerTitle variants={container} initial="initial" animate="animate">
        <Headline variants={item}>DIG</Headline>
        <Headline variants={item}>DEEP</Headline>
      </BannerTitle>
    </Banner>
  )
}

================================ 我正在使用样式化组件,

import styled from "styled-components"
import { motion } from "framer-motion"

//Banner
export const Banner = styled.div`
  background: ${props => props.theme.background};
  height: 100vh;
  width: 100%;
  position: relative;
  margin-bottom: 296px;
`
export const Video = styled.div`
  height: 100%;
  width: 100%;
  video {
    object-fit: cover;
  }
`
export const Canvas = styled.canvas`
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  display: block;
`

此代码块为画布应用深色背景,以便遮盖其背后的视频 但不是覆盖视频(屏幕会变暗,视频将在后台播放)而是显示其他内容

这是最终结果的图片

【问题讨论】:

  • 将z-index 属性应用于canvas,或者您可以在视频上使用filter 属性并将值设置为brightness(0)。它应该将整个视频涂成黑色MDN Filter
  • 嘿,如果你注意到我在我的 useEffect 中使用 globalCompositeOperation 设置为 source-over,这应该给我与 z-index 设置为更高属性相同的效果,但出于某种原因它不起作用,因此会发生两种效果,画布没有被绘制,视频像图像一样冻结(而不是播放)@a.mola
  • globalCompositeOperation 只影响没有东西被绘制到画布上的方式,而不影响它与其他元素的交互方式。视频是否在没有画布的情况下播放?
  • @a.mola,是的,它确实如此,它在没有画布的情况下播放,但是当画布放在它上面时,视频停止播放,而是显示该图像,这没关系如果我添加了z-index,仍然不起作用,brigthness(0) 似乎有效,但它使视频根本不显示。我希望画布在继续播放的同时覆盖视频。但这不起作用

标签: html reactjs canvas html5-video styled-components


【解决方案1】:

好吧,由于一些新的安全修复程序,视频的 autoplay 无法正常工作。 Read more 并且您需要在 HTMLMediaElement 上具有 muted 属性。

我在视频上创建了一个事件侦听器,以便在它开始播放时删除muted 属性。我传递了once 选项,因此事件将被调用一次。

const canvas = document.getElementById('canvas');
const video = document.getElementById('video');
const ctx = canvas.getContext('2d');


video.addEventListener('play', _ => {
  console.log('playing');
  canvas.width = getComputedStyle(video).width.slice(0, -2);
  canvas.height = getComputedStyle(video).height.slice(0, -2);
  ctx.fillRect(0, 0, canvas.width, canvas.height);
}, { once: true });
body {
  position: relative;
  height: 100vh;
  width: 100vw;
  display: flex;
  align-items: center;
  justify-content: center;
}

video {
  width: 75vw;
}

canvas {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
<video id="video" src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4" muted autoplay controls></video>
<canvas id="canvas"></canvas>

【讨论】:

  • 谢谢你,视频实际上又在播放了,现在唯一的问题是画布没有被创建或显示,在代码中画布应该覆盖整个视频黑色或白色取决于应用程序的主题,所以我们应该有一个黑色背景和它后面播放的视频(我们看不到后面播放的视频,但它应该,我们看到的只是一个黑色背景),它几乎就像创建的画布上下文不应用我分配的样式,我不想使用亮度或 z-index 属性,想法? @a.mola
  • 我已经编辑了我的代码,只需添加muted 属性@Irongatez
猜你喜欢
  • 1970-01-01
  • 2018-07-31
  • 2023-03-18
  • 1970-01-01
  • 2012-06-02
  • 2017-02-01
  • 2018-05-08
相关资源
最近更新 更多