首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何检测,画布对象的绘制完成了?

如何检测,画布对象的绘制完成了?
EN

Stack Overflow用户
提问于 2019-03-15 18:51:03
回答 1查看 687关注 0票数 0

我有下面的JS代码(在这里,在堆栈溢出上找到的,并经过了一点修改),它使用画布来调整客户端的图像大小。

代码语言:javascript
复制
function FileListItem(a) {
    // Necesary to proper-work of CatchFile function (especially image-resizing).
    // Code by Jimmy Wärting (https://github.com/jimmywarting)
    a = [].slice.call(Array.isArray(a) ? a : arguments)
    for (var c, b = c = a.length, d = !0; b-- && d;) d = a[b] instanceof File
    if (!d) throw new TypeError('expected argument to FileList is File or array of File objects')
    for (b = (new ClipboardEvent('')).clipboardData || new DataTransfer; c--;) b.items.add(a[c])
    return b.files
}

function CatchFile(obj) {
    // Based on ResizeImage function.
    // Original code by Jimmy Wärting (https://github.com/jimmywarting)

    var file = obj.files[0];
    // Check that file is image (regex)
    var imageReg = /[\/.](gif|jpg|jpeg|tiff|png|bmp)$/i;
    if (!file) return

    var uploadButtonsDiv = document.getElementById('upload_buttons_area');
    // Check, that it is first uploaded file, or not
    // If first, draw a div for showing status
    var uploadStatusDiv = document.getElementById('upload_status_area');

    if (!uploadStatusDiv) {
        var uploadStatusDiv = document.createElement('div');
        uploadStatusDiv.setAttribute('class', 'upload-status-area');
        uploadStatusDiv.setAttribute('id', 'upload_status_area');
        uploadButtonsDiv.parentNode.insertBefore(uploadStatusDiv, uploadButtonsDiv.nextSibling);
        // Draw sub-div for each input field
        var i;
        for (i = 0; i < 3; i++) {
          var uploadStatus = document.createElement('div');
          uploadStatus.setAttribute('class', 'upload-status');
          uploadStatus.setAttribute('id', ('upload_status_id_commentfile_set-' + i + '-file'));
          uploadStatusDiv.append(uploadStatus);
        }
    }

    var canvasDiv = document.getElementById('canvas-area');
    var currField = document.getElementById(obj.id);
    var currFieldLabel = document.getElementById(('label_' + obj.id));

    // Main image-converting procedure
    if (imageReg.test(file.name)) {
        file.image().then(img => {
            const canvas = document.createElement('canvas')
            canvas.setAttribute('id', ('canvas_' + obj.id));
            const ctx = canvas.getContext('2d')
            const maxWidth = 1600
            const maxHeight = 1200

            // Calculate new size
            const ratio = Math.min(maxWidth / img.width, maxHeight / img.height)
            const width = img.width * ratio + .5|0
            const height = img.height * ratio + .5|0

            // Resize the canvas to the new dimensions
            canvas.width = width
            canvas.height = height

            // Drawing canvas-object is necessary to proper-work
            // on mobile browsers.
            // In this case, canvas is inserted to hidden div (display: none)
            ctx.drawImage(img, 0, 0, width, height)
            canvasDiv.appendChild(canvas)

            // Get the binary (aka blob)
            canvas.toBlob(blob => {
                const resizedFile = new File([blob], file.name, file)
                const fileList = new FileListItem(resizedFile)

                // Temporary remove event listener since
                // assigning a new filelist to the input
                // will trigger a new change event...
                obj.onchange = null
                obj.files = fileList
                obj.onchange = CatchFile
            }, 'image/jpeg', 0.70)
        }
        )

        // If file is image, during conversion show status
        function ShowConvertConfirmation() {
            if (document.getElementById('canvas_' + obj.id)) {
                document.getElementById(('upload_status_' + obj.id)).innerHTML =
                '<font color="#4CAF50">Konwertowanie pliku ' + file.name + ' zakończone!</font>';
                return true;
            }
            else {
                document.getElementById(('upload_status_' + obj.id)).innerHTML =
                '<font color="#4CAF50">Konwertowanie pliku ' + file.name + ' zakończone!</font>';
                return false;
            }
        }

        // Loop ShowConvertConfirmation function untill return true (file is converted)
        var convertConfirmationLoop = setInterval(function() {
            var isConfirmed = ShowConvertConfirmation();
            if (!isConfirmed) {
                ShowConvertConfirmation();
            }
            else {
                // Break loop
                clearInterval(convertConfirmationLoop);
            }
        }, 2000); // Check every 2000ms
        }
    // If file is not an image, show status with filename
    else {
        document.getElementById(('upload_status_' + obj.id)).innerHTML =
        '<font color="#4CAF50">Dodano plik ' + file.name + '</font>';
        //uploadStatusDiv.append(uploadStatus);
    }
}

画布用隐藏的div绘制:

代码语言:javascript
复制
<div id="canvas-area" style="overflow: hidden; height: 0;"></div>

我只是检测,div画布区域是在此基础上,JS附加了另一个div的状态。

不幸的是,在一些移动设备(中档智能手机)上,信息将在绘图完成之前显示出来(这是错误的)。因此,一些上传的图像被破坏或保持原来的大小。

如何防止这种情况发生?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-04-07 10:26:37

在图像加载之后应该发生的所有事情,都应该在then回调中执行,或者从其中调用。

重要的是要认识到,不在此回调范围内的代码将在绘图完成之前立即执行。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55189035

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档