2013-08-05 2 views
0

Я хочу визуализировать огромную диаграмму, которая нарисована в холсте HTML5. Как показано ниже, давайте представим карту мира, невозможно одновременно визуализировать все это с «приличной» детальностью. Поэтому на моем холсте я хотел бы, чтобы мы могли обтекать его с помощью мыши, чтобы увидеть другие страны, которые не видны.Переместить холст HTML5 с фоновым изображением

Кто-нибудь знает, как реализовать этот вид панорамирования в холсте HTML5? Еще одна особенность - увеличение и уменьшение масштаба.

canvas diagram Я видел несколько примеров, но я не мог заставить их работать, ни швов, чтобы ответить на мой вопрос.

Заранее благодарен!

+0

Таким образом, вы в основном хотите перемещать (панорамировать) изображение внутри объекта холста HTML5, контролируемого с помощью мыши? Также увеличьте масштаб изображения. – Eric

+0

Точно! Я хотел бы перетащить изображение вокруг. – Emanuel

ответ

3

Для достижения функции панорамирования с помощью прокрутки это просто вопрос двух операций рисования, один полный и один обрезанный.

To get this result можно сделать следующие (see full code here):

переменные настройки:

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 

Настройка основных функций, которые вы используете, чтобы установить размер в зависимости от размера окна (в том числе на изменение размера):

/// 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; 

Основной функцией в этом является функция рисования. Здесь мы рисуем изображение в позиции, вычисленной движением мыши (см. Следующий раздел).

  • Первый шаг, чтобы получить этот размытый вид - установить альфа примерно на 0,2 (вы также можете нарисовать прозрачный прямоугольник сверху, но это более эффективно).
  • Тогда нарисуйте полное изображение.
  • Сброс альфа
  • Нарисуйте заглядывание с помощью вырезания с исправленными смещениями для источника.

-

/// 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]); 
} 

Теперь это вопрос обработки мыши вниз, двигаться и вверх, и вычислить корректоры -

В мыши вниз мы храним текущие позиции мыши, которые мы будем использовать для счетные дельты на перемещениях мыши:

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; 
} 

Здесь мы используем дельты, чтобы избежать изображений прыжков установки угла в положение мыши , Дельты передаются в виде смещения к update функции:

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(); 
    } 
} 

И, наконец, на мыши вверх мы делаем смещение постоянной часть положения изображения:

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; 
    } 
} 

Для увеличения холста я считаю, что это уже ответили в этом сообщении - вы должны слить это с ответом, приведенным здесь:

+0

Вы определенно отправили ответ, большое спасибо! У меня теперь работает прокладка, но в отношении увеличения я уже видел этот пост, но в этом случае, когда мы хотим увеличить масштаб, мы должны перерисовать весь фоновый рисунок (переводить, масштабировать), правильно? Я пытался играть с функцией drawImage, чтобы иметь возможность масштабировать, захватывая больше фонового изображения, таким образом избегая перерисовывания фона. Возможно ли это? – Emanuel

+0

@Emanuel вы имеете в виду, как использовать квадрат в качестве лупы? Если так, вы можете сделать что-то вроде этого: http://jsfiddle.net/AbdiasSoftware/Us9nH/3/ – K3N

+0

еще раз большое спасибо за вашу помощь! Это действительно то, что вы опубликовали, но я хочу, чтобы иметь возможность увеличения, но и уменьшить масштаб в соответствии с прокруткой мыши. Кстати, заметили ли вы на своей первой скрипке, что когда вы обходите мышью, есть какой-то увеличивающий эффект, когда вы двигаетесь к нижней части карты? Благодаря! – Emanuel

1

Чтобы сделать что-то вроде того, что вы запросили, это всего лишь случай наличия 2 холстов, каждый из которых имеет разный индекс z. одно холст меньше, чем другой, и позиция, установленная на оси x и y мыши.

Затем вы просто показываете на маленьком холсте правильное изображение, основанное на положении x и y на маленьком холсте по отношению к более крупному холсту.

Однако ваш вопрос требует определенного решения, которое, если только кто-то не сделал, и они готовы просто сбросить свой код, вам будет трудно получить полный ответ. Надеюсь, все будет хорошо.

Смежные вопросы