合成:如何根据单选按钮中的选定选项动态更改 canvas 新绘图?

Compositing: how to change canvas new drawings dynamically based on selected option from radio button?

个月前关于通过合成着色 canvas (HTML5 Canvas)。当我再次遇到它时,我确实以某种方式理解了它是如何工作的。但我今天的问题是,是否可以通过单选按钮更改绘制像素的分层,而不会影响已选择颜色的其他图层?

为了理解我在说什么,我创建了一个工作 JSFIDDLE。 (抱歉弄乱了CSS)

解释 Fiddle:我目前拥有的是,我可以更改示例图像的背景颜色和中心的花朵。现在,如果您单击灰色按钮 "Change center image",将出现一个模式,显示 2 个样本中心图像,花朵和爪子。我想要实现的是根据模态上的所选项目更改之前绘制的canvas(即花)。假设我单击爪子图像,我应该能够看到爪子而不是花。所选的背景颜色不能受到影响。

这可能吗?如果不行,还有别的办法吗?

所以这是我的 JavaScript:

var cvs = document.getElementById("canvas");
var ctx = cvs.getContext("2d");

var centerImgDefaultColor = "#f6de16";
var baseColor = "#d85700";

var imageURLs = [];
var imagesOK = 0;
var imgs = [];

var images = ["http://s23.postimg.org/y8hbni44b/base.png","http://s10.postimg.org/592v9dsd5/flower.png","http://s10.postimg.org/592v9dsd5/flower.png"]; 
for (var i = 0; i < images.length; i++) {        
imageURLs.push(images[i]);
}
loadAllImages();

function loadAllImages() {
for (var i = 0; i < imageURLs.length; i++) {
    var img = new Image();
    imgs.push(img);
    img.onload = function () {
        imagesOK++;
        imagesAllLoaded();
    };
    img.src = imageURLs[i];
}
}

var imagesAllLoaded = function () {

if (imagesOK >= imageURLs.length) {
    base = imgs[0];
    paw = imgs[1];
    overlay = imgs[2];
    draw();
}

};


function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();

ctx.drawImage(overlay, 0, 0);
ctx.fillStyle = centerImgDefaultColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.globalCompositeOperation = "destination-atop";
ctx.drawImage(paw, 0, 0);

ctx.drawImage(base, 0, 0);
ctx.fillStyle = baseColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.globalCompositeOperation = "destination-atop";
ctx.restore();
}

$(".paw").click(function () {
centerImgDefaultColor = '#' +  $( this ).attr( "value" );
draw();
});

$(".base").click(function () {
baseColor = '#' +  $( this ).attr( "value" );
draw();
});

还有我的HTML:

    <div style="float:left;">
    <p>Background Color</p>
    <div class="base" style="width:25px;height:25px;background-color:#000000;" value="000000"></div>
    <div class="base" style="width:25px;height:25px;background-color:#7da7de;" value="7da7de"></div>
    <div class="base" style="width:25px;height:25px;background-color:#d85700;" value="d85700"></div>
</div>

<div style="float:right;">
    <p>Center Image Color</p>
    <div class="paw" style="width:25px;height:25px;background-color:#040054;" value="040054"></div>
    <div class="paw" style="width:25px;height:25px;background-color:#267d00;" value="267d00"></div>
    <div class="paw" style="width:25px;height:25px;background-color:#f6de16;" value="f6de16"></div>    
</div>
<a class="button" href="">Change center image</a>

<div id="modal">
    <a href="" class="close">&#215;</a>
    <input type="radio" class="btn-img" name="imageLayout" value="flower" checked="checked"/><img src="http://s10.postimg.org/6j3y3l979/prev_flower.png"/>
    <input type="radio" class="btn-img" name="imageLayout" value="paw"/><img src="http://s1.postimg.org/gtmv5giwr/prev_paw.png"/>
</div>
<div class="modal-bg"></div> 

<canvas id="canvas" width=310 height=450></canvas>

一开始我实际上是在考虑获取单选按钮的值并通过点击功能将其加载到我的图像数组中,但我认为这是不可能的。

$(".btn-img").click(function() { var val = 
    $('input[name="imageLayout"]:checked').val(); 
});

所以我想在我的 JS 中使用类似的东西(假设图像来自我的服务器,所以我使用图像的直接名称):

var selectedimageLayout = $('input[name="imageLayout"]:checked').val();
var imageLayoutSample = selectedimageLayout + ".png";

并将其传递到我的图像数组:

var images = ["http://s23.postimg.org/y8hbni44b/base.png",imageLayoutSample ,imageLayoutSample];

但是我无法在单击单选按钮时动态地让它发生变化。

我将非常感谢任何意见、建议或答案。谢谢。

您可以使用此 jQuery 选择器监听模式单选按钮上的点击:

#modal input[type=radio]

然后根据单击的单选按钮重绘场景:

$('#modal input[type=radio]').click(function(){
    var imageName=$(this).val();
    if(imageName=='paw'){
        // draw the paw in the specified colors
    }else if(imageName=='flower'){
        // draw the flower in the specified colors
    }
});

[补充:使用合成合成图像+背景]

这是一个重绘函数,它接受一个图像对象、背景色和前景色,并使用合成为具有指定背景的图像对象重新着色:

function redraw(img,background,foreground){
    ctx.clearRect(0,0,canvas.width,canvas.height);
    ctx.drawImage(img,0,0);
    ctx.globalCompositeOperation='source-in';
    ctx.fillStyle=foreground;
    ctx.fillRect(0,0,canvas.width,canvas.height);
    ctx.globalCompositeOperation='destination-over';
    ctx.fillStyle=background;
    ctx.fillRect(0,0,canvas.width,canvas.height);
    ctx.globalCompositeOperation='source-over';
}