这真的很奇怪,当global alCompositeOperation为"source-top"时,它可以工作,但当global alCompositeOperation为""Destination-top""时,它失败了.似乎不同类型的单词不能一起显示.以下是代码片段.

window.requestAnimationFrame(draw);
let FirstTime=Date.now();
function draw(){
    var canvas = document.getElementById("myCanvas");
    const width_mid=canvas.width/2;
    const height_mid=canvas.height/2;
    var timeStamp=Date.now();
    var num=Math.floor((timeStamp-FirstTime)/300);
    if(num>15)
        return;
    var ctx = canvas.getContext("2d");

    ctx.font = "200px 华文行楷";
    ctx.textAlign="center";
    ctx.fillText("CHH算法网",width_mid,height_mid+40);
    // ctx.globalCompositeOperation='source-atop';
    ctx.globalCompositeOperation='destination-atop';
    ctx.beginPath();
    ctx.moveTo(0,300);
    ctx.quadraticCurveTo(70,100,200,70);
    var end_x=200;
    var bezier_x;
    for(var i=0;i<num;i++){
        if(i%2==0){
            end_x+=10;
            bezier_x=end_x+100;
        }
        else{
            end_x+=200;
            bezier_x=end_x-130;
        }
        ctx.quadraticCurveTo(bezier_x,i%2?100:100,end_x,i%2?70:280);
    }
    ctx.strokeStyle="white";
    ctx.lineWidth=200;
    ctx.stroke();
    window.requestAnimationFrame(draw);
}
body{
    background-color: rgb(255, 213, 0);
}
#btn{
    text-align: center;
    position: relative;
    left:40%;
    top:70px;
    width: 200px;
    height: 100px;
    border-radius: 200px;
    color:white;
    background-color: rgb(25, 99, 145);
    font-size: 30px;
    font-family:"Lucida Sans Typewriter";
    border:none;
}
#btn:hover{
    color:rgb(25, 99, 145);
    background-color: white;
}
<canvas id="myCanvas" width="1300px" height="300px"></canvas>

我修改了globalCompositeOperation,发现如果globalCompositeOperation是'destination-atop',只能显示一种类型的单词.我希望做的是用画笔作为橡皮擦擦,擦go 黄色,它下面的标题就会逐渐出现.

推荐答案

我不知道为什么你的问题仅限于Firefox,但这里的解决方案是简单地确保你的上下文在每次开始绘制时都是正确的reset.我发现在执行任何操作之前添加ctx.save(),在完成循环后添加ctx.restore()可以解决您的问题,尽管我不确定为什么它只适用于CH字母,而不适用于其他字符.无论哪种方式,这样做都是安全的,而且每个浏览器都支持它.不管怎样,这样做也是一个很好的做法,以确保您永远不会陷入不确定它所处状态的上下文中.

这种持久复合操作的另一个问题是,由于您没有将其重置为and you aren't clearing the canvas,因此该操作在技术上应用于存在already的像素.因此,最好做到这两点:清除你的背景和清除你的画布.在下面的代码片段中,我已经完成了这两个操作:

const canvas = document.getElementById( "myCanvas" );
const ctx = canvas.getContext( "2d" );
const width_mid = canvas.width / 2;
const height_mid = canvas.height / 2;

let time = null;
let useSourceAtop = false;

function draw( timeStamp ){

  if( time === null ) time = timeStamp;
  
  const num = Math.floor((timeStamp-time)/300);
  
  if( num  > 15 ) return;
  
  ctx.save(); // <- save the current state of your context - and since we have made no changes to it, this means save the current, reset context
  ctx.clearRect( 0, 0, canvas.width, canvas.height ); // <-- Clear the canvas so you don't draw over the same pixel (this could mess with things such as anti-aliasing as a 50% alpha pixel would continuously get printed, making it more opaque etc)
  ctx.font = "200px 华文行楷";
  ctx.textAlign = "center";
  ctx.fillText( "CHH算法网", width_mid, height_mid+40 );
  
  if( useSourceAtop ) ctx.globalCompositeOperation = 'source-atop';
  else ctx.globalCompositeOperation = 'destination-atop';
  
  ctx.beginPath();
  ctx.moveTo( 0, 300 );
  ctx.quadraticCurveTo( 70, 100, 200, 70 );
  
  let end_x = 200;
  let bezier_x;
  
  for( let i = 0; i < num; i++ ){
  
      if( i%2 == 0 ){ 
      
          end_x += 10;
          bezier_x = end_x + 100;
          
      } else {
      
          end_x += 200;
          bezier_x = end_x - 130;
          
      }
      
      ctx.quadraticCurveTo(
        bezier_x,
        i%2 ? 100 : 100,
        end_x,
        i%2 ? 70 : 280
      );
      
  }
  
  ctx.strokeStyle = "white";
  ctx.lineWidth = 200;
  ctx.stroke();
  ctx.restore(); // <-- reset any changes made to your context, like globalCompositeOperation, transforms, lineWidths, colors, etc... to the last time you saved them.
    
  window.requestAnimationFrame( draw );

}

window.requestAnimationFrame( draw );

document.addEventListener( 'dblclick', event => {
  
  event.preventDefault();
  useSourceAtop = !useSourceAtop;
  time = null;
  window.requestAnimationFrame( draw );
  
});
body {
  background-color: rgb(255, 213, 0);
}
canvas {
  width: 100%;
}
<canvas id="myCanvas" width="1300px" height="300px"></canvas>

我还冒昧地在您的代码中添加了一些空格,我知道这是首选,但我认为带有喘息空间的清晰代码会更容易解析和沟通.我的眼睛不需要试着辨认出被打碎在一起的人物之间的区别.

Html相关问答推荐

如何让一个动态列表以网格方式水平显示

我如何 Select 外部html文件元素作为选项,并显示在一个div与jQuery?

如何在伪元素背景中定位多个CSS径向梯度

有没有一种方法可以动态地从网格或Flexbox中取出HTML元素?

使用CSS Flexbox时,我的图像未对齐

错误时交换表单,成功时使用HTMX重定向

图像如何能达到 HTML 表格的全宽?

如何在Rmarkdown中添加千位分隔符?

当悬停时,同时影响相邻的两侧div

如何正确地嵌套Flexbox

如何并排放置部分?

将图像高度调整到容器 div 中而不使其高度增加

为什么 css position:fixed 不适用于对话框标签?

不同屏幕尺寸的显示问题

辅助功能:alt 或 alt="" 用于装饰图像

浮动元素忽略 margin-top 属性后的块元素

如何突出显示 .qmd html 文件中的特定代码行

AWS SES:如何正确使用 CSS

下拉菜单项在页面加载时显示,需要隐藏直到悬停

尽管设置了 width:100% left:0,但居中对齐的 CSS 动画并不对称