Я получил много помощи от этого сайта, но у меня, кажется, проблема собрать все это вместе. В частности, в JS я знаю, как
а) нарисовать изображение на холсте
б) заставьте прямоугольник следовать за курсором (Рисование на холсте) и (http://billmill.org/static/canvastutorial/ball.html)
c) нарисуйте прямоугольник, чтобы использовать его в качестве фона
Чего я не могу понять, так это того, как использовать прямоугольник в качестве фона, а затем нарисовать изображение (png) на холсте и заставить его следовать за курсором.
То, что у меня есть до сих пор, выглядит так:
var canvas = document.getElementByID('canvas');
var ctx = canvas.getContext('2d');
var WIDTH = canvas.width;
var HEIGHT = canvas.height;
var bgColor = '#FFFFFF';
var cirColor = '#000000';
clear = function() {
ctx.clearRect(0, 0, WIDTH, HEIGHT);
}
drawIMG = function(x,y,r) {
ctx.fillStyle = cirColor;
ctx.beginPath();
ctx.arc(x, y, r, 0, Math.PI*2, true);
ctx.closePath();
ctx.fill();
}
draw = function() {
ctx.fillStyle = bgColor;
clear();
ctx.fillRect(0, 0, WIDTH, HEIGHT);
drawIMG(150, 150, 30);
drawIMG(300, 500, 12);
};
draw();
Это отобразит элемент холста HTML5, высота и ширина которого указаны в HTML и поэтому являются переменными, с белым прямоугольником размером с холст под двумя черными кругами в точках (150 150) и (300 500). Он делает это отлично.
Однако я не знаю, как заставить JS рисовать .png поверх того, что следует за курсором. Как я уже сказал, я смог выполнить большинство шагов по отдельности, но понятия не имею, как их комбинировать. Я знаю, например, что я должен сделать
img = new Image();
а потом
img.src = 'myPic.png';
в какой-то момент. Их нужно сочетать с модификаторами позиции, такими как
var xPos = pos.clientX;
var yPos = pos.clientY;
ctx.drawImage(img, xPos, yPos);
Но я понятия не имею, как это сделать, сохраняя при этом какие-либо другие вещи, которые я написал выше (в частности, фон).
Спасибо за ваше терпение, если вы прочитали все это. Я не спал какое-то время и боюсь, что мой мозг настолько загорелся, что я не узнал бы ответ, если бы он разделся догола и исполнил Макарену. Я был бы признателен за любую помощь, которую вы могли бы прислать мне, но я думаю, что рабочий пример будет лучше. Я посвящен в религию программирования и до сих пор лучше всего учусь, бессовестно копируя, а затем изменяя.
В любом случае, заранее примите мою оптимистическую благодарность.
Ответ 1 · рейтинг 1 · kemicofa ghost
Во-первых, я сделал анимированный фиолетовый огонь, который следует за мышью. Нажмите (edit больше не существует) здесь, чтобы просмотреть его.
Прежде чем продолжить, я рекомендую вам посетить эти веб-сайты: http://www.williammalone.com/articles/create-html5-canvas-javascript-sprite-animation/
Уильям рассказывает об основных приемах анимации холста.
http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/ Пол Айриш рассказывает о функции рекурсивной анимации, которая вращается со скоростью 60 кадров в секунду.
Использование обоих их туториалов - неплохое начало для анимации.
Теперь, насколько я понимаю, вам нужен один "фон" и одна анимация, которая следует за курсором. Первое, что вы должны иметь в виду, это то, что когда вы рисуете на холсте, все, на чем вы рисуете, заменяется. Итак, первое, что я заметил, что вызовет проблемы с производительностью, это тот факт, что вы очищаете весь холст, а не то, что нужно очистить.
Что вам нужно сделать, так это запомнить положение и размер вашего движущегося элемента. Неважно, какую форму он принимает, потому что ваш clearRect() должен полностью удалить его.
Теперь вы, наверное, спросите, а что, если я нарисую прямоугольник на заднем плане. Ну, это вызовет проблему. У вас есть два решения. Либо (а) очистите фон и анимацию движения и снова нарисуйте их в том же порядке, либо (б) поскольку вы знаете, что ваш фон никогда не будет двигаться, создайте второй холст с position = absolute. , z-index = -1 , и его расположение такое же, как и у первого холста.
Таким образом, вам никогда не придется беспокоиться о фоне, и вы сможете сосредоточиться на текущей анимации.
Теперь, возвращаясь к части кодирования, первое, что вам нужно сделать, это скопировать рекурсивную функцию Пола Айриша:
(function() {
var lastTime = 0;
var vendors = ['webkit', 'moz'];
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
window.cancelAnimationFrame =
window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame)
window.requestAnimationFrame = function(callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() { callback(currTime + timeToCall); },
timeToCall);
lastTime = currTime + timeToCall;
return id;
};
if (!window.cancelAnimationFrame)
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
}());
Тогда вопрос, как его использовать? Если вы перейдете здесь, вы сможете увидеть, как это было сделано:
function fireLoop()
{
window.requestAnimationFrame(fireLoop);
fire.update();
fire.render();
console.log('you spin me right round baby right round');
follow();
}
Это петля, которую я использую. Каждую секунду функция Пола Айриша будет вызывать основной цикл. В этой петле. Я обновляю информацию, выбираю нужную анимацию, которую нужно нарисовать, а затем рисую на холсте (после удаления предыдущего элемента).
Функция follow выбирает следующие координаты для анимации. Вам придется изменить эту часть, так как вы не хотите перемещать холст, а перемещать анимацию. Вы можете использовать тот же код, но вам нужно применить местоположение к тому месту, где вы хотите рисовать на холсте.
function follow()
{
$(fireCanvas).offset({
top: getTop(),
left: getLeft()
});
}
function getTop()
{
var off = $(fireCanvas).offset();
if(off.top != currentMousePos.y - $(fireCanvas).height() + 10)
{
if(off.top > currentMousePos.y - $(fireCanvas).height() + 10)
{
return off.top - 1;
}
else
{
return off.top + 1;
}
}
}
function getLeft()
{
var off = $(fireCanvas).offset();
if(off.left != currentMousePos.x - $(fireCanvas).width()/2)
{
if(off.left > currentMousePos.x - $(fireCanvas).width()/2)
{
return off.left - 1;
}
else
{
return off.left + 1;
}
}
}
var currentMousePos = { x: -1, y: -1 };
$(document).mousemove(function(event) {
currentMousePos.x = event.pageX;
currentMousePos.y = event.pageY;
});
Если вы хотите, чтобы я подробно рассказал о чем-то конкретном, дайте мне знать.