2013-06-19 2 views
1

Я пытаюсь изучить Холст и нахожусь в странном сгустке, который я не могу понять, хотя я уверен, что это просто что-то глупое. В принципе, у меня есть страница, на которой вы можете выбрать локальный файл изображения. Затем он будет рисовать его на холсте, размер которого был изменен, чтобы соответствовать изображению, и когда вы наводите мышь на изображение, оно дает координаты курсора и отображает некоторые направляющие линии.Рисование изображения на холст Иногда не отображает ничего

Страница: here.

Проблема, с которой я сталкиваюсь, - это когда вы выбираете файл, он будет случайным образом изменять размер холста до 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(); 
} 

ответ

1

КСТАТИ Хороший инструмент измерения у вас есть!

Изменить это:

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"), 
+0

Спасибо за комплимент, но это на самом деле пример из книги _Core HTML5 Canvas_, поэтому я не могу взять на себя ответственность за это. Я просто пытался переключить его, чтобы вы могли выбрать локальный файл, а не просто использовать файл жесткого кодированного изображения на сервере. :) В любом случае, я внес свои изменения, и теперь это работает как чемпион. Мне никогда не приходило в голову проверить загрузку фактического изображения. Большое спасибо! –

Смежные вопросы