javascript - 将图像绘制到 Canvas 有时不显示任何内容

标签 javascript image html5-canvas

我正在尝试学习 Canvas 并遇到了一个我无法弄清楚的奇怪故障,尽管我确定这只是我忽略的愚蠢问题。基本上,我有一个页面,您可以在其中选择本地镜像文件。然后它将其绘制到已调整大小以适合图像的 Canvas 上,当您将鼠标移到图像上时,它会给出光标的坐标并显示一些引导线。

页面是here .

我遇到的问题是,当您选择一个文件时,它会随机将 Canvas 大小调整为 0x0,从那时起,无论您选择什么图像文件,它都将保持该大小。如果您刷新页面并选择上次导致问题的同一图像文件,那么它可能会正常工作并显示(也可能不会)。

我不认为这是浏览器缓存问题,因为我已经看到它发生在我选择 File1 并且它工作正常,选择 File2 并且它工作正常,然后再次选择 File1 并且它坏了。此外,如果我理解正确,那么将 FileReader 的事件处理程序设置为 onloadend 应该可以避免在图像被完全读取之前尝试绘制图像的任何问题。

这是我的代码(我确信有更简洁的方法可以做到这一点,但我仍在学习)。任何帮助将不胜感激。

index.html

<!DOCTYPE html>
<head>
    <title>Image Coordinates Inspector</title>  
    <style>
        body {
            background: #4a4a4a;
            color: #fdcd00;
        }   
        #canvas {
            margin-left: 15px;
            background: #ffffff;
            border: thin inset rgba(100, 150, 230, 0.5);
            cursor: crosshair;
            display: none;
        }
        #coordinates {
            margin-left: 15px;
        }   
        #fileselect {
            margin-left: 10px;
        }
    </style>
    <script language="JavaScript" type="text/javascript" src="imgcoords.js"></script>
</head>
<body onload="initializePage()">
    <div id='fileselect'>
        <form>
            <input id="filename" name="filename" type="file" accept="image/*">
        </form>
    </div>
    <div id='coordinates'></div>
    <canvas id='canvas'>
        Canvas not supported.
    </canvas>
</body>
</html>

imgcoords.js

var canvas,
    coordinates,
    filename,
    context,
    img = new Image(),
    coordevent = false;

function initializePage() {
    canvas = document.getElementById('canvas');
    coordinates = document.getElementById('coordinates');
    filename = document.getElementById('filename');
    context = canvas.getContext('2d');

    filename.onchange = function(e) {
        validateFile();
        e.preventDefault();
    };
}

function validateFile() {
    if (filename.value != '' && filename.files[0].type.match(/image.*/)) {
        var file = filename.files[0],
            reader = new FileReader();

        canvas.style.display = "none";
        reader.readAsDataURL(file);
        reader.onloadend = function(e) {
            img.src = e.target.result;
            resizeCanvas();
            drawImageFile();
        };
    } else {
        canvas.style.display = "none";
        alert("Selected file is not a valid image file.");
    }
}

function resizeCanvas() {
    canvas.width = img.width;
    canvas.height = img.height;
}

function windowToCanvas(canvas, x, y) {
    var bbox = canvas.getBoundingClientRect();

    return { x: (x - bbox.left) * (canvas.width / bbox.width),
             y: (y - bbox.top) * (canvas.height / bbox.height)
    };
}

function clearCanvas() {
    context.clearRect(0, 0, canvas.width, canvas.height);
}

function drawImageFile() {
    clearCanvas();
    context.drawImage(img, 0, 0);

    if (!coordevent) {
        canvas.onmousemove = function(e) {
            var loc = windowToCanvas(canvas, e.clientX, e.clientY);

            drawImageFile();
            drawGuidelines(loc.x, loc.y);
            updateCoordinates(loc.x, loc.y);
        };
        coordevent = true;
    }

    updateCoordinates(0, 0);
    canvas.style.display = "inline";
}

function drawGuidelines(x, y) {
    context.strokeStyle = 'rgba(0, 0, 230, 0.8)';
    context.lineWidth = 0.5;
    drawVerticalLine(x);
    drawHorizontalLine(y);
}

function updateCoordinates(x, y) {
    coordinates.innerHTML = '(' + x.toFixed(0) + ', ' + y.toFixed(0) + ')';
}

function drawHorizontalLine(y) {
    context.beginPath();
    context.moveTo(0, y + 0.5);
    context.lineTo(context.canvas.width, y + 0.5);
    context.stroke();
}

function drawVerticalLine(x) {
    context.beginPath();
    context.moveTo(x + 0.5, 0);
    context.lineTo(x + 0.5, context.canvas.height);
    context.stroke();
}

最佳答案

顺便说一句,您那里有不错的测量工具!

改变这个:

reader.onloadend = function(e) {
    img.src = e.target.result;
    resizeCanvas();
    drawImageFile();
};

为了给 img 加载它需要的时间:

reader.onloadend = function(e) {
    img.onload=function(){
        resizeCanvas();
        drawImageFile();
    }
    img.src = e.target.result;
};

此外,还有一个新的 Chrome 错误,您可能希望这样避免:

// img = new Image() is buggy in Chrome
img = document.createElement("img"),

关于javascript - 将图像绘制到 Canvas 有时不显示任何内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17183906/

相关文章:

javascript - 我正在尝试打开一个具有某种效果的模态窗口

javascript - 您知道 Google Docs Javascript 如何执行间隔数据自动刷新吗?

javascript - 在 createJS/easelJS 中围绕另一个对象旋转一个对象

javascript - 我可以在 HTML5 Canvas 中创建图形形状对象吗以及当用户将鼠标悬停在形状上时如何将光标显示为指针

JavaScript:如何处理所有后续的元素对?

javascript - 为什么 Rails 辅助方法会阻止 "unobtrusive JavaScript"?

php - 图片 - 上传没有响应,无法访问 $_FILES

css - symfony 1图像风格的正确方法

java - 使用 Struts 2 在 MySQL 的 JSP 页面中查看图像

javascript setTimeout() 无法正常工作