Увеличьте точку (используя масштаб и перевод)

139
задан Just a student 27 September 2017 в 09:30
поделиться

2 ответа

Наконец-то решил:

 var zoomIntensity = 0.2; var canvas = document.getElementById ("холст"); var context = canvas.getContext ("2d"); var width = 600; var height = 200; var scale = 1; var originx = 0; var originy = 0; var visibleWidth = ширина; var visibleHeight = height; function draw () {// Очистить экран до белого цвета. context.fillStyle = "белый"; context.fillRect (originx, originy, 800 / масштаб, 600 / масштаб); // Рисуем черный квадрат. context.fillStyle = "черный"; context.fillRect (50,50,100,100); } // Отрисовываем цикл со скоростью 60 кадров в секунду. setInterval (розыгрыш, 1000/60); canvas.onwheel = функция (событие) {event.preventDefault (); // Получить смещение мыши. var mousex = event.clientX - canvas.offsetLeft; var mousey = event.clientY - canvas.offsetTop; // Нормализовать колесо до +1 или -1. var wheel = event.deltaY <0? 1: -1; // Вычислить коэффициент масштабирования. var zoom = Math.exp (колесо * zoomIntensity); // Перевести так, чтобы видимая исходная точка находилась в исходной точке контекста. context.translate (originx, originy); // Вычислить новое видимое начало координат. Изначально мышь находится на // расстоянии мыши / шкалы от угла, мы хотим, чтобы точка под // мышью оставалась на том же месте после увеличения, но она // находится на расстоянии mouse / new_scale от угла. Поэтому нам нужно // сместить начало координат (координаты угла), чтобы учесть это. originx - = mousex / (масштаб * масштаб) - mousex / масштаб; originy - = mousey / (масштаб * масштаб) - мышка / масштаб; // Масштабируем его (центрируем вокруг исходной точки из-за преобразования выше). context.scale (масштабирование, масштабирование); // Смещаем видимую исходную точку в правильное положение. context.translate (-originx, -originy); // Обновить масштаб и др.масштаб * = масштаб; visibleWidth = ширина / масштаб; visibleHeight = высота / масштаб; } 
   

Ключ, как указал @Tatarize , - это вычислить положение оси таким образом, чтобы точка масштабирования (указатель мыши) оставалась на том же месте после масштабирования.

Изначально мышь находится на расстоянии mouse / scale от угла, мы хотим, чтобы точка под мышью оставалась на том же месте после увеличения, но это на mouse / new_scale подальше от угла. Поэтому нам нужно сместить начало координат (координаты угла), чтобы учесть это.

originx -= mousex/(scale*zoom) - mousex/scale;
originy -= mousey/(scale*zoom) - mousey/scale;
scale *= zomm

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

55
ответ дан 23 November 2019 в 23:05
поделиться

На самом деле это очень сложная задача (математически), и я почти над этим работаю. Я задал аналогичный вопрос о Stackoverflow, но не получил ответа, но разместил его в DocType (StackOverflow для HTML / CSS) и получил ответ. Проверьте это http://doctype.com/javascript-image-zoom-css3-transforms-calculate-origin-example

Я занимаюсь созданием подключаемого модуля jQuery, который делает это (стиль Google Maps масштабирование с помощью преобразований CSS3). У меня есть бит масштабирования курсора мыши, работающий нормально, я все еще пытаюсь понять, как позволить пользователю перетаскивать холст, как вы можете это сделать в Google Maps. Когда он заработает, я опубликую здесь код, но посмотрите ссылку выше для части mouse-zoom-to-point.

Я не осознавал, что в контексте Canvas есть методы масштабирования и перевода, вы можете добиться того же, используя CSS3, например. использование jQuery:

$('div.canvasContainer > canvas')
    .css('-moz-transform', 'scale(1) translate(0px, 0px)')
    .css('-webkit-transform', 'scale(1) translate(0px, 0px)')
    .css('-o-transform', 'scale(1) translate(0px, 0px)')
    .css('transform', 'scale(1) translate(0px, 0px)');

Убедитесь, что вы установили CSS3 transform-origin на 0, 0 (-moz-transform-origin: 0 0). Использование преобразования CSS3 позволяет увеличивать масштаб чего угодно, просто убедитесь, что для контейнера DIV установлено значение overflow: hidden, чтобы не допустить выплескивания увеличенных краев по бокам.

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


Обновление: Мех! Я просто опубликую здесь код, а не заставлю вас перейти по ссылке:

$(document).ready(function()
{
    var scale = 1;  // scale of the image
    var xLast = 0;  // last x location on the screen
    var yLast = 0;  // last y location on the screen
    var xImage = 0; // last x location on the image
    var yImage = 0; // last y location on the image

    // if mousewheel is moved
    $("#mosaicContainer").mousewheel(function(e, delta)
    {
        // find current location on screen 
        var xScreen = e.pageX - $(this).offset().left;
        var yScreen = e.pageY - $(this).offset().top;

        // find current location on the image at the current scale
        xImage = xImage + ((xScreen - xLast) / scale);
        yImage = yImage + ((yScreen - yLast) / scale);

        // determine the new scale
        if (delta > 0)
        {
            scale *= 2;
        }
        else
        {
            scale /= 2;
        }
        scale = scale < 1 ? 1 : (scale > 64 ? 64 : scale);

        // determine the location on the screen at the new scale
        var xNew = (xScreen - xImage) / scale;
        var yNew = (yScreen - yImage) / scale;

        // save the current screen location
        xLast = xScreen;
        yLast = yScreen;

        // redraw
        $(this).find('div').css('-moz-transform', 'scale(' + scale + ')' + 'translate(' + xNew + 'px, ' + yNew + 'px' + ')')
                           .css('-moz-transform-origin', xImage + 'px ' + yImage + 'px')
        return false;
    });
});

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


Обновление 2: Только что заметил, что я использую transform-origin вместе с translate.Мне удалось реализовать версию, которая использует масштабирование и перевод самостоятельно, проверьте это здесь http://www.dominicpettifer.co.uk/Files/Mosaic/MosaicTest.html Подождите, пока изображения для загрузки, затем используйте колесо мыши для увеличения, также поддерживает панорамирование путем перетаскивания изображения. Он использует преобразования CSS3, но вы должны иметь возможность использовать те же вычисления для своего холста.

25
ответ дан 23 November 2019 в 23:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: