0

我想将动画画布作为背景剪辑到<h1 />. 要求是:

  • 使用实际<h1 />标签而不是在画布中呈现标题。
  • 使用要渲染的图像ctx.drawImage()

h1 { 
  color: transparant;
  background-image: <some-canvas>;
  background-clip: text;
}

到目前为止,我尝试了几种方法并取得了不同的成功:

  • 创建一个常规画布并将其设置为<h1 />-tag 使用-webkit-canvas和的背景-moz-element。这种方法满足了我的所有要求,但不幸的是在 Chromium 中-webkit-canvas被弃用了。document.getCSSCanvasContext("2d")Safari 是唯一可用的浏览器。
  • 使用 CSS Paint API (Houdini)。使用 arequestAnimationFrame()更新 css var 我可以继续勾选动画并执行我想要实现的动画。但是,在 Chromium 中,必须使用解决方法来传递图像(而不是创建图像类型的属性,图像必须通过 using 来传递background-image,这使我无法使用background-image来告诉 CSS Paint 使用我的工作集作为背景。该规范并未完全实施。
  • 创建一个内联 svg 作为 background-image: url("data:image/svg+xml;utf8,<svg><foreignObject><canvas id='..'/></foreignObject></svg>");并尝试使用requestAnimationFrame. 根本不起作用。

我还有其他方法可以尝试吗?

4

1 回答 1

0

如果它不必a background-image,则可以将元素放在canvas元素内部,将and与h1元素的匹配,给它一个低于元素中文本的值,使其看起来在文本后面,就像一个背景。canvas widthheighth1z-indexh1

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

/*
  Set the dimensions of the canvas to 
  match the parent h1 element
----------------------------------------------------------*/
setCanvasSize();

// (and for demonstrative purposes, scale on window resize)
window.addEventListener('resize', setCanvasSize, false);

function setCanvasSize () {
  var _w = canvas.parentNode.clientWidth;
  var _h = canvas.parentNode.clientHeight;
  canvas.width = _w;
  canvas.height = _h;
  canvas.style.width = "'" + _w + "px'";
  canvas.style.height = "'" + _h + "px'";
}
/*--------------------------------------------------------*/

/*--------------------------------------------------------
  All this code below is just a ball animation borrowed from MDN
  to illustrate what I'm suggesting.
  
  Source: MDN 
  https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Advanced_animations 
*/
var raf;
var running = false;

var ball = {
  x: 100,
  y: 100,
  vx: 5,
  vy: 1,
  radius: 50,
  color: 'blue',
  draw: function() {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true);
    ctx.closePath();
    ctx.fillStyle = this.color;
    ctx.fill();
  }
};

function clear() {
  ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
  ctx.fillRect(0,0,canvas.width,canvas.height);
}

function draw() {
  clear();
  ball.draw();
  ball.x += ball.vx;
  ball.y += ball.vy;

  if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) {
    ball.vy = -ball.vy;
  }
  if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) {
    ball.vx = -ball.vx;
  }

  raf = window.requestAnimationFrame(draw);
}
   
if (!running) {
  raf = window.requestAnimationFrame(draw);
  running = true;
}

ball.draw();
/*--------------------------------------------------------*/
h1 {
  /* Important for positioning the span element */
  position: relative;
  
  /* Cosmetic/demonstrative */
  border: 2px solid red;
  height: 100%;
  text-align: center;
  color: red;
  font-size: 32px;
  font-family: Roboto,sans-serif;
  margin: 0 auto;
}

h1 span { 
  /* Vertically and horizontally center the text */
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
  
  /*
    Text will appear above canvas as long as its 
    z-index > canvas' z-index
  */
  z-index: 2;

}

h1 canvas {
  /* this will make the canvas appear behind the text */
  position: relative;
  z-index: 1; 
}
<h1>
  <span>Lorem Ipsum etc.</span>
  <canvas id="canvas"></canvas>
</h1>

无论如何只是一个想法,也许您可​​以尝试一下并扩展该想法以满足您的需求。我不是 100% 确定你在做什么,如果没有帮助,我很抱歉。

于 2021-07-17T00:55:28.680 回答