我该怎么做才能露出整个字符串?

问题描述 投票:0回答:1

很奇怪的是,当globalCompositeOperation为'source-atop'时它可以工作,但当globalCompositeOperation为''destination-atop'时却失败。似乎不同类型的单词不能一起显示。这是代码片段。

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',则只能显示一种类型的单词。我希望做的是使用画笔作为橡皮擦来擦除黄色和下面的标题逐渐出现。

html firefox canvas
1个回答
0
投票

我不确定为什么你的问题仅限于 Firefox,但这里的解决方案是简单地确保你的上下文在每次开始绘图时正确地reset。我发现在执行任何操作之前添加

ctx.save()
并在完成循环后添加
ctx.restore()
可以解决您的问题,尽管我不确定为什么它只适用于 CH 字母而不适用于其他字符。无论哪种方式,这样做都是安全的,并且每个浏览器都支持它。无论如何,这样做也是一个很好的做法,以确保您永远不会陷入不确定其所处状态的环境中。

此持久复合操作的另一个问题是,由于您没有重置它并且没有清除画布,因此该操作在技术上适用于已经存在的像素。因此,最好两者兼而有之:清理你的上下文并清理你的画布。在下面的代码片段中我已经完成了这两件事:

window.requestAnimationFrame(draw);

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();
  ctx.clearRect( 0, 0, canvas.width, canvas.height );
  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();
    
  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 id="myCanvas" width="1300px" height="300px"></canvas>

© www.soinside.com 2019 - 2024. All rights reserved.