移动带有背景图片的HTML5画布 [英] Move HTML5 Canvas with a background image

查看:340
本文介绍了移动带有背景图片的HTML5画布的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要显示一个绘制在HTML5画布中的巨大图表。如下所述,让我们想象世界地图,它不可能用一个体面的细节同时可视化。因此,在我的画布上,我想使用鼠标来查看其他不可见的国家。



有没有人知道如何在HTML5画布中实现这种平移?另一个功能是放大和缩小。




我看过几个例子,但是我不能让他们工作,也不能缝合以解决我的问题。



提前感谢! / p>

解决方案

使用窥视孔实现平移功能只需两个绘制操作,一个完整和一个剪辑。 / p>

取得这个结果 ,您可以执行以下操作( 查看此处的完整代码 ):



设置变量:

  var ctx = canvas.getContext ('2d'),

ix = 0,iy = 0,/// image position
offsetX = 0,offsetY = 0,/// current offsetets
deltaX, deltaY,/// deltas from mouse down
mouseDown = false,///在鼠标拖动
img = null,/// background
rect,/// rect position
rectW = 200,rectH = 150; ///高亮区的大小

设置用于根据窗口设置大小的主要功能大小(包括调整大小):

  /// calc画布w / h相对于窗口以及
///设置矩形在中心与预定义
/// width和height
函数setSize(){
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
rect = [canvas.width * 0.5 - rectW * 0.5,
canvas.height * 0.5 - rectH * 0.5,
rectW,rectH]
update();
}

///窗口调整大小,因此重新计算canvas和rect
window.onresize = setSize;

这里的主要功能是绘制函数。这里我们在通过鼠标移动计算的位置绘制图像(见下一节)。




  • 第一步,可以将alpha设置为大约0.2(您也可以在顶部绘制一个透明的矩形,但这样更有效率)。

  • 然后绘制完整的图像。

  • 重置alpha

  • 使用修正后的偏移量,使用剪辑绘制窥视孔。



-

  /// main draw 
function update(){
if(img == = null)return;

/// limit x / y as drawImage不能用负数绘制
///用于裁剪的偏移量
if(ix + offsetX> rect [0])ix = rect [0] - offsetX;
if(iy + offsetY> rect [1])iy = rect [1] - offsetY;

///清除背景以清除垃圾
ctx.clearRect(0,0,canvas.width,canvas.height);

/// make everything transparent
ctx.globalAlpha = 0.2;

///绘制完整背景
ctx.drawImage(img,ix + offsetX,iy + offsetY);

///重置alpha,因为我们需要下一次绘制的不透明度
ctx.globalAlpha = 1;

///绘制背景的剪辑版本,
///调整偏移和图像位置
ctx.drawImage(img,-ix - offsetX + rect [0 ],/// sx
-iy - offsetY + rect [1],/// sy
rect [2],rect [3],/// sw / h

/// destination
rect [0],rect [1],rect [2],rect [3]);

///通过抵消半像素来创建一个漂亮的边框
ctx.strokeRect(rect [0] + 0.5,rect [1] + 0.5,rect [2] 3]);
}

现在这是处理鼠标向下,向上移动和计算偏移 -



在鼠标下方,我们存储当前鼠标位置,我们将用它来计算鼠标移动时的增量:

  canvas.onmousedown = function(e){

///不要做任何事情,直到我们有一个图像
if(img == = null)return;

///正确的鼠标pos
var coords = getPos(e),
x = coords [0],
y = coords [1]

///将当前位置存储到calc deltas
deltaX = x;
deltaY = y;

///这里我们去..
mouseDown = true;
}

这里我们使用增量来避免图像跳转设置角落到鼠标位置。三角洲作为偏移量传递到更新函数:

 画布。 onmousemove = function(e){

///在拖动?
if(mouseDown === true){

var coords = getPos(e),
x = coords [0],
y = coords [1]

/// offset = current - 原始位置
offsetX = x - deltaX;
offsetY = y - deltaY;

///重绘我们到目前为止
update();
}
}



最后在鼠标上,部分图片位置:

  document.onmouseup = function(e){

///是在拖累?
if(mouseDown === true){
///不再有!
mouseDown = false;

/// make image pos。永久
ix + = offsetX;
iy + = offsetY;

///所以我们需要重置偏移量
offsetX = offsetY = 0;
}
}

对于缩放画布我相信这已经回答了此帖子 - 您应该能够将此与此处提供的答案合并:

缩放画布到鼠标光标


I want to visualize a huge diagram that is drawn in a HTML5 canvas. As depicted below, let’s imagine the world map, it’s impossible to visualize it all at the same time with a "decent" detail. Therefore, in my canvas I would like to be able to pan over it using the mouse to see the other countries that are not visible.

Does anyone know how to implement this sort of panning in a HTML5 canvas? Another feature would be the zoom in and out.

I've seen a few examples but I couldn't get them working nor they seam to address my question.

Thanks in advance!

解决方案

To achieve a panning functionality with a peep-hole it's simply a matter of two draw operations, one full and one clipped.

To get this result you can do the following (see full code here):

Setup variables:

var ctx = canvas.getContext('2d'),

    ix = 0, iy = 0,           /// image position
    offsetX = 0, offsetY = 0, /// current offsets
    deltaX, deltaY,           /// deltas from mouse down
    mouseDown = false,        /// in mouse drag
    img = null,               /// background
    rect,                     /// rect position
    rectW = 200, rectH = 150; /// size of highlight area

Set up the main functions that you use to set size according to window size (including on resize):

/// calc canvas w/h in relation to window as well as
/// setting rectangle in center with the pre-defined
/// width and height
function setSize() {
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    rect = [canvas.width * 0.5 - rectW * 0.5,
            canvas.height * 0.5 - rectH * 0.5,
            rectW, rectH]
    update();
}

/// window resize so recalc canvas and rect
window.onresize = setSize;

The main function in this is the draw function. Here we draw the image on the position calculated by mouse moving (see next section).

  • First step to get that washed-out look is to set alpha down to about 0.2 (you could also draw a transparent rectangle on top but this is more efficient).
  • Then draw the complete image.
  • Reset alpha
  • Draw the peep-hole using clipping with corrected offsets for the source.

-

/// main draw
function update() {
    if (img === null) return;

    /// limit x/y as drawImage cannot draw with negative
    /// offsets for clipping
    if (ix + offsetX > rect[0]) ix = rect[0] - offsetX;
    if (iy + offsetY > rect[1]) iy = rect[1] - offsetY;

    /// clear background to clear off garbage
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    /// make everything transparent
    ctx.globalAlpha = 0.2;

    /// draw complete background
    ctx.drawImage(img, ix + offsetX, iy + offsetY);

    /// reset alpha as we need opacity for next draw
    ctx.globalAlpha = 1;

    /// draw a clipped version of the background and
    /// adjust for offset and image position
    ctx.drawImage(img, -ix - offsetX + rect[0],  /// sx
                       -iy - offsetY + rect[1],  /// sy
                       rect[2], rect[3],         /// sw/h

                       /// destination
                       rect[0], rect[1], rect[2], rect[3]);

    /// make a nice sharp border by offsetting it half pixel
    ctx.strokeRect(rect[0] + 0.5, rect[1] + 0.5, rect[2], rect[3]);
}

Now it's a matter of handling mouse down, move and up and calculate the offsets -

In the mouse down we store current mouse positions that we'll use for calculating deltas on mouse move:

canvas.onmousedown = function(e) {

    /// don't do anything until we have an image
    if (img === null) return;

    /// correct mouse pos
    var coords = getPos(e),
        x = coords[0],
        y = coords[1];

    /// store current position to calc deltas
    deltaX = x;
    deltaY = y;

    /// here we go..
    mouseDown = true;
}

Here we use the deltas to avoid image jumping setting the corner to mouse position. The deltas are transferred as offsets to the update function:

canvas.onmousemove = function(e) {

    /// in a drag?
    if (mouseDown === true) {

        var coords = getPos(e),
            x = coords[0],
            y = coords[1];

        /// offset = current - original position
        offsetX = x - deltaX;
        offsetY = y - deltaY; 

        /// redraw what we have so far
        update();
    }
}

And finally on mouse up we make the offsets a permanent part of the image position:

document.onmouseup = function(e) {

    /// was in a drag?
    if (mouseDown === true) {
        /// not any more!!!
        mouseDown = false;

        /// make image pos. permanent
        ix += offsetX;
        iy += offsetY;

        /// so we need to reset offsets as well
        offsetX = offsetY = 0;
    }
}

For zooming the canvas I believe this is already answered in this post - you should be able to merge this with the answer given here:
Zoom Canvas to Mouse Cursor

这篇关于移动带有背景图片的HTML5画布的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆