Zoom in/out of the canvas by drawing a rectangle to highlight an area

49 Views Asked by At

I'm trying to create a canvas zoom-in/out functionality by drawing a rectangle to highlight an area. I'm using a project to read dxf files. https://github.com/ieskudero/three-dxf-viewer/

I have a Raycasting class that implements zooming in/out using the mouse wheel.

I found a ready-made solution for drawing a rectangle to highlight the zoom area: https://jsfiddle.net/d9BPz/546/ Drawing a rectangle using click, mouse move, and click

But I can't figure out how to scale the canvas according to the obtained rectangle coordinates.

import { Raycaster } from 'three';

export class Raycasting {

    constructor(container, camera, targets) {

        this.camera = camera;
        this.container = container;
        this.raycaster = new Raycaster();
        this._calculateThreshold();

        this.targets = targets;

        //detect zoom change and change the threshold accordingly
        this.container.addEventListener('wheel', () => {
            this._calculateThreshold();
        });

    }

    raycast(pointer) {

        this.raycaster.setFromCamera(pointer, this.camera);

        const intersects = this.raycaster.intersectObjects(this.targets, true);

        return intersects.length === 0 ? null : intersects[0];
    }

    _calculateThreshold() {
        const size = {
            width: this.camera.right / this.camera.zoom - this.camera.left / this.camera.zoom,
            height: this.camera.top / this.camera.zoom - this.camera.bottom / this.camera.zoom
        };
        const threshold = Math.min(size.width, size.height);
        this.raycaster.params.Line.threshold = threshold / 500;
    }

    _drawZoomRectangle(callback) {
        const container = document.getElementById('canvas3d');

        function setMousePosition(e) {
            var ev = e || window.event; //Moz || IE
            if (ev.pageX) { //Moz
                mouse.x = ev.pageX + window.pageXOffset;
                mouse.y = ev.pageY + window.pageYOffset;
            } else if (ev.clientX) { //IE
                mouse.x = ev.clientX + document.body.scrollLeft;
                mouse.y = ev.clientY + document.body.scrollTop;
            }
        }

        var mouse = {
            x: 0,
            y: 0,
            startX: 0,
            startY: 0
        };
        var element = null;

        container.onmousemove = function (e) {
            setMousePosition(e);
            if (element !== null) {
                element.style.width = Math.abs(mouse.x - mouse.startX) + 'px';
                element.style.height = Math.abs(mouse.y - mouse.startY) + 'px';
                element.style.left = (mouse.x - mouse.startX < 0) ? mouse.x + 'px' : mouse.startX + 'px';
                element.style.top = (mouse.y - mouse.startY < 0) ? mouse.y + 'px' : mouse.startY + 'px';
            }
        };

        container.onmousedown = function () {
            mouse.startX = mouse.x;
            mouse.startY = mouse.y;
            element = document.createElement('div');
            element.className = 'zoom-rectangle';
            element.style.left = mouse.x + 'px';
            element.style.top = mouse.y + 'px';
            container.appendChild(element);
            container.style.cursor = 'crosshair';
        };

        container.onmouseup = function () {
            element.remove();
            element = null;
            container.style.cursor = 'default';
            callback(mouse);
        };
    }

    zoomIn() {
        console.log('zoom in');
        this._drawZoomRectangle(this.completeZoomIn);
    }

    completeZoomIn(mouse) {
        console.log('complete zoom in');
        console.log(mouse);
        // Try to zoom in here
    }

    zoomOut() {
        console.log('zoom out');
        this._drawZoomRectangle(this.completeZoomOut);
    }

    completeZoomOut(mouse) {
        console.log('complete zoom out');
        console.log(mouse);
        // Try to zoom out here
    }
}

I thought that I would be able to implement my own calculation of the camera location based on the method _calculateThreshold. But I can't change the zoom value even to a constant value.

this.raycaster.params.Line.threshold = 1.2;

0

There are 0 best solutions below