Масштабирование точки XY на холсте HTML5 в процентах - PullRequest
0 голосов
/ 21 октября 2011

Я работаю над своим первым проектом холста, и для него требуется частичная карта США с масштабированием и центром в состоянии при нажатии.

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

Моя следующая проблема заключалась в том, что клиент хотел, чтобы только 13 состояний были вытянуты, но не размещены для масштабирования друг против друга.(Например, поместите Огайо и Иллинойс рядом на холсте и не обращайте внимания на Индиану).Моим решением было ввести фиксированную X, Y «постоянную» для каждого состояния, чтобы после масштабирования добавить значение XY для этого состояния и сделать эту точку для рисования.

for ( var j = 0; j < state.myPolygons.length; ++j) {
    context.beginPath();
    context.lineWidth = lineWidth;
    context.strokeStyle = stateStroke;
    context.fillStyle = stateFill;
    for ( var k = 0; k < state.myPolygons[j].myXVals.length; ++k ) {
        var x = parseFloat(state.myPolygons[j].myXVals[k]*state.scale)+state.posX;
        var y = parseFloat(state.myPolygons[j].myYVals[k]*state.scale)+state.posY;
        y = canvas.height - y;
        if ( k == 0 ) 
            context.moveTo(x,y);
        else 
            context.lineTo(x,y);
    }
    context.closePath();
    context.fill();
    context.stroke();
}

Эффект щелчка по состоянию, его увеличения и центрирования на холсте был достигнут путем определения целевого масштаба и количества шагов.Я получаю разницу между целевой шкалой и текущей шкалой и делю ее на количество шагов, чтобы выяснить, сколько нужно добавить к шкале состояния в каждом «кадре».Пример: начальный масштаб Огайо составляет 1,97 от найденных координат.Моя цель по шкале Огайо - 3,75%.Я получаю разницу (1,78) и делю ее на 45 (определенный набор шагов) для рисования.Это дает мне 0,039 как инкрементатор моего масштаба в каждом кадре.Затем я переключаюсь, пока текущий масштаб моего состояния меньше целевого масштаба.Однако, опять же, поскольку мне нужно манипулировать XY рендеринга, у меня есть константа увеличения и масштабирования для каждого состояния, которое добавляется к вычисленному XY, чтобы оно могло «скользить» к центру холста.

Все это прекрасно работает, и у меня есть Калифорнийский зум / скользящий слева направо, Огайо, скользящий справа налево и т. Д. --- Вот моя проблема.

У меня есть ряд точек, чтобы указать клиентские замкив состоянии.Это простые X Y, на которых я рисую круг.Первоначальный рендеринг карты включает в себя цикл для прохождения каждого набора состояний местоположений.Я применяю тот же масштабный коэффициент и posX, переменные posY, чтобы отрегулировать окончательное размещение точки относительно окончательного рендеринга состояния

for (var loc in state.Locations) {
    var locx = parseFloat(state.Locations[loc].x*state.scale)+state.posX
    var locy =parseFloat(state.Locations[loc].y*state.scale)+state.posY;
    var txt=state.Locations[loc].text;
    var lnk=state.Locations[loc].link;
    context.beginPath();
    context.arc(locx,locy,locationSize,0,Math.PI*2,true);
    context.fillStyle = locationFill;
    context.closePath();
    context.fill();
    context.stroke();                           
}

Однако, когда состояние масштабируется, логика масштабирования дляточки не удается.Применяется шкала состояний для данного кадра

x = parseFloat(activeState.myPolygons[j].myXVals[k]*activeState.scale)+activeState.posX;
y = parseFloat(activeState.myPolygons[j].myYVals[k]*activeState.scale)+activeState.posY;

Когда я применяю это к заданному местоположению в состоянии с

locx = parseFloat(activeState.Locations[loc].x*activeState.scale)+activeState.posX;
locy = parseFloat(activeState.Locations[loc].y*activeState.scale)+activeState.posY;

, я получаю X довольно близко, но в ОгайоНапример, Y где-то недалеко от Флориды.В других штатах, таких как Калифорния, ситуация еще хуже: их точки начинают «укладываться» друг на друга и в конечном итоге «расстилаются» друг с другом.

Я пытаюсь выяснить, какие триггерные функции необходимы дляувеличивайте и уменьшайте положение XY в местоположении по отношению к текущему масштабу состояния и держите его на том же пути, по которому движется состояние в анимации (как увеличение, так и уменьшение).

Моя последняя попытка до того, как прийти сюда, состояла в том, чтобы получить начальный XY местоположения и сравнить его расстояние с ПОСЛЕДНИМ XY массива состояний.Затем я пытался найти угол линии, соединяющей эти 2 точки, и затем использовал все это для масштабирования.Я все еще чувствую, что с этим подходом я могу что-то сделать, я просто не могу этого сделать.

Спасибо всем, что нашли время прочитать это, я ценю любую помощь, которую вы можете предложить

1 Ответ

0 голосов
/ 21 октября 2011

Вы можете просто посмотреть на бумагу, которую я положил на ваш стол, ту, на которой написано уравнение.Тем не менее, SVG будет более оптимальным для проекта, поскольку вы можете легко сгруппировать вещи, используя тег g, а затем просто масштабировать всю группу.

Однако, поскольку вы вынуждены использовать canvas на этом этапе: Вам придется масштабировать режиссера вверх и вниз, используя trig, учитывая угол начальной точки к точке местоположения и РАЗНИЦУ влево или вправо от исходного расстояния.Я объясню более подробно с фактическими уравнениями, когда вы позволите мне вернуть мне эту статью.Тем не менее, единственная строка, которую вам действительно нужно изменить на этом этапе:

locy = parseFloat(activeState.Locations[loc].y*activeState.scale)+activeState.posY;
...