HTML5 / Canvas toDataURL的滞后

时间:2014-03-27 18:40:44

标签: jquery html5-canvas

我正在尝试创建一个网页,您可以在其中选择图像(并最终操作并将其保存回计算机)。我的操作小部件实际上需要文件是jpegs或pngs(就像普通的img)。

到目前为止,我有这个:http://jsfiddle.net/Xg3VN/3/

function handleImage(e) {
    var reader = new FileReader();
    reader.onload = function (event) {
        var img = new Image();
        img.onload = function () {
            canvas.width = img.width;
            canvas.height = img.height;
            ctx.drawImage(img, 0, 0);

        }
        img.src = event.target.result;
    }
    reader.readAsDataURL(e.target.files[0]);
    var img = new Image();
    img.src = canvas.toDataURL();
    $('body').append($('<img>').attr('src', canvas.toDataURL()));

}

有一个延迟 - 您选择一个文件并显示它,但我希望它将带有“toDataURL”源的图像附加到页面的末尾。

现在,有一个周期滞后。第一张图片仅在第二张图片上传时附加。

我认为答案涉及回调,但我在这里迷失了。

谢谢!

2 个答案:

答案 0 :(得分:1)

您需要在onload函数中创建dataURL:

这是一个使用FileReader创建img元素和canvas元素的示例:

function handleFiles(files) {

    for (var i = 0; i < files.length; i++) {
      var file = files[i];
      var imageType = /image.*/;

      if (!file.type.match(imageType)) {
        continue;
      }

      var img = document.createElement("img");
      img.classList.add("obj");
      img.file = file;

      // testing...adds the new img element to a div with id="preview"

      preview.appendChild(img);

      var reader=new FileReader();
      reader.onload=(function(aImg){
          return function(e) {
              aImg.onload=function(){
                  var canvas=document.createElement("canvas");
                  var ctx=canvas.getContext("2d");
                  canvas.width=aImg.width;
                  canvas.height=aImg.height;
                  ctx.drawImage(aImg,0,0);

                  // testing...adds the temp canvas to the body
                  // if you need canvas.toDataURL, you can also do that now

                  document.body.appendChild(canvas);
              }
              // e.target.result is a dataURL for the image
              aImg.src = e.target.result;
          }; 
      })(img);
      reader.readAsDataURL(file);

    } // end for

} // end handleFiles

完整代码示例:从桌面拖放图片并同时创建img&amp;画布元素

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
    #dropzone{border:1px solid blue; width:300px;height:300px;}
</style>
<script>
$(function(){

    // dropzone event handlers
    var dropzone;
    dropzone = document.getElementById("dropzone");
    dropzone.addEventListener("dragenter", dragenter, false);
    dropzone.addEventListener("dragover", dragover, false);
    dropzone.addEventListener("drop", drop, false);

    //
    function dragenter(e) {
      e.stopPropagation();
      e.preventDefault();
    }
    //

    function dragover(e) {
      e.stopPropagation();
      e.preventDefault();
    }

    //
    function drop(e) {
      e.stopPropagation();
      e.preventDefault();

      var dt = e.dataTransfer;
      var files = dt.files;

      handleFiles(files);
    }

    // create img and/or canvas elements from dropped image files

    function handleFiles(files) {

        for (var i = 0; i < files.length; i++) {
          var file = files[i];
          var imageType = /image.*/;

          if (!file.type.match(imageType)) {
            continue;
          }

          var img = document.createElement("img");
          img.classList.add("obj");
          img.file = file;
          preview.appendChild(img);

          var reader=new FileReader();
          reader.onload=(function(aImg){
              return function(e) {
                  aImg.onload=function(){
                      var canvas=document.createElement("canvas");
                      var ctx=canvas.getContext("2d");
                      canvas.width=aImg.width;
                      canvas.height=aImg.height;
                      ctx.drawImage(aImg,0,0);
                      document.body.appendChild(canvas);
                  }
                  // e.target.result is a dataURL for the image
                  aImg.src = e.target.result;
              }; 
          })(img);
          reader.readAsDataURL(file);

        } // end for

    } // end handleFiles

}); // end $(function(){});
</script>
</head>
<body>
    <h4>Drag an image from desktop to blue dropzone.</h4>
    <div id="dropzone"></div>
    <div id="preview"></div>
</body>
</html>

答案 1 :(得分:1)

只需在加载程序中移动该方法的最后一部分:

function handleImage(e) {
    var reader = new FileReader();
    reader.onload = function (event) {
        var img = new Image();
        img.onload = function () {
            canvas.width = img.width;
            canvas.height = img.height;
            ctx.drawImage(img, 0, 0);

            var domImg = new Image();          // create a new image object
            domImg.src = canvas.toDataURL();   // set canvas URL as source
            $('body').append(domImg);          // append to body
        }
        img.src = event.target.result;
    }
    reader.readAsDataURL(e.target.files[0]);
}

<强> Modified fiddle

您可以立即追加,因为DOM和元素在准备好后会更新。请注意,如果您需要在创建图像后立即使用图像,则需要另一个onload处理程序:

var domImg = new Image();          // create a new image object
domImg.onload = nextStep;          // go to this function after loaded
domImg.src = canvas.toDataURL();   // set canvas URL as source
$('body').append(domImg);          // append to body