时间:2010-07-23 16:46:58

标签: javascript html5 canvas transparency gradient

5 个答案:

答案 0 :(得分:16)

可以使用context.globalCompositeOperation制作掩码

context.drawImage(img, 0, 0, img.width, img.height, 0,0, img.width, img.height);
context.globalCompositeOperation = "destination-out";
gradient = context.createLinearGradient(0, 0, 0, img.height);
gradient.addColorStop(0, "rgba(255, 255, 255, 0.5)");
gradient.addColorStop(1, "rgba(255, 255, 255, 1.0)");
context.fillStyle = gradient;
context.fillRect(0, 0, img.width, img.height);

这不是每像素操作而应该更快

答案 1 :(得分:10)

要使用透明蒙版正确合并两个图像,首先需要拍摄两个图像中的一个并将其放入 off screen 画布,然后使用context.globalCompositeOperation = destination-out添加所需的透明蒙版per @ Tommyka的回答

var offscreen = document.createElement('canvas'); // detached from DOM
var context = offscreen.getContext('2d');
context.drawImage(image1, 0, 0, image1.width, image1.height);

var gradient = context.createLinearGradient(0, 0, 0, img.height);
gradient.addColorStop(0, "rgba(255, 255, 255, 0.5)");
gradient.addColorStop(1, "rgba(255, 255, 255, 1.0)");
context.globalCompositeOperation = "destination-out";
context.fillStyle = gradient;
context.fillRect(0, 0, image1.width, image1.height);

然后,要实际合并这两个图像,您需要将另一个图像绘制到另一个画布中,然后简单地在其上绘制alpha合成的屏幕外画布:

var onscreen = document.getElementById('mycanvas');
var context2 = onscreen.getContext('2d');
context2.drawImage(image2, 0, 0, image2.width, image2.height);
context2.drawImage(offscreen, 0, 0, onscreen.width, onscreen.height);

http://jsfiddle.net/alnitak/rfdjoh31/4/

演示

答案 2 :(得分:7)

答案 3 :(得分:0)

答案 4 :(得分:0)

我通过合并图像的异步加载来实现Alnitak's response的现代化。

我也摆脱了魔术数字。

const imageUrls = [
  // Base image
  'http://www.netstate.com/states/symb/flowers/images/apple_blossoms.jpg',
  // Gradient image
  'http://www.netstate.com/states/symb/flowers/images/oklahoma_rose.jpg'
];

const main = async () => {
  const ctx = document.getElementById('cv').getContext('2d'),
    baseImg = await loadImage(imageUrls[0]),
    gradImg = await loadImage(imageUrls[1]);

  draw(ctx, baseImg, gradImg);
};

/**
 * Loads an Image object via a Promise.
 * @param {String} url - Location of an image file
 * @return {Promise<Image>} Returns a promise that resolves to an Image.
 */
const loadImage = (url) => new Promise((resolve, reject) => {
  const img = new Image();
  img.addEventListener('load', () => resolve(img));
  img.addEventListener('error', reject);
  img.src = url;
});

/**
 * Draws an image, as a gradient applied to it, above another image.
 * @param {Image} baseImg - Image that is applied under the gradient
 * @param {Image} gradImg - Image to be applied as a gradient
 */
const draw = (ctx, baseImg, gradImg) => {
  const {width, height} = baseImg,
      originX = Math.floor(width / 2),
      originY = Math.floor(height / 2),
      radius = Math.min(originX, originY);

  const offScreen = document.createElement('canvas');
  offScreen.width = offScreen.height = width;
  const ctx2 = offScreen.getContext('2d');

  ctx2.drawImage(gradImg, 0, 0, width, height);
  const gradient = ctx2.createRadialGradient(originX, originY, 0, originX, originY, radius);

  gradient.addColorStop(0, 'rgba(255, 255, 255, 0)');
  gradient.addColorStop(1, 'rgba(255, 255, 255, 1)');

  ctx2.fillStyle = gradient;
  ctx2.globalCompositeOperation = 'destination-out';
  ctx2.fillRect(0, 0, width, height);

  ctx.drawImage(baseImg, 0, 0, width, height);
  ctx.drawImage(offScreen, 0, 0, width, height);
};

main();
<canvas id="cv" width="300" height="300"></canvas>