Javascript 使用canvas globalAlpha进行淡入淡出

Javascript 使用canvas globalAlpha进行淡入淡出,javascript,html,canvas,Javascript,Html,Canvas,我试图将一幅画布的内容淡入另一幅画布。从脚本开始,我有以下几点可以用,但我不明白为什么褪色如此之快-为什么globalAlpha在只运行了0.2秒之后就几乎完全褪色了新图像?脚本在下面和下面 变量宽度=500,高度=300; var main=document.getElementById('main'); var mainctx=main.getContext('2d'); //开始路径,创建画布大小的矩形 mainctx.beginPath(); mainctx.rect(0,0,宽度,高

我试图将一幅画布的内容淡入另一幅画布。从脚本开始,我有以下几点可以用,但我不明白为什么褪色如此之快-为什么globalAlpha在只运行了0.2秒之后就几乎完全褪色了新图像?脚本在下面和下面


变量宽度=500,高度=300;
var main=document.getElementById('main');
var mainctx=main.getContext('2d');
//开始路径,创建画布大小的矩形
mainctx.beginPath();
mainctx.rect(0,0,宽度,高度);
mainctx.fillStyle=“#ff0000”;
mainctx.fill();
var test=document.getElementById('test');
var testctx=test.getContext('2d');
//开始路径,创建画布大小的矩形
testctx.beginPath();
rect(0,0,宽度,高度);
testctx.fillStyle=“#00ff00”;
testctx.fill();
var-op=1;
函数fade()
{
op-=0.001;
控制台日志(op);
//mainctx.clearRect(0,0,宽度,高度);
mainctx.globalAlpha=1-op;
mainctx.drawImage(testctx.canvas,0,0);

如果(op由于您没有清除画布,所以它看起来好像很快就褪色了,那么您会继续覆盖彼此的相同透明图像

您只需删除clearRect函数前面的//即可

<!DOCTYPE html>
<html>

  <head>
  </head>

  <body>

   <canvas id="main" width="500" height="300"></canvas>
   <canvas id="test" width="500" height="300"></canvas>

  <script>

  var width = 500, height = 300;
  var main = document.getElementById('main');
   var mainctx = main.getContext('2d');

  //begin path, create a rect the size of the canvas
  mainctx.beginPath();
   mainctx.rect(0, 0, width, height);
  mainctx.fillStyle = "#ff0000";
   mainctx.fill();

  var test = document.getElementById('test');
  var testctx = test.getContext('2d');

  //begin path, create a rect the size of the canvas
  testctx.beginPath();
  testctx.rect(0, 0, width, height);
  testctx.fillStyle = "#00ff00";
  testctx.fill();

  var op = 1;

  function fade()
  {
      op -= 0.001;

      console.log(op);

          //you already had it here, i only had to remove the "//"
      mainctx.clearRect(0, 0, width, height);
      mainctx.globalAlpha = 1 - op;
          mainctx.drawImage(testctx.canvas, 0, 0);

      if (op <= 0.1) setTimeout(function(){ console.log("done"); }, 1);
      else requestAnimationFrame(fade);
  }

  fade();

  </script>

  </body>

</html>

变量宽度=500,高度=300;
var main=document.getElementById('main');
var mainctx=main.getContext('2d');
//开始路径,创建画布大小的矩形
mainctx.beginPath();
mainctx.rect(0,0,宽度,高度);
mainctx.fillStyle=“#ff0000”;
mainctx.fill();
var test=document.getElementById('test');
var testctx=test.getContext('2d');
//开始路径,创建画布大小的矩形
testctx.beginPath();
rect(0,0,宽度,高度);
testctx.fillStyle=“#00ff00”;
testctx.fill();
var-op=1;
函数fade()
{
op-=0.001;
控制台日志(op);
//你已经在这里了,我只需要删除“/”
mainctx.clearRect(0,0,宽度,高度);
mainctx.globalAlpha=1-op;
mainctx.drawImage(testctx.canvas,0,0);

如果(op多亏了@kaido关于第三张画布的建议和@Soul_man在中的回答,我有了一个似乎很好的想法。而不是将原始图像放在第三张画布上(看起来很笨重,但也许我错了——也许这是更糟糕的记忆方式?)我现在使用getImageData存储原始图像,并将其写入每个循环的画布中,然后以越来越高的不透明度写入新图像


变量宽度=500,高度=300,text=“hello”;
var main=document.getElementById('main');
var mainctx=main.getContext('2d');
//开始路径,创建画布大小的矩形
mainctx.beginPath();
mainctx.rect(0,0,宽度,高度);
//十六进制颜色和填充画布矩形的百分比
mainctx.fillStyle=“#ff0000”;
mainctx.fill();
//将文本写入画布
mainctx.font='Bold 100px Arial';
mainctx.textAlign=“中心”;
mainctx.textBaseline=“中间”;
mainctx.fillStyle='#ffffff';
mainctx.fillText(文本,0+(宽度/2),0+(高度/2));
var test=document.getElementById('test');
var testctx=test.getContext('2d');
//开始路径,创建画布大小的矩形
testctx.beginPath();
rect(0,0,宽度,高度);
//十六进制颜色和填充画布矩形的百分比
testctx.fillStyle=“#00ff00”;
testctx.fill();
//不透明度从0开始
var-op=0;
//将现有主画布图像复制到内存中
var originalimage=mainctx.getImageData(0,0,宽度,高度);
//褪色帆布
函数fade()
{
//放置原始图像
mainctx.putImageData(原始图像,0,0);
//从0开始设置全局alpha,然后绘制新图像
mainctx.globalAlpha=op;
mainctx.drawImage(testctx.canvas,0,0);
//增量
op+=0.01;
if(op>=1.0)setTimeout(function(){console.log(“done”);},2000);
else requestAnimationFrame(淡入淡出);
}
褪色();

也许在
设置超时时
而不是
1
使用更高的值,如
2000
问题不在于褪色的速度(尽管我确实需要减慢它)这是淡入度从1.0到0.0的分布。当淡入度达到0.8时,新图像几乎完全淡入。您必须将原始画布状态保留在第三个屏幕外画布中,您将在交叉的每一步与第二个画布一起绘制fade@Kaiido举例说明为什么需要第三块画布当我处理两张画布的时候,这并不完全是我想要的方式。@Garrettlych,因为0.1不透明度+0.1不透明度不是0.2不透明度,所以要实现过渡,你需要在每一步都从原始图像开始。我现在没有时间撰写答案,但我明天会尝试。为了澄清,我正在将第一张画布从m它的当前图像到第二个画布上的图像-因此交叉淡入淡出从红色到绿色,而不是从无淡入绿色。那么我希望它能解释工作的不透明度是的,第三个屏幕外画布应该比putImageData性能更好,但很明显,这是一个应该,因为它在很大程度上取决于设备和浏览器的实现。所以无论哪种方式都很好。
<!DOCTYPE html>
<html>

  <head>
  </head>

  <body>

   <canvas id="main" width="500" height="300"></canvas>
   <canvas id="test" width="500" height="300"></canvas>

  <script>

  var width = 500, height = 300;
  var main = document.getElementById('main');
   var mainctx = main.getContext('2d');

  //begin path, create a rect the size of the canvas
  mainctx.beginPath();
   mainctx.rect(0, 0, width, height);
  mainctx.fillStyle = "#ff0000";
   mainctx.fill();

  var test = document.getElementById('test');
  var testctx = test.getContext('2d');

  //begin path, create a rect the size of the canvas
  testctx.beginPath();
  testctx.rect(0, 0, width, height);
  testctx.fillStyle = "#00ff00";
  testctx.fill();

  var op = 1;

  function fade()
  {
      op -= 0.001;

      console.log(op);

          //you already had it here, i only had to remove the "//"
      mainctx.clearRect(0, 0, width, height);
      mainctx.globalAlpha = 1 - op;
          mainctx.drawImage(testctx.canvas, 0, 0);

      if (op <= 0.1) setTimeout(function(){ console.log("done"); }, 1);
      else requestAnimationFrame(fade);
  }

  fade();

  </script>

  </body>

</html>
<canvas id="main" width="500" height="300" style="border: 1px solid #ff0000;"></canvas>
<canvas id="test" width="500" height="300" style="border: 1px solid #ff0000;"></canvas>

<script>

var width = 500, height = 300, text = "hello";


var main = document.getElementById('main');
var mainctx = main.getContext('2d');

//begin path, create a rect the size of the canvas
mainctx.beginPath();
mainctx.rect(0, 0, width, height);

//percentage to hex colour and fill canvas rect
mainctx.fillStyle = "#ff0000";
mainctx.fill();

//write text to canvas
mainctx.font = 'Bold 100px Arial';
mainctx.textAlign="center";
mainctx.textBaseline = "middle";
mainctx.fillStyle = '#ffffff';
mainctx.fillText(text, 0 + (width / 2), 0 + (height / 2));


var test = document.getElementById('test');
var testctx = test.getContext('2d');

//begin path, create a rect the size of the canvas
testctx.beginPath();
testctx.rect(0, 0, width, height);

//percentage to hex colour and fill canvas rect
testctx.fillStyle = "#00ff00";
testctx.fill();

//start opacity at 0
var op = 0;

//copy the existing main canvas image into memory
var originalimage = mainctx.getImageData(0, 0, width, height);


//fade canvas
function fade()
{
    //place the original image
    mainctx.putImageData(originalimage, 0, 0);

    //starting at 0 set the global alpha and then draw the new image
    mainctx.globalAlpha = op;
    mainctx.drawImage(testctx.canvas, 0, 0);

    //increment
    op += 0.01;

    if (op >= 1.0) setTimeout(function(){ console.log("done"); }, 2000);
    else requestAnimationFrame(fade);
}

fade();

</script>