如何为多个画布图像填充颜色?

2024-04-30

这是我第一次使用 html5 canvas,我还不知道它是如何工作的。

我的问题是,我必须修改画布中图像的颜色。如果只有一张图像,这很容易。但是,我会有不止一张,换句话说,重叠的图像。

为了进一步理解我的问题,我创建了一个插图。只有 2 个图像文件,图像 1 和图像 2:

这是我当前的代码(fiddle http://jsfiddle.net/3nq4acts/这里也):

HTML:

<canvas id="canvas1" width="600" height="600"></canvas>

JS:

var can = document.getElementById('canvas1');
var ctx = can.getContext('2d');
var ctx2 = can.getContext('2d');


ctx.fillStyle = 'yellow'; // background color. box in the middle is transparent. try changing this to see the effect
ctx.fillRect(40,0,250,300); // not sure if there's other way to fill in the tranparent area. but I created a box behind the image

var img = new Image();
img.onload = function() {
    ctx.drawImage(img, 0, 0);
}

img.src = "http://s7.postimg.org/aruxhs8mz/pink.png"; //image 1


// I want to fill in the paw image too
/*ctx2.fillStyle = 'purple'; 
ctx2.fillRect(40,0,500,500); */

//should I declare something like this again?

var img2 = new Image();
img2.onload = function() {
    ctx2.drawImage(img2, 0, 0);
}

img2.src = "http://s7.postimg.org/69smposl7/paw.png"; //image 2
//paw initially colored light blue. i would like to customize the color of this too

我应该能够填充中间的爪子图像,而不仅仅是主图像。怎么做?

我创建了一个小提琴只是为了启发你我的问题。

希望有人可以帮助我提供任何建议。

非常感谢!


您可以使用合成来完成您的任务。

合成告诉画布在画布上绘制其他新图形(像素)时要做什么。

就您而言,学习 3 种合成模式很有用。

源头合成

默认的合成方法是“源覆盖”,即在现有像素上绘制新绘图。

// first draw a blue destination rectangle
ctx.fillStyle='blue';
ctx.fillRect(30,30,50,50);

// second draw a red source rectangle
ctx.fillStyle='red';
ctx.fillRect(60,60,50,50);

enter image description here then enter image description here results enter image description here

源顶合成

“source-atop”合成将仅在新像素与现有画布像素重叠的地方绘制新像素。

// first draw a blue destination rectangle
ctx.fillStyle='blue';
ctx.fillRect(30,30,50,50);

// set compositing to 'source-atop'
// (the new red pixels will only be drawn where
//  they overlap the existing blue pixels)
ctx.globalCompositeOperation='source-atop';

// second draw a red source rectangle
// (red will overwrite only where it overlapped the blue)
ctx.fillStyle='red';
ctx.fillRect(60,60,50,50);

enter image description here then enter image description here results enter image description here

目的地合成

“destination-over”合成将在现有画布像素下绘制新像素。

// first draw a blue destination rectangle
ctx.fillStyle='blue';
ctx.fillRect(30,30,50,50);

// set compositing to 'source-atop'
// (the new red pixels will only be drawn where
//  they overlap the existing blue pixels)
ctx.globalCompositeOperation='destination-over';

// second draw a red source rectangle
// (red will appear under the blue)
ctx.fillStyle='red';
ctx.fillRect(60,60,50,50);

enter image description here then enter image description here results enter image description here

以下是如何使用合成来改变爪子的颜色。

  1. 清除画布。您无法直接更改先前在画布上绘制的任何内容的颜色,因此画布的典型工作流程是擦除它并以新的位置和颜色重新绘制项目。

  2. 画出爪子图像。

  3. 将合成设置为source-atop因此,新的绘图只会在现有爪子像素存在的地方绘制。

  4. 使用新的爪子颜色填充画布fillStyle & fillRect。这会导致您的爪子重新着色,因为新着色的矩形像素只会出现在您的爪子像素当前存在的位置。

  5. 将合成设置为destination-over因此新的绘图将在现有像素下绘制。

  6. 填写黄色框。您的爪子不会被覆盖,因为新的(黄色)像素将绘制在您的爪子“下方”。

  7. 将合成设置回默认值source-over因此新的图纸将绘制在现有图纸的基础上。

  8. 画出中心透明的框架。您的爪子和黄色背景将通过框架的透明中​​心显示。

这是示例代码和演示:

var can = document.getElementById('canvas1');
var ctx = can.getContext('2d');
var ctx2 = can.getContext('2d');

var images=[];
var urls=[];
urls.push('http://s7.postimg.org/aruxhs8mz/pink.png');
urls.push('http://s7.postimg.org/69smposl7/paw.png');
var imgCount=urls.length;

document.getElementById('recolor').onclick=function(){
  redrawWithNewPawColor();
};

for(var i=0;i<urls.length;i++){
  images[i]=new Image();
  images[i].onload=myOnload;
  images[i].src=urls[i];
}
function myOnload(){
  imgCount--;
  if(imgCount>0){return;}
  start();
}
function start(){
  redrawWithNewPawColor()
}

function drawWithRecoloredPaw(newPawColor){

  // clear the canvas
  ctx.clearRect(0,0,can.width,can.height);

  // draw the paw
  ctx.drawImage(images[1], 0, 0);  

  // set compositing to source-atop
  // so only existing pixels will be overwritten
  ctx.globalCompositeOperation='source-atop';
  // fill with new color
  ctx.fillStyle=newPawColor;
  // Because of compositing, only the paw is being color filled
  ctx.fillRect(0,0,can.width,can.height);

  // set compositing to destination-over
  // so new pixels will be draw behind existing (paw) pixels
  ctx.globalCompositeOperation='destination-over';
  // change the fill color to yellow
  ctx.fillStyle='yellow';
  // fill the yellow box
  ctx.fillRect(40,0,250,300);   

  // set compositing to the default of source-over
  ctx.globalCompositeOperation='source-over';
  // draw the transparent frame
  ctx.drawImage(images[0],0,0);

}

function redrawWithNewPawColor(){
  drawWithRecoloredPaw(randomColor());
}

function randomColor(){ 
  return('#'+Math.floor(Math.random()*16777215).toString(16));
}
body{ background-color: ivory; padding:10px; }
#canvas{border:1px solid red;}
<button id='recolor'>Recolor Paw</button>
<br>
<canvas id="canvas1" width=600 height=600></canvas>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何为多个画布图像填充颜色? 的相关文章

  • 将 jquery-mobile 与 Webpack 结合使用

    我正在尝试使用 webpack 加载 jquery mobile 但到目前为止还没有运气 我知道 jquery mobile 依赖于 jquery ui 而 jquery ui 又依赖于 jquery 如何在 Webpack 中设置这样的场
  • 未捕获的引用错误:myFunction 未定义[重复]

    这个问题在这里已经有答案了 这到底是怎么回事 http jsfiddle net sVT54 http jsfiddle net sVT54
  • 将 Sweet Alert 弹出窗口添加到 React 组件中的按钮

    我为 Bootstrap 和 React 找到了这个完美的 Sweet Alert 模块 我在 Meteor 应用程序中使用它 http djorg83 github io react bootstrap sweetalert http d
  • 将音频与视频流合并 Node.js

    我正在创建 YouTube 视频下载器并且正在使用ytdl core库 它无法下载带有音频的高质量视频 因为 youtube 将其放在另一个文件中 但我需要将其全部下载到一个文件中 我已经这样做了 app get download asyn
  • 禁用 JavaScript 中的右键单击

    当我尝试禁用右键单击时 它不起作用 我尝试使用下面的代码 document onclick function e console log e button if e button 2 e preventDefault return fals
  • 响应式网格布局框架[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 使用模态表单 ajax 超出 HTMLFormElement.toString 的最大调用堆栈大小

    我想使用模态窗口中的 ajax 请求提交表单 单击此链接可打开该模式 a class btn btn primary i class fa fa edit i Write a review a 模态窗口 div class modal fa
  • ElectronJS ReferenceError:导航器未定义

    我正在尝试在电子上制作自定义标题栏 但是当我启动我的应用程序时 我遇到了 ReferenceError 导航器未定义 问题 请帮忙 这是我的 main js 中的代码片段 My Codes https i stack imgur com c
  • 保存/导出Chrome的JavaScript控制台输入历史记录

    无论如何 我可以保存或导出 JavaScript 控制台的历史记录吗 input 控制台历史记录 在 Google Chrome 中 我不想保存输出或错误 因此将鼠标悬停在控制台框上 右键单击并选择Save as 不是解决方案 我不想每次都
  • 如何使用 jQuery 向表中添加新行,并为其分配递增的 id

    我有一个现有的 HTML 表格 它是用户输入 GPS 点的表单的一部分 用户还可以选择上传 GPS 数据点 我想要一个用户可以按下的按钮 其中一些 Javascript 会向表中添加一个或多个新行 但新行必须继续增加表中使用的名称和 id
  • Aptana Studio 3 上的预览选项卡在哪里?

    我在 Windows PC 上使用 Aptana Studio 2 并有一个选项卡用于在 IE 上预览页面 另一个选项卡用于在 Firefox 上预览 但我切换到了 Aptana 3 我不知道是没有预览还是我没有找到它 是的 我在 stac
  • Flux + React.js - 操作中的回调是好还是坏?

    让我解释一下我最近遇到的问题 我有 React js Flux 驱动的应用程序 有一个列表显示文章数量 注意 应用程序中有多个不同的列表 和文章详情查看在里面 但每个列表只有一个 API 端点 它返回文章数组 为了显示我需要的详细信息fin
  • 如何将 Browserify 与外部依赖项一起使用?

    我正在尝试慢慢地将 Browserify 引入我的网站 但我不想重写所有 js 也不希望 jquery 和其他库的重复实例与我的 Browserify 版本捆绑在一起 如果我构建将 jquery 列为外部依赖项的模块 那么如何将其指向我的全
  • 如何在 onDraw() 方法中定义与像素无关的高度

    我扩展了 View 来构建自定义小部件 我想用独立的像素单位定义小部件的高度 我认为可以通过将像素密度乘以所需的高度来完成 但我不知道该怎么做 到目前为止我所拥有的 最小化 public class Timeline extends Vie
  • 如何在 e2e AngularJS 测试中进行文件上传?

    在我的一种观点中 我有一个文件上传控件 它支持通过拖放或单击按钮后打开的标准文件对话框上传文件 How to do this in my e2e tests1 1 Just one of the two options will be en
  • 加载另一个 JS 脚本后加载

    这是我的代码 very big js file lots of html stuff 问题是 这些是异步加载的 有没有办法等待第二个脚本直到第一个脚本加载 如果您使用 jQuery 有一个非常简单的方法可以通过获取脚本 https api
  • ES6 模板文字的延迟执行

    我正在玩新的ES6 模板文字 http tc39wiki calculist org es6 template strings 我首先想到的是String format对于 JavaScript 所以我开始实现一个原型 String pro
  • 替换两个引号之间的字符串

    我想转动一根绳子str hello my name is michael what s your s into hello my name is span class name michael span 我怎样才能在 JavaScript
  • React Native - 跨屏幕传递数据

    我遇到了一些麻烦react native应用程序 我不知道如何跨屏幕传递数据 我意识到还有其他类似的问题在 SO 上得到了回答 但是这些解决方案对我来说不起作用 我正在使用StackNavigator 这是我的设置App js file e
  • 如何调试 Gulp 任务?

    如何调试我的中定义的 gulp 任务gulpfile js使用诸如 Google Chrome 调试器之类的调试器逐行单步执行任务的代码 对于 Node js 6 3 版本 您可以使用 inspect flag https nodejs o

随机推荐