H5 Canvas 中 globalCompositeOperation 的理解和应用

H5 CanvasHTML5 中的一个元素,它拥有丰富的 API,允许开发人员通过 JS 在网页上绘制图形、动画和复杂的视觉效果-比如笔者之前的文章引力粒子特效 - 归为尘埃

本文,我们来讲讲 globalCompositeOperation 这个重要的属性。

globalCompositeOperaton 是什么

globalCompositeOperation 顾名思义,为合成操作,用于设置新绘制的图形如何和已有图形进行合成。 这个属性接受一个字符串值,该值决定了合成的方式。

context.globalCompositeOperation = "source-over" 是其默认值,表示新图形会覆盖在已有图形之上。

合成操作方式

合成的方式有以下,我们结合案例,逐一来体验。

假设我们有素材如下:

该素材的尺寸为 548px * 452px ,包含透明的地方和红色不透明的地方。该图片作为已有图片

笔者头像作为新图,尺寸为 90px * 90px

html 复制代码
<canvas id="canvas" width="548" height="452"></canvas>
javascript 复制代码
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const imgOrigin = new Image();
imgOrigin.src = "path/to/orignal-image.png";
imgOrigin.onload = () => {
  ctx.drawImage(imgOrigin, 0, 0, 548, 452);
  
  // 设置 globalCompositeOperation 为 source-over
  ctx.globalCompositeOperation = "source-over";

  const imgTarget = new Image();
  imgTarget.src = "path/to/target-image.png";
  imgTarget.onload = () => {
    ctx.drawImage(imgTarget, 0, 0);
  }
}
  • source-over:默认值,新图形绘制在已有图形上。

如上代码,得到的结果如图:

  • source-in:新图形仅在与已有图形重叠的地方显示

我们更改下目标绘制的尺寸 ctx.drawImage(imgTarget, 0, 0, 300, 300);

注意:以下案例新图的绘制尺寸均为 300px * 300px

  • source-out:新图形仅在不与已有图形重叠的地方显示。
  • source-atop:新图形仅在与已有图形重叠的地方显示,且在已有图形之上。
  • destination-over:新图形绘制在已有图形之下
  • destination-in:已有图形仅在与新图形重叠的地方显示。
  • destination-out:已有图形仅在不与新图形重叠的地方显示
  • destination-atop:已有图形仅在与新图形重叠的地方显示,且在新图形之上
  • lighter:新图形和已经有的图形颜色值相加
  • copy:新图形完成替换已有图形
  • xor:新图形和已有图形进行抑或操作
CSS 复制代码
body {
  // 方便比较,这里更改下背景颜色
  background-color: blue;
}

案例

我们在合成图像的时候,针对不同形状的图层,比如开题给出的图👇

那么我们可以通过 source-atop 将需要的图绘制在红色的区间。

如果,我们需要将蒙层的边框和上面的蒙层进行叠加,获取到新的蒙层内容。我们可以使用 destination-out

typescript 复制代码
// 创建图层背景图片-这里统一没有重叠的地方,以原图的为标准,保留其原图不重叠的部分
async function createModelLayerBgImage(params: Params, backgroundImage?: string): Promise<string> {
    const croppedFrame = await createCroppedCanvas(params);
    // 没有背景图则取相框
    if (!backgroundImage) {
        return croppedFrame || whiteBgBase64;
    }

    const modelLayerWidth: number = params.modelLayerInfo.size.width;
    const modelLayerHeight: number = params.modelLayerInfo.size.height;
    const generateCanvas: HTMLCanvasElement | null = document.createElement("canvas");
    generateCanvas.width = modelLayerWidth;
    generateCanvas.height = modelLayerHeight;

    const generateCtx = generateCanvas.getContext("2d");
    if (!generateCtx) {
        console.error("Failed to get 2D context from generate canvas");
        return backgroundImage;

    }

    const bgImage = await loadImage(backgroundImage);
    generateCtx.drawImage(bgImage, 0, 0, modelLayerWidth, modelLayerHeight);

    // 先变成白色背景
    generateCtx.globalCompositeOperation = "source-in";
    generateCtx.fillStyle = "#FFFFFF";
    generateCtx.fillRect(0, 0, modelLayerWidth, modelLayerHeight);

  
    generateCtx.globalCompositeOperation = "destination-out";
    // 加载剪切的图层的边框背景图
    const croppedFrameImage = await loadImage(croppedFrame);
    generateCtx.drawImage(croppedFrameImage, 0, 0, modelLayerWidth, modelLayerHeight);

    // 返回base64编码的图片 - 变成白色背景图
    const base64Image = generateCanvas.toDataURL("image/png");

    return base64Image;

}

参考

相关推荐
星空寻流年26 分钟前
CSS3(BFC)
前端·microsoft·css3
九月TTS27 分钟前
开源分享:TTS-Web-Vue系列:Vue3实现固定顶部与吸顶模式组件
前端·vue.js·开源
H3091943 分钟前
vue3+dhtmlx-gantt实现甘特图展示
android·javascript·甘特图
CodeCraft Studio1 小时前
数据透视表控件DHTMLX Pivot v2.1发布,新增HTML 模板、增强样式等多个功能
前端·javascript·ui·甘特图
一把年纪学编程1 小时前
【牛马技巧】word统计每一段的字数接近“字数统计”
前端·数据库·word
llc的足迹1 小时前
el-menu 折叠后小箭头不会消失
前端·javascript·vue.js
九月TTS1 小时前
TTS-Web-Vue系列:移动端侧边栏与响应式布局深度优化
前端·javascript·vue.js
Johnstons2 小时前
AnaTraf:深度解析网络性能分析(NPM)
前端·网络·安全·web安全·npm·网络流量监控·网络流量分析
whatever who cares2 小时前
CSS3 伪元素(Pseudo-elements)大全
前端·css·css3
若愚67922 小时前
前端取经路——性能优化:唐僧的九道心经
前端·性能优化