Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Прокрутка фона на canvas. (https://javascript.ru/forum/misc/57900-prokrutka-fona-na-canvas.html)

levshkatov 25.08.2015 18:47

Прокрутка фона на canvas.
 
Необходимо сделать цикличную прокрутку фона/изображения на канвасе.
Причем в разные стороны (двигается туда, где находится курсор мыши).
Как это проще реализовать? Знаю, что для цикличной прокрутки только по оси Х достаточно такого вот кода:
var draw = canvas.getContext('2d');
var bg = new Image();
function drawBg() {  
	
    draw.drawImage(bg, -vx, 0);
	draw.drawImage(bg, bg.width - vx, 0);
    if (Math.abs(vx) > bg.width) {
		vx = 0;
	} 
    vx += 0.5;
}

Анимирую с помощью вот этого: requestAnimationFrame.
К мышке я смогу прикрутить, у меня не получается именно движение картинки в разных направлениях. Не совсем понимаю, для чего нужен второй метод отрисовки изображения, хотя без него цикла не получается.

tsigel 25.08.2015 19:07

Возможно как вариант забрать данные о картинке по пикселям с помощью getImageData, а затем при смешении рисовать соответсвующие куски картинки. Во всяком случае на сколько я понимаю с помощью drawImage нельзя нарисовать кусок картинки, а вылезать за холст не хочется.

levshkatov 25.08.2015 19:17

tsigel, да ну и ладно, вылезем за холст, ничего страшного. Фон и предполагается что будет больше размеров канваса. Пользователь начинает движение где-то с середины изображения (довольно широкая рамка изображения по краям остается за пределами канваса) Таким образом оно и прокручивается в разные стороны. Просто рисовать куски с помощью getImageData мне кажется намного сложнее, а главное ресурсозатратнее.

рони 25.08.2015 19:48

levshkatov,
<!DOCTYPE HTML>

<html>

<head>
  <title>Untitled</title>
  <meta charset="utf-8">
</head>

<body>
 <canvas width="800" height="600" id="canvas"></canvas>
  <script>
    var canvas = document.getElementById('canvas');
    var c = canvas.getContext('2d');
    var img = new Image();
img.onload = function() {
  c.drawImage(img,0,0);

}
img.src = "http://nevsepic.com.ua/uploads/posts/2011-10/1317583107_www.nevsepic.com.ua_kazumasa-uchio-ucchiey-003.jpg";
function getMousePos(canvas, event) {
        var rect = canvas.getBoundingClientRect();
        return {
          x: event.clientX - rect.left,
          y: event.clientY - rect.top
        };
      }


canvas.addEventListener('mousemove', function(event) {
     var mousePos = getMousePos(canvas, event);
     var x = (img.width - canvas.width)  * (mousePos.x /canvas.width );
     var y = (img.height - canvas.height)  * (mousePos.y /canvas.height );
         c.clearRect(0, 0, canvas.width, canvas.height);
         c.drawImage(img,-x|0,-y|0);
        });


  </script>

</body>

</html>

levshkatov 25.08.2015 19:58

рони, не совсем то, что нужно. Мне необходима анимация циклического прокручивания картинки. Например, пока мышка направлена вверх, картинка движется вверх, и не прекращает двигаться. (одна заканчивается, следом за ней такая же, бесшовная, картинка) Здесь же "обозрение картинки в увеличенном масштабе".

рони 25.08.2015 22:57

levshkatov,
<!DOCTYPE HTML>

<html>

<head>
  <title>Untitled</title>
  <meta charset="utf-8">
</head>

<body>
 <canvas width="800" height="600" id="canvas"></canvas>
 <script>
var canvas = document.getElementById("canvas");
var c = canvas.getContext("2d");
var img = new Image;
img.onload = function() {
    drawBg()
};
img.src = "http://www.vector-eps.com/wp-content/gallery/old-model-paper-background-textures/thumbs/thumbs_old-model-paper-texture3.jpg";
var dir = {
    vx: 0,
    vy: 0,
    step: 2,
    x: 0,
    y: 0
};

function drawBg() {
    requestAnimationFrame(drawBg);
    c.clearRect(0, 0, canvas.width, canvas.height);
    for (var k = -img.height; k < canvas.height + img.height; k += img.height-1)
    for (var i = -img.width; i < canvas.width + img.width; i += img.width-1) c.drawImage(img, i - dir.vx, k - dir.vy);
    if (Math.abs(dir.vx) > img.width) dir.vx = 0;
    dir.vx += dir.x * dir.step;
    if (Math.abs(dir.vy) > img.height) dir.vy = 0;
    dir.vy += dir.y * dir.step
}

function getMousePos(canvas, event) {
    var rect = canvas.getBoundingClientRect();
    return {
        x: event.clientX - rect.left,
        y: event.clientY - rect.top
    }
}
var x = 0,
    y = 0,
    timer;
canvas.addEventListener("mousemove", function(event) {
    window.clearTimeout(timer);
    timer = window.setTimeout(function() {
        var mousePos = getMousePos(canvas, event);
        var a = Math.atan2(mousePos.y - y, mousePos.x - x);
        dir.x = -Math.cos(a);
        x = mousePos.x;
        dir.y = -Math.sin(a);
        y = mousePos.y
    }, 50)
});
  </script>

</body>

</html>

levshkatov 26.08.2015 08:40

Большое спасибо за помощь!

рони 26.08.2015 08:49

levshkatov,
таймер можно убрать при желании строки 48,50, 51, 58

Dabonirc 07.08.2023 10:51

хочу использовать твой код но мне он непонятен
сделай пожста версию попроще:

просто функцию(x, y) которая двигает зацикленный фон на x и y

без мышки и таймера

вот так я расшифровал код но не уверен что верно:
в коде нет блоков в if и for - поэтому мне трудно его прочитать

var направление = {
    горизонтально: 0,
    вертикально: 0,
    шаг: 1,
    x: 0,
    y: 0
};

function сдвинуть_фон() {

    контекст.clearRect(0, 0, canvas.width, canvas.height)
    
    for (var k = -img.height; k < canvas.height + img.height; k += img.height-1)
    {
        for (var i = -img.width; i < canvas.width + img.width; i += img.width-1) 
        {
            контекст.drawImage(img, i - направление.горизонтально, k - направление.вертикально)
            
            if (Math.abs(направление.горизонтально) > img.width) 
            { 
                направление.горизонтально = 0 
            }

            направление.горизонтально += направление.x * направление.шаг;

            if (Math.abs(направление.вертикально) > img.height)
            {
                направление.вертикально = 0
            }

            направление.вертикально += направление.y * направление.шаг
        }
    }
}

рони 07.08.2023 14:06

Dabonirc,
<!DOCTYPE HTML>
<html>

<head>
    <title>Untitled</title>
    <meta charset="utf-8">
</head>

<body>
    <canvas width="800" height="600" id="canvas"></canvas>
    <script>
        let canvas = document.getElementById("canvas");
        let c = canvas.getContext("2d");
        let img = new Image;
        img.onload = function() {
            drawBg()
        };
        img.src = "http://www.vector-eps.com/wp-content/gallery/old-model-paper-background-textures/thumbs/thumbs_old-model-paper-texture3.jpg";
        let dir = {
            vx: 0,
            vy: 0,
            step: 2.3, //>0
            x: .7,// 1 ... -1
            y: .5 // 1 ... -1
        };

        function drawBg() {
            requestAnimationFrame(drawBg);
            c.clearRect(0, 0, canvas.width, canvas.height);
            for (let k = -img.height; k < canvas.height + img.height; k += img.height - 1)
                for (let i = -img.width; i < canvas.width + img.width; i += img.width - 1) c.drawImage(img, i - dir.vx, k - dir.vy);
            if (Math.abs(dir.vx) > img.width) dir.vx = 0;
            dir.vx += dir.x * dir.step;
            if (Math.abs(dir.vy) > img.height) dir.vy = 0;
            dir.vy += dir.y * dir.step
        }
    </script>
</body>

</html>


Часовой пояс GMT +3, время: 09:55.