求助,如何在手机端实现生成自由拖动的选取框?

 function startResize(e, handle) {
            isResizing = true;
            currentHandle = handle;
            startX = (e.touches ? e.touches[0].clientX : e.clientX);
            startY = (e.touches ? e.touches[0].clientY : e.clientY);
            startWidth = parseInt(document.defaultView.getComputedStyle(selectionBox).width, 10);
            startHeight = parseInt(document.defaultView.getComputedStyle(selectionBox).height, 10);
            startLeft = selectionBox.offsetLeft;
            startTop = selectionBox.offsetTop;
            e.preventDefault();
        }

        function resize(e) {
            if (!isResizing) return;

            let clientX = (e.touches ? e.touches[0].clientX : e.clientX);
            let clientY = (e.touches ? e.touches[0].clientY : e.clientY);
            let width, height, left, top;
            const containerRect = imageContainer.getBoundingClientRect();

            if (currentHandle.classList.contains('nw')) {
                width = startWidth - (clientX - startX);
                height = startHeight - (clientY - startY);
                left = startLeft + (clientX - startX);
                top = startTop + (clientY - startY);

                if (width > 10 && height > 10 && left >= 0 && top >= 0) {
                    selectionBox.style.width = width + 'px';
                    selectionBox.style.height = height + 'px';
                    selectionBox.style.left = left + 'px';
                    selectionBox.style.top = top + 'px';
                }
            } else if (currentHandle.classList.contains('ne')) {
                width = startWidth + (clientX - startX);
                height = startHeight - (clientY - startY);
                top = startTop + (clientY - startY);

                if (width > 10 && height > 10 && (startLeft + width) <= containerRect.width && top >= 0) {
                    selectionBox.style.width = width + 'px';
                    selectionBox.style.height = height + 'px';
                    selectionBox.style.top = top + 'px';
                }
            } else if (currentHandle.classList.contains('sw')) {
                width = startWidth - (clientX - startX);
                height = startHeight + (clientY - startY);
                left = startLeft + (clientX - startX);

                if (width > 10 && height > 10 && left >= 0 && (startTop + height) <= containerRect.height) {
                    selectionBox.style.width = width + 'px';
                    selectionBox.style.height = height + 'px';
                    selectionBox.style.left = left + 'px';
                }
            } else if (currentHandle.classList.contains('se')) {
                width = startWidth + (clientX - startX);
                height = startHeight + (clientY - startY);

                if (width > 10 && height > 10 && (startLeft + width) <= containerRect.width && (startTop + height) <= containerRect.height) {
                    selectionBox.style.width = width + 'px';
                    selectionBox.style.height = height + 'px';
                }
            }
            e.preventDefault();
        }

        function stopResize() {
            if (isResizing) {
                isResizing = false;
            }
        }

        resizeHandles.forEach(handle => {
            handle.addEventListener('mousedown', (e) => startResize(e, handle));
            handle.addEventListener('touchstart', (e) => startResize(e, handle), { passive: false });
        });

        window.addEventListener('mousemove', resize);
        window.addEventListener('touchmove', resize, { passive: false });

        window.addEventListener('mouseup', stopResize);
        window.addEventListener('touchend', stopResize);

        const screenshotButton = document.getElementById('screenshot-button');
        screenshotButton.addEventListener('click', function () {
            // This is where you can handle the screenshot logic
            console.log('Selected area:', selectionBox.getBoundingClientRect());
        });

这个网页需要在手机端上使用,但是对于如何更改选取框的位置和大小没有思路。现在生成的选取框是无法拖动的。

阅读 583
avatarAI BotBETA

在手机端实现生成自由拖动的选取框,通常涉及监听触摸事件(如touchstarttouchmovetouchend)并在画布上绘制相应的矩形框。以下是一个简化的实现思路,它会在你提供的HTML和JavaScript代码的基础上增加选取框的功能:

  1. 初始化选取框的状态(如位置、大小)。
  2. 监听触摸事件以更新选取框的状态。
  3. 在画布上绘制选取框。

以下是实现这一功能的代码示例:

// ... 省略之前的代码 ...

// 初始化选取框状态
let selecting = false; // 是否正在选取
let selectStart = { x: 0, y: 0 }; // 选取开始的坐标
let selectEnd = { x: 0, y: 0 }; // 选取结束的坐标

// 监听触摸事件
cameraCanvas.addEventListener('touchstart', function(event) {
    if (event.touches.length === 1) { // 单点触摸
        selecting = true;
        selectStart = { x: event.touches[0].clientX, y: event.touches[0].clientY };
        selectEnd = { x: event.touches[0].clientX, y: event.touches[0].clientY };
    }
});

cameraCanvas.addEventListener('touchmove', function(event) {
    if (selecting && event.touches.length === 1) {
        selectEnd = { x: event.touches[0].clientX, y: event.touches[0].clientY };
        drawSelectionBox();
    }
});

cameraCanvas.addEventListener('touchend', function(event) {
    if (selecting && event.touches.length === 0) {
        selecting = false;
        // 在这里可以添加处理选取框的逻辑,比如获取选取区域的像素数据等
        console.log('选取框位置:', selectStart, '到', selectEnd);
    }
});

// 绘制选取框
function drawSelectionBox() {
    cameraCtx.clearRect(0, 0, cameraCanvas.width, cameraCanvas.height); // 清除画布
    cameraCtx.drawImage(video, 0, 0, cameraCanvas.width, cameraCanvas.height); // 重新绘制视频帧

    if (selecting) {
        cameraCtx.strokeStyle = 'red'; // 选取框颜色
        cameraCtx.lineWidth = 2; // 选取框线宽
        cameraCtx.beginPath();
        cameraCtx.rect(
            Math.min(selectStart.x, selectEnd.x), // 选取框左上角x坐标
            Math.min(selectStart.y, selectEnd.y), // 选取框左上角y坐标
            Math.abs(selectEnd.x - selectStart.x), // 选取框宽度
            Math.abs(selectEnd.y - selectStart.y) // 选取框高度
        );
        cameraCtx.stroke(); // 绘制选取框
    }
}

// ... 省略之前的代码 ...

请注意,这段代码是一个简单的示例,它使用了clientXclientY坐标来定义选取框的位置,这些坐标是相对于浏览器视口的。你可能需要将这些坐标转换为相对于画布的坐标,特别是如果画布有偏移或者缩放的话。此外,这段代码没有处理多点触控的情况,如果需要支持多点触控,你需要相应地修改事件监听和处理逻辑。

还要注意的是,这段代码在touchmove事件中不断清除画布并重新绘制视频帧和选取框,这可能会导致性能问题,特别是在低性能设备上。为了优化性能,你可以考虑只在选取框发生变化时重绘选取框,或者使用离屏画布来减少重绘次数。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏