CSS转换后单击坐标:scale

时间:2018-12-18 06:01:42

标签: javascript resize transform mouse scale

我正在使用图像缩放器,因此可以选择调整尺寸的尺寸,例如1920x1080,然后可以在这些尺寸内拖动图像,就像Photoshop想要裁剪或调整图像的尺寸一样,我内置了“缩放”功能,您可以在其中缩放工作空间,缩放功能是通过将CSS的“工作空间”尺寸减半并使用transform:scale()

来实现的

现在,仅右上角的手柄可以调整大小,并且在使用1比例尺时可以正常工作,如果将比例尺更改为0.5(第9行),然后再试一次,您会发现鼠标X和Y计算有误,如果您在演示的第88行看到调整大小时设置了图像框的X和Y的位置,我知道这个数字需要以某种方式缩放,尽管我什至不知道从哪里开始解决这个问题数学上

https://codepen.io/anon/pen/XojMZB

class Cropper {
constructor() {
    this.css_class = {
        loading: 'loading'
    };
    this.default_scale = 1; //eg: 0.5 = 50% or 0.25 = 25%
    this.current_scale = null;
    this.crop_width = 1920;
    this.crop_height = 1080;
    this.metric_pixel = 'px';
    this.metric_scheme = this.metric_pixel;
    this.callbacks = {};
    // this.is_dragging_image = false;
    this.loading = true;
    this.resize_acceleration = 2;
    this.image_pos = {
        width: 0,
        height: 0,
        currentX: 0,
        currentY: 0,
        initialX: 0,
        initialY: 0,
        offsetX: 0,
        offsetY: 0,
    };
    this.resize_state = {};
    this.registerElements();

    /**
     *  Start up when our image has been loaded
     **/
    this.cropper_target_image.onload = () => {
        this.init();
    };
}
getCanvasScale() {
    return this.current_scale || this.default_scale
}
getCanvasScaleCalc() {
    return (1 / this.getCanvasScale())
}
getCanvasWidth(metric = true) {
    let scheme = (metric) ? this.metric_scheme : 0;
    return (this.crop_width / this.getCanvasScaleCalc()) + scheme
}
getCanvasHeight(metric = true) {
    let scheme = (metric) ? this.metric_scheme : 0;
    return (this.crop_height / this.getCanvasScaleCalc()) + scheme
}
getNaturalImageWidth(metric = true) {
    let scheme = (metric) ? this.metric_pixel : 0;
    return this.cropper_target_image.naturalWidth + scheme
}
getNaturalImageHeight(metric = true) {
    let scheme = (metric) ? this.metric_pixel : 0;
    return this.cropper_target_image.naturalHeight + scheme
}

//Image manipulation
moveImage(x, y) {
    // this.resize_state.container_left = x;
    // this.resize_state.container_top = y;
    this.cropper_image_dragger.style.transform = `translate3d(${ x }px, ${ y }px, 0)`;
}

//Resize Events
resizeBegin(mouseEvent) {
    mouseEvent.preventDefault();
    mouseEvent.stopPropagation();
    this.saveMouseState(mouseEvent);
    document.addEventListener('mousemove', this, true);
    document.addEventListener('mouseup', this, true);
}

resizing(mouseEvent) {
    let mouse = {},
        width, height, left, top, constrain = false;
    mouse.x = (mouseEvent.clientX);
    mouse.y = (mouseEvent.clientY);

    if (this.resize_state.click_target === this.resize_anchors.top_left) {
        width = (this.resize_state.container_width) - (mouse.x - this.resize_state.container_left);
        height = (this.resize_state.container_height) - (mouse.y - this.resize_state.container_top);

        left = (mouse.x);
        top = (mouse.y);
        // if(constrain || mouseEvent.shiftKey){
        //     top = mouse.y - ((width / this.getNaturalImageWidth(false) * this.getNaturalImageHeight(false)) - height);
        // }
    }
    this.resizeImage(width, height);
    this.moveImage(left, top);
    // this.saveMouseState(mouseEvent);
}
endResize(mouseEvent) {
    mouseEvent.preventDefault();
    this.saveMouseState(mouseEvent);
    document.removeEventListener('mousemove', this, true);
    document.removeEventListener('mouseup', this, true);
}
resizeImage(width, height) {
    this.cropper_image_dragger.style.width = width + 'px';
    this.cropper_image_container.style.width = width + 'px';
    this.cropper_image_dragger.style.height = height + 'px';
    this.cropper_image_container.style.height = height + 'px'
};
saveMouseState(mouseEvent) {
    // Save the initial event details and container state
    let drag_pos = this.cropper_image_dragger.getBoundingClientRect();

    this.resize_state.container_width = this.cropper_image_dragger.offsetWidth;
    this.resize_state.container_height = this.cropper_image_dragger.offsetHeight;
    this.resize_state.container_left = drag_pos.left;
    this.resize_state.container_top = drag_pos.top;
    this.resize_state.mouse_x = (mouseEvent.clientX || mouseEvent.pageX || mouseEvent.touches[0].clientX); // + window.pageXOffset
    this.resize_state.mouse_y = (mouseEvent.clientY || mouseEvent.pageY || mouseEvent.touches[0].clientY); // + window.pageYOffset
    this.resize_state.click_target = mouseEvent.target;

    if (mouseEvent.touches) {
        this.resize_state.touches = [];

        [].forEach.call(mouseEvent.touches, function(i, ob) {
            this.resize_state.touches[i] = {};
            this.resize_state.touches[i].clientX = 0 + ob.clientX;
            this.resize_state.touches[i].clientY = 0 + ob.clientY;
        });
    }
    this.resize_state.evnt = mouseEvent
}

//init
registerElements() {
    this.cropper_wrapper = document.getElementById('cropper-wrap');
    this.cropper_wrapper.classList.add(this.css_class.loading);

    this.cropper_container = document.getElementById('cropper-container');
    this.cropper_true_dimension = document.getElementById('true-dimension');
    this.cropper_true_anchor = document.getElementById('true-anchor');
    this.cropper_image_dragger = document.getElementById('the-image-dragger');
    this.cropper_image_container = document.getElementById('the-image-container');
    this.cropper_target_image = document.getElementById('cropper-target-image');
    this.resize_anchors_wrap = document.getElementById('resize-anchors');
    let resize_anchors = this.resize_anchors_wrap.getElementsByClassName('resize-anchor');
    this.resize_anchors = {
        top_left: resize_anchors[0],
        top_right: resize_anchors[1],
        bottom_left: resize_anchors[2],
        bottom_right: resize_anchors[3]
    };
}
removeResize() {
    this.resize_anchors_wrap.removeEventListener("mousedown", this, false);
}
registerEvents() {
    this.resize_anchors_wrap.addEventListener("mousedown", this, false);
    this.resize_anchors_wrap.addEventListener("mouseup", this, false);
}
init() {
    this.registerEvents();

    //wrapper
    this.cropper_container.style.width = this.getCanvasWidth();
    this.cropper_container.style.height = this.getCanvasHeight();
    this.cropper_container.style.margin = 'auto';

    //Setup True Dimension Elements
    this.cropper_true_dimension.style.transform = `scale(${ this.getCanvasScale() })`;
    this.cropper_true_dimension.style.width = this.crop_width + this.metric_scheme;
    this.cropper_true_dimension.style.height = this.crop_height + this.metric_scheme;

    //anchor
    this.cropper_true_anchor.style.width = this.crop_width + this.metric_scheme;
    this.cropper_true_anchor.style.height = this.crop_height + this.metric_scheme;

    this.cropper_image_dragger.style.width = this.getNaturalImageWidth();
    this.cropper_image_dragger.style.height = this.getNaturalImageHeight();

    this.cropper_image_container.style.width = this.getNaturalImageWidth();
    this.cropper_image_container.style.height = this.getNaturalImageHeight();

    let init_image_x = this.getCanvasWidth(false) - (this.getNaturalImageWidth(false) / this.getCanvasScaleCalc());
    let init_image_y = this.getCanvasHeight(false) - (this.getNaturalImageHeight(false) / this.getCanvasScaleCalc());

    this.moveImage(init_image_x, init_image_y);
    this.image_pos = {
        width: this.getNaturalImageWidth(false),
        height: this.getNaturalImageHeight(false),
        //position on canvas
        currentX: init_image_x,
        currentY: init_image_y,
        initialX: init_image_x,
        initialY: init_image_y,
        offsetX: init_image_x / 2,
        offsetY: init_image_y / 2,
    };
    this.moveImage(0, 0);
    this.loading = false;
    this.cropper_wrapper.classList.remove(this.css_class.loading);
    return true;
}

handleEvent(event) {
    switch (event.type) {
        //This is just used for listeners you will need to trash throughout lifecycle
        //ps. The drag events live forever so they're outside of this built-in listener that we only use for trashing purposes
        case "mousedown":
            this.resizeBegin(event);
            break;
        case "mousemove":
            this.resizing(event);
            break;
        case "mouseup":
            this.endResize(event);
            break;
        default:
            return console.warn(this.constructor.name + '.handleEvent could not find a matching event type');
    }
}}let cropper = new Cropper();

0 个答案:

没有答案