使用文字掩盖视频 [英] Using text to mask a video

查看:51
本文介绍了使用文字掩盖视频的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以使用HTML / CSS文本掩盖视频?我已经找到并设置了这种工作方式,但是没有一种方法允许在文本后面提供透明背景。

Is it possible to use HTML/CSS text to mask a video? I've found and set up ways that sort of work, but none allow for a transparent background behind the text.

例如,这支笔需要您进行某种操作

For example, this pen requires you to have some sort of fill, where it isn't really masking the actual video, but creating the illusion.

https://codepen.io/dudleystorey/pen/QvvEYQ

如果您更改

body {
  background: white;
  margin: 2rem;
}

body {
  background: black;
  margin: 2rem;
}

您会看到它只是一个白色填充,且填充有遮罩,而不是视频。
也许只有在画布上才有可能吗?

You'll see that it's just a white fill with a mask on the fill, not the video. Perhaps this is possible only in canvas?

推荐答案

是的,使用< a href = https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation rel = noreferrer>合成和渲染循环:

Yes, you can achieve it with canvas quite easily, using compositing and a rendering loop:

var vid = document.createElement('video');
vid.onerror = function() {
  vid.onerror = null;
  vid.src = "http://thenewcode.com/assets/videos/ocean-small.mp4";
};
vid.src = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/ocean-small.webm"
vid.muted = true;
vid.onloadedmetadata = initCanvas;
vid.loop = true;
vid.play();

function initCanvas() {
  var canvas = document.createElement('canvas');
  var vWidth = vid.videoWidth;
  var vHeight = vid.videoHeight;
  var ctx = canvas.getContext('2d');
  // we need to handle the resizing of our canvas ourselves...
  window.onresize = function() {
    canvas.width = window.innerWidth;
    canvas.height = (vHeight / vWidth) * canvas.width;
    var fontSize = (vWidth / 2 * (window.innerWidth / vWidth)) * 0.35;
    ctx.font = '700 ' + fontSize + 'px Impact,sans-serif';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
  };
  onresize();
  
  document.body.appendChild(canvas);
  draw();
  
  function draw() {
    // first draw our video frame
    ctx.drawImage(vid, 0,0, canvas.width, canvas.height);
    // set the composite mode
    ctx.globalCompositeOperation = 'destination-in';
    // will remove every pixels that are not where new pixels will come
    ctx.fillText('OCEAN', canvas.width / 2, canvas.height / 2);
    // reset the normal compositing mode
    ctx.globalCompositeOperation = 'source-over';
    // do it again at next screen refresh
    requestAnimationFrame(draw);
  }
}

body {
  background: linear-gradient(45deg, white 0%, blue 100%) no-repeat;
}

但这可能不是性能和可伸缩性方面的最佳解决方案。

But that may not be the best solution in term of performances and scalability.

您应该能够应用相同的svg < mask> 您在< video> 元素上使用的(进行了一些修改),但似乎仍未广泛支持HTML内容上的SVG掩码(Firefox接受它,Chrome浏览器不会...)。

You should be able to apply the same svg <mask> you were using on your <video> element (with some modifications), but it seems SVG masks over HTML content is still not widely supported (Firefox accepts it, Chrome doesn't...).

body {
  background: linear-gradient(45deg, white 0%, blue 100%);
}
svg{
  font-family: impact, sans-serif;
}
video {
  -webkit-mask: url(#mask);
  mask: url(#mask);
  width: 100%;
  position: absolute;
  z-index: 1;
}

<svg width="0" height="0" style="position:absolute;z-index:-1">
  <defs>
    <mask id="mask" x="0" y="0" maskContentUnits="objectBoundingBox" maskUnits="objectBoundingBox" width="100%" height="100%">
      <text fill="white" x="0.5" y="0.5" style="font-weight:700" font-size="0.22" text-anchor="middle" alignment-baseline="middle">OCEAN</text>
    </mask>
  </defs>
</svg>
<video autoplay playsinline muted loop preload poster="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/oceanshot.jpg">
  <source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/ocean-small.webm" />
  <source src="http://thenewcode.com/assets/videos/ocean-small.mp4" />
</video>

因此,更好的解决方案可能是使用SVG < clipPath> 似乎比CSS 具有更好的浏览器支持遮罩

So a better solution might be to use an SVG <clipPath> which seems to have better browser support than CSS mask.

body {
  background: linear-gradient(45deg, white 0%, blue 100%);
}
svg{
  font-family: impact, sans-serif;
}
video {
  -webkit-clip-path: url(#clip);
  clip-path: url(#clip);
  width: 100%;
  position: absolute;
  z-index: 1;
}

<svg style="opacity:0;position:fixed;z-index:-999" viewBox="0 0 1 1">
  <defs>
    <clipPath id="clip" clipPathUnits="objectBoundingBox">
      <text x="0.5" y="0.5" font-size="0.22" text-anchor="middle" alignment-baseline="middle">OCEAN</text>
    </clipPath>
  </defs>
</svg>
<video autoplay playsinline muted loop preload poster="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/oceanshot.jpg">
  <source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/ocean-small.webm" />
  <source src="http://thenewcode.com/assets/videos/ocean-small.mp4" />
</video>

请注意,我也不是完全不知道css clipPath的浏览器支持,因此对于某些浏览器,您可能必须使用画布。

这篇关于使用文字掩盖视频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆