Canvas putImageData XOR проблема только на iPad
Кто-нибудь знает, что не так со следующим кодом.
Демо: http://jsbin.com/xecicovi/1/
Он отлично работает на Windows и Android, но курсор непоследовательно оставляет некоторые следы на iPad. Я использую getImageData и XOR'ing биты и putImageData, чтобы нарисовать и стереть прямоугольный блок курсора.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title> New Document </title>
<script src="jquery-1.11.0.js"></script>
<script language="javascript">
var m_ctx;
var m_canvas;
var m_bCursorOn = false;
var m_nXpos = 0;
function DrawCursor()
{
var nCellY = 10;
var nCellH = 24;
var nCellX = m_nXpos;
var nCellW = 13;
m_bCursorOn = !m_bCursorOn;
// XOR the cursor location image to draw/erase the cursor
var imgData = m_ctx.getImageData( nCellX, nCellY, nCellW, nCellH );
var data = imgData.data;
for(var i = 0; i < data.length; i += 4)
{
data[i] ^= 255;
data[i + 1] ^= 255;
data[i + 2] ^= 255;
}
m_ctx.putImageData( imgData, nCellX, nCellY );
}
function MoveCursor()
{
if (m_bCursorOn)
DrawCursor();
m_nXpos += 13;
if ( m_nXpos >1000)
m_nXpos = 0;
DrawCursor();
}
window.onload = function()
{
m_canvas = $('#myCanvas')[0];
m_ctx = m_canvas.getContext("2d");
m_canvas.width = window.innerWidth;
m_canvas.height = window.innerHeight;
m_ctx.fillStyle = "black";
m_ctx.fillRect( 0, 0, m_canvas.width, m_canvas.height );
setInterval( function(){ DrawCursor();}, 301 ); // cursor blink
setInterval( function(){ MoveCursor();}, 501 );
};
</script>
</head>
<body >
<canvas id="myCanvas" width="800" height="600"></canvas>
</body>
</html>
1 ответ
Скорее всего, это проблема, связанная с тем, как браузер Safari работает с форматом заднего буфера и соотношением пикселей к ширине. Это не связано с субпикселями, так как вы имеете дело с пиксельным буфером напрямую.
Ваш код правильный как таковой; Обходной путь - принудительно заставить значения ширины целочисленными для холста.
Измените эти строки:
m_canvas.width = window.innerWidth;
m_canvas.height = window.innerHeight;
в
m_canvas.width = window.innerWidth|0; // removes fractions
m_canvas.height = window.innerHeight|0;
и проблема должна исчезнуть в Safari ( модифицированный jsbin здесь).
Надеюсь это поможет.
Добавил обратно оригинальный ответ:
Добавьте эту строку:
m_canvas.style.width = ((m_canvaswindow.width/13)|0)*13+'px';
в этом месте:
window.onload = function() {
m_canvas = $('#myCanvas')[0];
m_ctx = m_canvas.getContext("2d");
m_canvas.width = window.innerWidth;
m_canvas.height = window.innerHeight;
m_canvas.style.width = ((m_canvas.width/13)|0)*13+'px';
// possibly you will need this for height as well
m_ctx.fillStyle = "black";
m_ctx.fillRect( 0, 0, m_canvas.width, m_canvas.height );
setInterval( DrawCursor, 301 );
setInterval( MoveCursor, 501 );
};
Это заставит размер соответствовать размеру курсора (если вы измените размер курсора, тогда, конечно, также должны быть обновлены значения 13 - просто используйте вместо этого динамическое значение).
Кроме того: это явно проблема с браузером Safari, и ответ здесь, естественно, будет действовать только как временное решение. Вы ничего не можете сделать с этой проблемой, кроме как дождаться ее решения (вы должны сообщить об этом команде Safari).