перетаскиваемое текстовое поле поверх изображения холста - PullRequest
0 голосов
/ 20 января 2020

Привет всем, поэтому я пытаюсь сделать перетаскиваемое текстовое поле на холсте. Но когда я не могу понять, функциональность. Все, что я хочу сделать, это перетащить текстовое поле вверху изображения. Было бы здорово просто нажать и перетащить текст. Кто-нибудь знает, как это сделать? это становится головной болью. если у вас есть какие-либо предложения, которые были бы великолепны.

image

1 Ответ

1 голос
/ 21 января 2020

Перетаскивание содержимого холста.

Используйте mousedown, mouseup и mousemove прослушиватели событий только для обновления состояния мыши. Например, положение и состояние кнопки.

Логика c для перетаскивания визуализированных элементов должна быть сделана в основном рендере l oop. В примере renderLoop вызывает handleMouse перед рендерингом любого контента.

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

Перетаскивание start и перетаскивание move

В handleMouse проверьте, не нажата ли мышь mouse.button === true

  • , если это так, и не перетаскивает, и есть текст для перетащите под мышью, установите перетаскивание в true и рассчитайте смещение от позиции мыши до текста x, y
  • «Перетаскивание», если мышь нажата и перетаскивание true, затем обновите выбранную позицию текста с помощью установив его в положение мыши плюс смещение перетаскивания

Drag drop

Если мышь нажата mouse.button === false

  • и перетаскивание равно true, тогда установите dragging в ложь. Выбранный текстовый элемент отбрасывается
  • , устанавливая selectedText на первый текстовый элемент под мышью.

Render l oop

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

Текстовые элементы

Я расширил массив для обработки текстовых элементов. Важная функция почти такая же, как если бы вы textItems.getUnder(point) возвращали текстовый элемент в point.x point.y. Если точка не находится над текстовым элементом, функция возвращает undefined.

Пример

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

Надеюсь, это поможет.

requestAnimationFrame(renderLoop);          
const ctx = canvas.getContext("2d");
var selectedText;
const mouse = {
    x: 0, 
    y: 0,
    bounds: canvas.getBoundingClientRect(),
    button: false,
    dragging: false,
    dragOffsetX: 0,
    dragOffsetY: 0,
    events(event) {  // mouse event handler should only record current mouse state
        const m = mouse;
        if (event.type === "mousedown") { m.button = true }
        else if (event.type === "mouseup") { m.button = false }
        m.x = event.pageX - m.bounds.left - scrollX;
        m.y = event.pageY - m.bounds.top - scrollY;
    }   
};
document.addEventListener("mousemove", mouse.events);
document.addEventListener("mousedown", mouse.events);
document.addEventListener("mouseup", mouse.events);
function renderLoop(time) {
    if (!textItems.length) { addDemoText() }
    textItems[0].update("Frame time: " + time.toFixed(3) + "ms");
    var cursor = "default";
    handleMouse();
    ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
    textItems.draw(ctx);
    if (selectedText) { 
        cursor = mouse.dragging ? "none" : "move";
        ctx.fillStyle = "#08F"; // highlight selected text
        selectedText.draw();
    }
    canvas.style.cursor = cursor;
    requestAnimationFrame(renderLoop); 
}
function handleMouse() {
    const m = mouse;
    const text = selectedText;
    if (m.button) {
        if (!m.dragging && text !== undefined) {
            m.dragging = true;
            m.dragOffsetX = text.x - m.x;
            m.dragOffsetY = text.y - m.y;
        }
        if (m.dragging) {
            text.x = m.x + m.dragOffsetX;
            text.y = m.y + m.dragOffsetY;
            text.keepOnCanvas()
        }
    } else {
        if (m.dragging) {                 
            selectedText = undefined;
            m.dragging = false;
        }
        selectedText = textItems.getUnder(m);
    }
}

const textItems = Object.assign([],{
    getUnder(point) { // returns undefined if no text under
        for(const t of this) {
            if (point.x >= t.x && point.x <= t.x + t.width && point.y < t.y + t.size && point.y >= t.y) {
                return t;
            }
        }
    },
    add(ctx, text, x,  y, color = "#000", size = 24, font = "arial") { // context ctx to measure the text
        var item;
        ctx.font = size + "px " + font;
        const width = ctx.measureText(text).width;
        this.push(item = {text, x, y, color, font, size, width,
            draw() { 
                ctx.font = this.size + "px " + this.font;
                ctx.textBaseline = "hanging";
                ctx.fillText(this.text, this.x, this.y);
            },
            keepOnCanvas() {
                const maxX = ctx.canvas.width - this.width;
                const maxY = ctx.canvas.height - this.size;
                this.x < 0 && (this.x = 0);
                this.y < 0 && (this.y = 0);
                this.x >= maxX && (this.x = maxX - 1);
                this.y >= maxY && (this.y = maxY - 1);
            }, 
            update(text) {
                this.text = text;
                ctx.font = this.size + "px " + this.font;
                this.width = ctx.measureText(text).width;
                this.keepOnCanvas();
            }
        });
        return item;
    },
    draw(ctx) {
        for(const text of this) {
            ctx.fillStyle = text.color;
            text.draw();
        }
    }
});
function addDemoText() { 
    var idx = 0;
    textItems.add(ctx, "", 0, 0);
    for (const t of "HI there! Some text to move with the mouse. Move mouse ? over text items. Click and drag to move the text. ? ?".split(" ")) {
        const text = textItems.add(ctx, t, idx % (canvas.width - 80), (idx / (canvas.width - 80) | 0) * 26 + 26);
        text.keepOnCanvas();
        idx += text.width + 12
    }
}
canvas {
    border: 1px solid black;
};
<canvas id="canvas" width="600" height="180">
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...