【问题标题】:HTML5 Canvas; Image clipping and multiple imagesHTML5 画布;图像剪辑和多个图像
【发布时间】:2015-10-12 16:59:29
【问题描述】:

我对画布还很陌生,但遇到了一些问题。

我正在努力实现一个最终目标:在一个画布中显示两个图像;一张图片是背景,另一张图片被剪裁为 PNG 并显示在顶部。

我已经到了那里,但我撞到了一堵墙,我不知道如何越过它。

我在http://jsfiddle.net/jhp79yg9/为它创建了一个jsFiddle

      function loadImages(sources, callback) {
        var images = {};
        var loadedImages = 0;
        var numImages = 0;
        // get num of sources
        for(var src in sources) {
          numImages++;
        }
        for(var src in sources) {
          images[src] = new Image();
          images[src].onload = function() {
            if(++loadedImages >= numImages) {
              callback(images);
            }
          };
          images[src].src = sources[src];
        }
      }
      var canvas = document.getElementById('canvas');
      var context = canvas.getContext('2d');

      var sources = {
        img1: 'https://scontent-iad3-1.cdninstagram.com/hphotos-xaf1/t51.2885-15/11351598_1454928098145798_1274636321_n.jpg',
        img2: 'https://igcdn-photos-c-a.akamaihd.net/hphotos-ak-xaf1/t51.2885-15/11379733_1139595366067106_273993739_n.jpg',
        mask: 'http://img12.deviantart.net/65e4/i/2013/003/6/6/png_floating_terrain_by_moonglowlilly-d5qb58m.png'
      };

      loadImages(sources, function(images) {
        context.drawImage(images.img2, 0, 0, 240, 240);
        
        context.drawImage(images.mask, 20, 95, 500, 349);
        context.globalCompositeOperation = 'source-in';
        context.drawImage(images.img1, 0, 0, 540, 540);

      });
<canvas id="canvas" width="540" height="540"></canvas>

在这个例子中,我将第一张图片的尺寸从 540x540 缩小到了 140x140,这样我就可以判断它是否搞砸了。

发生的情况是它没有显示第二张图像,而是显示了两次“img1”变量而不是显示“img2”。

谁能提供帮助?

我也说不出来,因为它正在渲染相同的图像,即在前景中和在背景中。那里的帮助也将不胜感激(剪辑的图像应该在前景中)。

谢谢!

【问题讨论】:

  • img2 is 被绘制,但是当mask 被绘制在它上面时,两者都被视为一个统一体 then img1source-in 绘制,它根据alpha 通道的值替换像素。 img1 没有被绘制两次。至少对我来说是这样(Firefox 39)。

标签: javascript html canvas


【解决方案1】:

另一种方法是从当前内容中剪下遮罩,然后在当前内容后面绘制背景:

loadImages(sources, function(images) {
    context.drawImage(images.img2, 0, 0, 540, 540);
    context.globalCompositeOperation = 'destination-out';
    context.drawImage(images.mask, 20, 95, 500, 349);
    context.globalCompositeOperation = 'destination-atop';
    context.drawImage(images.img1, 0, 0, 540, 540);
})

http://jsfiddle.net/jhp79yg9/6/

【讨论】:

  • 谢谢。这实际上最终工作得更好了。快速附加问题,我有一个点击时交换图像的功能,它适用于背景中的图像,但在剪辑的图像上,它看起来像是将新图像放在旧图像下方。有任何想法吗?编辑:对不起,我写反了。前景很好,背景没有变化。
【解决方案2】:

我无法清楚地理解您的要求,但做一些假设,我希望这会给您提供您所需要的

context.drawImage(images.img2, 100, 180, 350, 350);
context.globalCompositeOperation = 'destination-atop';
context.drawImage(images.mask, 100, 180, 350, 350);
context.drawImage(images.img1, 0, 0, 540, 540);

http://jsfiddle.net/jhp79yg9/5/

【讨论】:

  • 我投了赞成票,虽然我理解这个问题,所以“男性健康”图片应该是背景,“Foo Fighters”应该是前景中的剪辑部分。
  • @Xufox 这并不是一个巨大的差异。他只需要以不同的顺序绘制图像。
  • 太棒了。谢谢!原来我真的很近,却又那么远。感谢您的帮助!
猜你喜欢
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-11
  • 1970-01-01
  • 1970-01-01
  • 2011-12-18
相关资源
最近更新 更多