Javascript 使用Canvas GlobalComposite制作面具用于拼图游戏后端的操作
我正在尝试为发布简单的拼图游戏制作一个后端。游戏使用12个预先制作好的形状作为面具来制作12个拼图。我找到了非常好的,并进行了测试 我正在制作的应用程序使用ajax将每个完成的部分发送到serverside.php脚本。用户使用SSE加载图像(600x400),应用程序根据数组arr_x和arr_y的值将原始图像移动到Javascript 使用Canvas GlobalComposite制作面具用于拼图游戏后端的操作,javascript,php,html,canvas,html5-canvas,Javascript,Php,Html,Canvas,Html5 Canvas,我正在尝试为发布简单的拼图游戏制作一个后端。游戏使用12个预先制作好的形状作为面具来制作12个拼图。我找到了非常好的,并进行了测试 我正在制作的应用程序使用ajax将每个完成的部分发送到serverside.php脚本。用户使用SSE加载图像(600x400),应用程序根据数组arr_x和arr_y的值将原始图像移动到tempCanvas中。这应该发生在for循环中: function drawPieces(){ var canvas = document.getElementById(
tempCanvas
中。这应该发生在for循环中:
function drawPieces(){
var canvas = document.getElementById("myCanvas");
var context =canvas.getContext("2d");
var tempCanvas = document.getElementById("tempCanvas");
var tempContext = tempCanvas.getContext("2d");
var img_mask = new Image();
var w;
var h;
var cvd0,cvd1,cvd2,cvd3,cvd4,cvd5,cvd6,cvd7,cvd8,cvd9,cvd10,cvd11;
var arr_data = [cvd0,cvd1,cvd2,cvd3,cvd4,cvd5,cvd6,cvd7,cvd8,cvd9,cvd10,cvd11];
var arr_x = [0,-136,-289,-414,0,-115,-270,-415,0,-118,-288,-415];
var arr_y = [0,0,0,0,-113,-111,-111,-124,-244,-256,-243,-241];
var img_bg = new Image(600, 400);
for (var i = 0; i<arr_x.length; i++) {
img_bg = original;
// get the mask
img_mask.src = "img/mask"+i+".png";
w = img_mask.width;
h = img_mask.height;
console.log("w = ", img_mask.width, " h = ", img_mask.height);
tempCanvas.width = w;
tempCanvas.height = h;
// Her lages maska
tempContext.drawImage(img_mask,0,0);
tempContext.globalCompositeOperation = 'source-in';
tempContext.drawImage(img_bg,arr_x[i],arr_y[i]);
myCanvas.width = w;
myCanvas.height = h;
// Draws tempCanvas on to myCanvas
console.log("tempCanvas: ", tempCanvas, " img_mask.src = ", img_mask.src);
context.drawImage(tempCanvas, 0, 0);
arr_data[i] = myCanvas;
sendData(arr_data[i], [i]);
};
}
我的设置绝对有问题,但我不知道是什么。谁来帮帮我
顺便说一下,这也是我的.php脚本:
<?php
if (isset($GLOBALS["HTTP_RAW_POST_DATA"]))
{
// Get the data
$imageData=$GLOBALS['HTTP_RAW_POST_DATA'];
$parts = explode("<split>", $imageData);
$imageData = $parts[0];
$index= $parts[1];
// Remove the headers (data:,) part.
// A real application should use them according to needs such as to check image type
$filteredData=substr($imageData, strpos($imageData, ",")+1);
// Need to decode before saving since the data we received is already base64 encoded
$unencodedData=base64_decode($filteredData);
// Save file.
$fp = fopen( "pieces/".$index.".png", "wb" );
fwrite( $fp, $unencodedData);
fclose( $fp );
}
?>
问题
问题是,图像加载是异步的,这意味着它们在后台加载,而您的代码仍在继续
这意味着当您尝试将图像与drawImage一起使用时,图像将无法准备就绪(加载并解码),从而导致错误。这里的错误是间接的,因为w和h没有获得画布的有效值,这意味着画布的宽度为0,高度为0,这将在尝试绘制时触发实际错误
它第二次“起作用”的原因是,浏览器缓存中存在图像,并且可能能够在使用图像之前提供该图像
另一个问题是,在循环中,您正在覆盖image变量,因此加载时只使用最后一个图像
解决方案
解决方案是在开始循环之前制作或使用图像加载器。制作一个很容易,但为了简单起见,我将在本例中使用(免责声明:作者同上),但只要您对图像使用回调,任何类型的加载程序都可以:
function drawPieces(){
var canvas = document.getElementById("myCanvas");
var context =canvas.getContext("2d");
var tempCanvas = document.getElementById("tempCanvas");
var tempContext = tempCanvas.getContext("2d");
var img_mask;
var w;
var h;
var cvd0,cvd1,cvd2,cvd3,cvd4,cvd5,cvd6,cvd7,cvd8,cvd9,cvd10,cvd11;
var arr_data = [cvd0,cvd1,cvd2,cvd3,cvd4,cvd5,cvd6,cvd7,cvd8,cvd9,cvd10,cvd11];
var arr_x = [0,-136,-289,-414,0,-115,-270,-415,0,-118,-288,-415];
var arr_y = [0,0,0,0,-113,-111,-111,-124,-244,-256,-243,-241];
var img_bg;
// using some image(s) loader
var loader = new YAIL({done: draw});
for (var i = 0; i<arr_x.length; i++)
loader.add("img/mask"+i+".png");
loader.load(); // start loading images
// this is called when images has loaded
function draw(e) {
for (var i = 0; i<arr_x.length; i++) {
//img_bg = original; ??
// get the mask
var img_mask = e.images[i]; // loaded images in an array
w = img_mask.width; // now you will have a valid
h = img_mask.height; // dimension here
console.log("w = ", img_mask.width, " h = ", img_mask.height);
tempCanvas.width = w;
tempCanvas.height = h;
// Her lages maska
tempContext.drawImage(img_mask,0,0);
tempContext.globalCompositeOperation = 'source-in';
tempContext.drawImage(img_bg,arr_x[i],arr_y[i]);
myCanvas.width = w;
myCanvas.height = h;
// Draws tempCanvas on to myCanvas
console.log("tempCanvas: ", tempCanvas, " img_mask.src = ", img_mask.src);
context.drawImage(tempCanvas, 0, 0);
arr_data[i] = myCanvas;
sendData(arr_data[i], [i]);
}
};
}
功能抽片(){
var canvas=document.getElementById(“myCanvas”);
var context=canvas.getContext(“2d”);
var tempCanvas=document.getElementById(“tempCanvas”);
var tempContext=tempCanvas.getContext(“2d”);
var-img_掩模;
var-w;
var h;
变量cvd0、cvd1、cvd2、cvd3、cvd4、cvd5、cvd6、cvd7、cvd8、cvd9、cvd10、cvd11;
var arr_数据=[cvd0、cvd1、cvd2、cvd3、cvd4、cvd5、cvd6、cvd7、cvd8、cvd9、cvd10、cvd11];
var arr_x=[0,-136,-289,-414,0,-115,-270,-415,0,-118,-288,-415];
var arr_y=[0,0,0,0,-113,-111,-111,-124,-244,-256,-243,-241];
var img_bg;
//使用一些图像加载程序
var loader=new YAIL({done:draw});
对于(var i=0;i
<?php
if (isset($GLOBALS["HTTP_RAW_POST_DATA"]))
{
// Get the data
$imageData=$GLOBALS['HTTP_RAW_POST_DATA'];
$parts = explode("<split>", $imageData);
$imageData = $parts[0];
$index= $parts[1];
// Remove the headers (data:,) part.
// A real application should use them according to needs such as to check image type
$filteredData=substr($imageData, strpos($imageData, ",")+1);
// Need to decode before saving since the data we received is already base64 encoded
$unencodedData=base64_decode($filteredData);
// Save file.
$fp = fopen( "pieces/".$index.".png", "wb" );
fwrite( $fp, $unencodedData);
fclose( $fp );
}
?>
function drawPieces(){
var canvas = document.getElementById("myCanvas");
var context =canvas.getContext("2d");
var tempCanvas = document.getElementById("tempCanvas");
var tempContext = tempCanvas.getContext("2d");
var img_mask;
var w;
var h;
var cvd0,cvd1,cvd2,cvd3,cvd4,cvd5,cvd6,cvd7,cvd8,cvd9,cvd10,cvd11;
var arr_data = [cvd0,cvd1,cvd2,cvd3,cvd4,cvd5,cvd6,cvd7,cvd8,cvd9,cvd10,cvd11];
var arr_x = [0,-136,-289,-414,0,-115,-270,-415,0,-118,-288,-415];
var arr_y = [0,0,0,0,-113,-111,-111,-124,-244,-256,-243,-241];
var img_bg;
// using some image(s) loader
var loader = new YAIL({done: draw});
for (var i = 0; i<arr_x.length; i++)
loader.add("img/mask"+i+".png");
loader.load(); // start loading images
// this is called when images has loaded
function draw(e) {
for (var i = 0; i<arr_x.length; i++) {
//img_bg = original; ??
// get the mask
var img_mask = e.images[i]; // loaded images in an array
w = img_mask.width; // now you will have a valid
h = img_mask.height; // dimension here
console.log("w = ", img_mask.width, " h = ", img_mask.height);
tempCanvas.width = w;
tempCanvas.height = h;
// Her lages maska
tempContext.drawImage(img_mask,0,0);
tempContext.globalCompositeOperation = 'source-in';
tempContext.drawImage(img_bg,arr_x[i],arr_y[i]);
myCanvas.width = w;
myCanvas.height = h;
// Draws tempCanvas on to myCanvas
console.log("tempCanvas: ", tempCanvas, " img_mask.src = ", img_mask.src);
context.drawImage(tempCanvas, 0, 0);
arr_data[i] = myCanvas;
sendData(arr_data[i], [i]);
}
};
}