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

Posted

技术标签:

【中文标题】合成:如何根据单选按钮中的选定选项动态更改画布新图纸?【英文标题】:Compositing: how to change canvas new drawings dynamically based on selected option from radio button? 【发布时间】:2015-11-26 08:01:11 【问题描述】:

几个月前我有一个related question,关于通过合成(html5 画布)为画布上色。当我再次遇到它时,我确实以某种方式理解它现在是如何工作的。但我今天的问题是,是否可以通过单选按钮更改绘制像素的分层而不影响已选择颜色的其他图层?

为了理解我在说什么,我创建了一个有效的JSFIDDLE。 (抱歉混乱的 CSS)

解释小提琴:我目前拥有的是我可以更改示例图像的背景颜色和中心的花朵。现在,如果您单击灰色按钮“更改中心图像”,将出现一个模式,显示 2 个示例中心图像,花朵和爪子。我想要实现的是根据模态框上的选中项来改变之前绘制的画布(也就是花)。假设我单击爪子图像,我应该能够看到爪子而不是花。所选的背景颜色不得受到影响。

这可能吗?如果没有,还有其他方法吗?

这是我的 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];

但是当我单击单选按钮时,我无法动态地让它改变。

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

【问题讨论】:

【参考方案1】:

你可以使用这个 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';

【讨论】:

您好 MarkE,感谢您的回答。我已经尝试过了,但是当我在 ifelse 条件下再次绘制爪子/花时,布局应该如何?我试图在“if paw condition”中使用类似:pawImage = url + paw.png;重绘爪();然后我有一个单独的 redrawPaw() 函数但没有工作。我该怎么做? (1) 保存最后的背景和前景色,(2) ClearRect 画布,(3) DrawImage 用户选择的爪子或花朵图像,(4) 使用源输入合成来改变将图像设置为您想要的颜色,(5)使用destination-over compositing在图像后面填充您保存的背景颜色,(6)TaDaaa ...你完成了。 :-) 是否需要再次声明所有内容?我的意思是 var canvas、var ctx、imageURLs.push 等。让我感到困惑的是如何声明图像源然后在 ifelse cond 中再次绘制它?感谢您的意见。 由于你已经在全局范围内声明了你的 canvas、ctx 和其他变量,你不必在函数中重新声明它们。我在答案中添加了重绘功能,展示了如何使用合成来更改图像颜色并应用适当的背景。干杯! 感谢 MarkE,在您的指导下,我成功实现了我的目标。谢谢! :)

以上是关于合成:如何根据单选按钮中的选定选项动态更改画布新图纸?的主要内容,如果未能解决你的问题,请参考以下文章

如何使选定的单选按钮根据另一个单选按钮更改另一个状态来更改一个状态?

仅从选定的单选按钮选项提交表单数据

如何按状态值更改选中(选定)单选按钮[重复]

如何根据选定的单选按钮值传递单选按钮值?

动态创建单选按钮并分配选定的值 PHP

如何通过选定的道具动态地更改 vue js 2 中的选项卡?