我正在构建一个应用程序来创建可以在DartFlash中使用的TextureAtlas。 我的想法是使用输入标记加载许多文件,然后使用FileReader API将这些文件转换为图像,在画布上绘制它们并将画布转储为用户可以下载的图像,沿着描述图像的JSON文件。 但是,它有时无法完成任务并正确写入输出图像。 我很确定这是一个同步问题,但我找不到问题。 我在Chrome中测试了它,它经常成功。在Firefox中,它具有更高的故障率。
以下是代码:
<html>
<head>
<script type="text/javascript">
"use strict"
var files=null;
var img_list=[];
var num_files=-1;
var img_list_length=0;
var output_json={}
var output_canvas=null;
var output_img=null;
var download_png=null;
function createOutputImg()
{
if(num_files != img_list_length)
{
return;
}
img_list.sort(function (a,b)
{
if(a.name > b.name)
{
return 1;
}
return -1;
});
output_canvas=document.createElement('canvas');
var total_width=0;
var highest_height=0;
for (var i=0; i<img_list.length; i++)
{
total_width+=img_list[i].width;
if(highest_height < img_list[i].height)
{
highest_height=img_list[i].height;
}
}
console.log(total_width);
output_canvas.width=total_width;
output_canvas.height=highest_height;
var context=output_canvas.getContext("2d");
output_json["frames"]=[];
var current_posx=0;
for (var i=0; i<img_list.length; i++)
{
var img=img_list[i];
context.drawImage(img, current_posx, 0);
console.log(i.toString()+" - "+img.name);
output_json["frames"].push(
{
"filename":img.name,
"frame":
{
"x":current_posx,
"y":0,
"w":img.width,
"h":img.height
},
"rotated":false,
"trimmed":false,
"spriteSourceSize":
{
"x":0,
"y":0,
"w":img.width,
"h":img.height
},
"sourceSize":
{
"w":img.width,
"h":img.height
}
});
current_posx+=img.width;
}
output_img=document.createElement('img');
output_img.src=output_canvas.toDataURL("image/png");
if(output_img.width != total_width)
{
alert("Error happened somewhere, please, refresh and retry again");
return;
}
var paragraph=document.createElement('p');
paragraph.innerHTML="Type a name for this resource.";
document.body.appendChild(paragraph);
var input_name=document.createElement('input');
input_name.type="text";
document.body.appendChild(document.createElement('br'));
document.body.appendChild(input_name);
var go_button=document.createElement('button');
go_button.innerHTML="Download";
document.body.appendChild(go_button);
document.body.appendChild(document.createElement('br'));
go_button.inputElement=input_name;
go_button.onclick=function (evt)
{
var resource_name=evt.target.inputElement.value;
if(resource_name == "")
{
alert ("Please type a name for this resource.");
return;
}
output_json["meta"]={}
output_json["meta"]["app"]="HTML ImagePacker";
output_json["meta"]["image"]=resource_name+".png";
output_json["meta"]["format"]="RGBA8888";
output_json["meta"]["size"]={};
output_json["meta"]["size"]["w"]=output_img.width;
output_json["meta"]["size"]["h"]=output_img.height;
output_json["meta"]["scale"]="1";
var json_data=new Blob([JSON.stringify(output_json)]);
var download_json=document.createElement('a');
download_json.innerHTML=resource_name+".json";
download_json.download=download_json.innerHTML;
download_json.href=window.URL.createObjectURL(json_data);
var download_png=document.createElement('a');
download_png.innerHTML=resource_name+".png";
download_png.download=download_png.innerHTML;
download_png.href=output_img.src;
document.body.appendChild(document.createElement('br'));
document.body.appendChild(download_json);
document.body.appendChild(document.createElement('br'));
document.body.appendChild(download_png);
document.body.appendChild(document.createElement('br'));
document.body.appendChild(output_img);
};
}
function handleFileSelect()
{
var files=document.getElementById("files").files;
num_files=files.length;
console.log(files);
var height=0;
for(var i=0; i<files.length; i++)
{
(function (file)
{
var reader=new FileReader();
reader.name=file.name;
reader.readAsDataURL(file);
reader.onload=(function (evt)
{
//console.log(evt);
if(evt.target.readyState == 2)
{
var img=document.createElement('img');
img.name=evt.target.name;
img.src=evt.target.result;
img_list.push(img);
img_list_length+=1;
//document.body.appendChild(img, null);
if(num_files == img_list_length)
{
createOutputImg();
}
}
});
})(files[i]);
}
}
</script>
</head>
<body>
<input type="file" id="files" name="files[]" onchange="handleFileSelect()" multiple/><br>
</body>
</html>