【问题标题】:Resize rectangle with four corners using fabric js使用fabric js调整具有四个角的矩形大小
【发布时间】:2017-09-13 03:38:58
【问题描述】:

var canvas = document.getElementById('canvas'),
    ctx = canvas.getContext('2d'),
    rect = {
        x: 150,
        y: 100,
        w: 123,
        h: 58
    },
    handlesSize = 4,
    currentHandle = false,
    drag = false;

function init() {
    canvas.addEventListener('mousedown', mouseDown, false);
    canvas.addEventListener('mouseup', mouseUp, false);
    canvas.addEventListener('mousemove', mouseMove, false);
}

function point(x, y) {
    return {
        x: x,
        y: y
    };
}

function dist(p1, p2) {
    return Math.sqrt((p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y));
}

function getHandle(mouse) {
    if (dist(mouse, point(rect.x, rect.y)) <= handlesSize) return 'topleft';
    if (dist(mouse, point(rect.x + rect.w, rect.y)) <= handlesSize) return 'topright';
    if (dist(mouse, point(rect.x, rect.y + rect.h)) <= handlesSize) return 'bottomleft';
    if (dist(mouse, point(rect.x + rect.w, rect.y + rect.h)) <= handlesSize) return 'bottomright';
    if (dist(mouse, point(rect.x + rect.w / 2, rect.y)) <= handlesSize) return 'top';
    if (dist(mouse, point(rect.x, rect.y + rect.h / 2)) <= handlesSize) return 'left';
    if (dist(mouse, point(rect.x + rect.w / 2, rect.y + rect.h)) <= handlesSize) return 'bottom';
    if (dist(mouse, point(rect.x + rect.w, rect.y + rect.h / 2)) <= handlesSize) return 'right';
    return false;
}

function mouseDown(e) {
    if (currentHandle) drag = true;
    draw();
}

function mouseUp() {
    drag = false;
    currentHandle = false;
    draw();
}

function mouseMove(e) {
    var previousHandle = currentHandle;
    if (!drag) currentHandle = getHandle(point(e.pageX - this.offsetLeft, e.pageY - this.offsetTop));
    if (currentHandle && drag) {
        var mousePos = point(e.pageX - this.offsetLeft, e.pageY - this.offsetTop);
        switch (currentHandle) {
            case 'topleft':
                rect.w += rect.x - mousePos.x;
                rect.h += rect.y - mousePos.y;
                rect.x = mousePos.x;
                rect.y = mousePos.y;
                break;
            case 'topright':
                rect.w = mousePos.x - rect.x;
                rect.h += rect.y - mousePos.y;
                rect.y = mousePos.y;
                break;
            case 'bottomleft':
                rect.w += rect.x - mousePos.x;
                rect.x = mousePos.x;
                rect.h = mousePos.y - rect.y;
                break;
            case 'bottomright':
                rect.w = mousePos.x - rect.x;
                rect.h = mousePos.y - rect.y;
                break;

            case 'top':
                rect.h += rect.y - mousePos.y;
                rect.y = mousePos.y;
                break;

            case 'left':
                rect.w += rect.x - mousePos.x;
                rect.x = mousePos.x;
                break;

            case 'bottom':
                rect.h = mousePos.y - rect.y;
                break;

            case 'right':
                rect.w = mousePos.x - rect.x;
                break;
        }
    }
    if (drag || currentHandle != previousHandle) draw();
}

function draw() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = 'black';
    ctx.fillRect(rect.x, rect.y, rect.w, rect.h);
    if (currentHandle) {
        var posHandle = point(0, 0);
        switch (currentHandle) {
            case 'topleft':
                posHandle.x = rect.x;
                posHandle.y = rect.y;
                break;
            case 'topright':
                posHandle.x = rect.x + rect.w;
                posHandle.y = rect.y;
                break;
            case 'bottomleft':
                posHandle.x = rect.x;
                posHandle.y = rect.y + rect.h;
                break;
            case 'bottomright':
                posHandle.x = rect.x + rect.w;
                posHandle.y = rect.y + rect.h;
                break;
            case 'top':
                posHandle.x = rect.x + rect.w / 2;
                posHandle.y = rect.y;
                break;
            case 'left':
                posHandle.x = rect.x;
                posHandle.y = rect.y + rect.h / 2;
                break;
            case 'bottom':
                posHandle.x = rect.x + rect.w / 2;
                posHandle.y = rect.y + rect.h;
                break;
            case 'right':
                posHandle.x = rect.x + rect.w;
                posHandle.y = rect.y + rect.h / 2;
                break;
        }
        ctx.globalCompositeOperation = 'xor';
        ctx.beginPath();
        ctx.arc(posHandle.x, posHandle.y, handlesSize, 0, 2 * Math.PI);
        ctx.fill();
        ctx.globalCompositeOperation = 'source-over';
    }
}

init();
draw();
&lt;canvas id="canvas" width="500" height="500"&gt;&lt;/canvas&gt;
此链接包含我需要在织物 js 中调整具有固定角的矩形区域大小而无需悬停作为示例的示例。

【问题讨论】:

标签: javascript jquery canvas html5-canvas fabricjs


【解决方案1】:

您可以通过以下方式完成...

  • 设置lockMovementX = truelockMovementY = true 以防止矩形对象移动
  • 禁用角控件以防止矩形对象的角调整大小(使其固定角)

let canvas = new fabric.Canvas('canvas');
let rect = new fabric.Rect({
  left: 100,
  top: 100,
  fill: '#07C',
  width: 100,
  height: 100,
  hoverCursor: 'default'
});
canvas.add(rect);

// prevent movement
rect.lockMovementX = true;
rect.lockMovementY = true;

// prevent corner resizing
rect.setControlsVisibility({
  tl: false,
  tr: false,
  bl: false,
  br: false,
  mtr: false
});
canvas {
  border: 1px solid lightgrey;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.9/fabric.min.js"></script>
<canvas id="canvas" width="300" height="300"></canvas>

【讨论】:

  • 调整矩形的大小应该与鼠标指针位置相对应,而不是简单的向某个方向拖动。
  • 在上面的例子中,它只是以某种纵横比调整大小,而不是鼠标指针的位置。
  • @RobsonJohny mouse pointer's position 是什么意思?
  • 如果您尝试在我发布的示例中调整矩形的大小,它只是根据鼠标指针调整大小。(即:调整矩形的形状对应于画布内的鼠标指针区域位置) .但是在不对应鼠标指针区域位置的情况下以某些纵横比调整大小的织物矩形)
  • 感谢您的回复。但是,我想我上次没有正确解释。
猜你喜欢
  • 1970-01-01
  • 2011-11-18
  • 2013-03-13
  • 1970-01-01
  • 2018-08-25
  • 2018-10-18
  • 1970-01-01
  • 1970-01-01
  • 2015-02-25
相关资源
最近更新 更多