Проблема MouseMove на холсте

Я пытаюсь получить квадратную форму, чтобы следовать за мышью на холсте, используя «mousemove».

function start(){
    var canvastmp = document.getElementById("myCanvas")
    var canvas = canvastmp.getContext("2d");
    window.addEventListener('mousemove', trevor, false);
}
function trevor(pos){
    canvas.clearRect(0,0,600,400);
    var x = pos.clientX;
    var y = pos.clientY;
    canvas.fillRect(x-25,y-25,100,100);
}
window.addEventListener('load',start,false);

Когда я запускаю его, вообще ничего не появляется. Я уже некоторое время настраиваю и просматриваю его, и я не могу понять, что не так. Еще раз прошу прощения за совершенно нубский вопрос! Любая помощь очень ценится.

Кроме того, я использую Chrome, если это поможет.


person trevnewt    schedule 14.10.2012    source источник


Ответы (3)


Проблема в том, что canvas выходит за рамки. Чтобы вернуть его в область видимости, либо вставьте функцию trevor внутрь функции start, либо передайте контекст холста как переменную в замыкание:

function start(){
    var canvastmp = document.getElementById("myCanvas")
    var ctx = canvastmp.getContext("2d");
    window.addEventListener('mousemove', function(pos){trevor(ctx,pos)}, false);
}
function trevor(ctx, pos){
    ctx.clearRect(0,0,600,400);
    var x = pos.clientX;
    var y = pos.clientY;
    ctx.fillRect(x-25,y-25,100,100);
}
window.addEventListener('load',start,false);

Или, альтернативно, используйте более объектный подход:

function trevor(ctx) {
    function moveHandler(pos) {
        ctx.clearRect(0,0,600,400);
        ctx.fillRect(pos.clientX - 25, pos.clientY - 25, 100, 100);
    }
}
var myTrevor = trevor((document.getElementById('myCanvas')).getContext('2d'));
window.addEventListener('load', myTrevor.moveHandler, false);

Самое приятное в этом то, что контексты всегда актуальны; trevor знает только контекст, который ему дан, и код, устанавливающий обработчик событий, также извлекает контекст.

person Phil H    schedule 14.10.2012

Ваша переменная canvas определена в функции start, но затем, когда вы ссылаетесь на нее в функции trevor, она выходит за рамки.

Определите его из обеих функций, чтобы он подходил для обеих, и это работает.

См. - http://jsfiddle.net/sync/mE4B4/.

var canvas;

function start() {
    var canvastmp = document.getElementById("myCanvas");
    canvas = canvastmp.getContext("2d");
    window.addEventListener('mousemove', trevor, false);
}

function trevor(pos) {
    canvas.clearRect(0, 0, 600, 400);
    var x = pos.clientX;
    var y = pos.clientY;
    canvas.fillRect(x - 25, y - 25, 100, 100);
}

window.addEventListener('load', start, false);​
person sync    schedule 14.10.2012
comment
Глобальные переменные — это простой способ «исправить» проблемы с областью действия, но это не очень хорошая практика. Вместо этого попробуйте замыкание, чтобы передать контекст Тревору. - person Phil H; 14.10.2012

Вы упомянули, что используете Chrome. Если это так, взгляните на встроенный инспектор (Инструменты > Инструменты разработчика). На вкладке Консоль отображаются ошибки. Если вы посмотрите туда, вы увидите что-то вроде Canvas not defined, что является полезным советом.

'canvas' var был вне области видимости. Будет работать следующее:

function mousemove(pos) {
  var c = document.getElementById("myCanvas");
  var ctx = c.getContext("2d");
  ctx.clearRect(0,0,600,400);

  var x = pos.clientX;
  var y = pos.clientY;

  ctx.fillStyle="#FF0000";
  ctx.fillRect(x-25,y-25,50,50);
}

window.addEventListener('mousemove', mousemove, false);

ЖИВАЯ ДЕМО ЗДЕСЬ

person Gabriel Florit    schedule 14.10.2012
comment
Это будет медленнее, так как внутри цикла есть запрос DOM (getElementById). Контекст холста не меняется между движениями мыши, так зачем тратить время на то, чтобы получить его снова? - person Phil H; 14.10.2012