4.5KB原生html+js+css实现图片打印位置的坐标和尺寸获取

一般用于图片打印文字或图片的坐标获取,代码来自AI有改动。

功能:本地图选择后不上传直接可比划线条作为对角线得到矩形,动态显示坐标

按下鼠标开始松开鼠标结束。有细微BUG但不影响坐标获取。

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Draw Rectangle on Image</title>
    <style>
        #container {
            position: relative;
            display: inline-block;
            border: 1px solid #333;
            cursor: crosshair;
            overflow: hidden;
        }
        .rectangle {
            position: absolute;
            border: 1px dashed red;
            background-color: rgba(255, 0, 0, 0.1);
        }
        textarea {
            width: 100%;
            height: 80px;
            margin-top: 10px;
            font-family: monospace;
        }
    </style>
</head>
<body>
    <h2>Draw Rectangle and Track Position</h2>

    <input type="file" id="imageUpload" accept="image/*">
    <div id="container"></div>

    <h3>Current Rectangle Info</h3>
    <textarea id="currentInfo" readonly>X: -, Y: -, Width: -, Height: -</textarea>

    <h3>Log of Rectangles</h3>
    <textarea id="logInfo" readonly></textarea>

    <script>
        const container = document.getElementById('container');
        const imageUpload = document.getElementById('imageUpload');
        const currentInfo = document.getElementById('currentInfo');
        const logInfo = document.getElementById('logInfo');

        let startX, startY, rect, isDrawing = false;

        // Change the background image when a file is uploaded and adjust container size
        imageUpload.addEventListener('change', (event) => {
            const file = event.target.files[0];
            if (file) {
                const reader = new FileReader();
                reader.onload = (e) => {
                    const img = new Image();
                    img.onload = () => {
                        container.style.width = `${img.width}px`;
                        container.style.height = `${img.height}px`;
                        container.style.backgroundImage = `url('${e.target.result}')`;
                    };
                    img.src = e.target.result;
                };
                reader.readAsDataURL(file);
            }
        });

        container.addEventListener('mousedown', (event) => {
            // Remove any previous rectangle and reset info
            if (rect) {
                rect.remove();
            }
            currentInfo.value = "X: -, Y: -, W: -, H: -";

            // Start drawing the rectangle
            startX = event.offsetX;
            startY = event.offsetY;
            isDrawing = true;

            // Create a new rectangle element
            rect = document.createElement('div');
            rect.classList.add('rectangle');
            rect.style.left = `${startX}px`;
            rect.style.top = `${startY}px`;
            rect.style.width = `0px`;
            rect.style.height = `0px`;
            container.appendChild(rect);
        });

        container.addEventListener('mousemove', (event) => {
            if (!isDrawing) return;

            // Calculate current width and height based on mouse position
            const currentX = event.offsetX;
            const currentY = event.offsetY;
            const width = Math.abs(currentX - startX);
            const height = Math.abs(currentY - startY);

            // Set rectangle position and size based on mouse direction
            rect.style.left = `${Math.min(startX, currentX)}px`;
            rect.style.top = `${Math.min(startY, currentY)}px`;
            rect.style.width = `${width}px`;
            rect.style.height = `${height}px`;

            // Update the current info display
            currentInfo.value = `X: ${Math.min(startX, currentX)}, Y: ${Math.min(startY, currentY)}, W: ${width}, H: ${height}`;
        });

        container.addEventListener('mouseup', (event) => {
            if (!isDrawing) return;
            isDrawing = false;

            // Record the final rectangle details
            const finalX = parseInt(rect.style.left);
            const finalY = parseInt(rect.style.top);
            const finalWidth = parseInt(rect.style.width);
            const finalHeight = parseInt(rect.style.height);

            // Append the log information to the logInfo textarea
            logInfo.value += `Rectangle - X: ${finalX}, Y: ${finalY}, W: ${finalWidth}, H: ${finalHeight}\n`;

            // Stop drawing for a new session
            isDrawing = false;
        });
    </script>
</body>
</html>
相关推荐
不听话坏6 小时前
Ignition篇(下 一) 动态执行前的事情
开发语言·前端·javascript
小二·7 小时前
React 19 + Next.js 15 现代前端开发实战:App Router / Server Components / 流式渲染
前端·javascript·react.js
CHNE_TAO_EMSM9 小时前
Android studio 打开文件时自动下载源码
前端·javascript·android studio
竹林81811 小时前
从 ethers.js 迁移到 Viem:一个签名验证 Bug 让我彻底放弃旧爱
javascript
你挚爱的强哥11 小时前
Vue2 实现 1.5s 十连击监听(连续点击若干次),封装通用可复用点击检测工具,不用 data!Vue 封装通用连击监听方法,支持自定义时长与点击次数
前端·javascript·vue.js
半个落月12 小时前
用 LangChain.js 手写一个能读写文件和执行命令的 Mini Cursor
javascript·人工智能·后端
天外天-亮12 小时前
HBuilder X 使用 uview-plus 方式
开发语言·javascript·hbuilder x·uview-plus
我有满天星辰13 小时前
Vue项目脚手架之争:create-vue与Vue CLI全面对比
前端·javascript·vue.js
多加点辣也没关系17 小时前
JavaScript|第9章:对象 — 基础
开发语言·javascript·ecmascript
我有满天星辰17 小时前
Vue 2 与 Vue 3 计算属性完全指南:从 Options API 到组合式 API 的演进
前端·javascript·vue.js