3

私はキャンバスを学ぼうとしていますが、私が見落としているばかげたものだと確信していますが、理解できない奇妙な不具合に遭遇しています. 基本的に、ローカルの画像ファイルを選択できるページがあります。次に、画像に合わせてサイズ変更されたキャンバスに描画し、画像の上にマウスを移動すると、カーソルの座標が表示され、ガイドラインが表示されます。

ページはこちらです。

私が抱えている問題は、ファイルを選択すると、キャンバスのサイズがランダムに 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();
}
4

1 に答える 1

2

ところで、あなたがそこに持っている素晴らしい測定ツール!

これを変える:

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"),
于 2013-06-19T18:25:12.790 に答える