javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > JS浏览器截图功能

用JavaScript实现浏览器截图功能的全过程

作者:ZCKKKing

在Web开发中实现网页截图功能可以帮助我们保存网页内容、生成海报、制作截图分享等,这篇文章主要介绍了用JavaScript实现浏览器截图功能的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

最近项目中要实现一个需求:
 

用户希望在上传文件时能够直接截图上传,并且要求能够截图浏览器外的内容。

多方查找之下找到了类似的解决方案,但个人感觉操作上有些抽象,仅供参考。

HTML部分

CSS部分

JS部分(原生JS为例)

完整代码

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>截图</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            font-family: 'Microsoft YaHei', sans-serif;
            background-color: #f5f5f5;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            height: 100vh;
            overflow: hidden;
        }

        .container {
            text-align: center;
            background-color: white;
            padding: 30px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
            max-width: 800px;
            width: 100%;
        }

        .button {
            background-color: #12B7F5;
            color: white;
            border: none;
            padding: 10px 20px;
            border-radius: 4px;
            cursor: pointer;
            font-size: 16px;
            transition: background-color 0.3s;
            margin-top: 10px;
        }

        .button:hover {
            background-color: #0E9AD7;
        }

        #screenshot-container {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            z-index: 9999;
        }

        #screenshot-canvas {
            position: absolute;
            top: 0;
            left: 0;
            cursor: crosshair;
        }

        .selection-area {
            position: absolute;
            border: 2px dashed #12B7F5;
            background-color: rgba(18, 183, 245, 0.1);
            pointer-events: none;
        }

        .toolbar {
            position: absolute;
            background-color: white;
            border-radius: 4px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
            padding: 5px;
            display: flex;
            gap: 5px;
        }

        .toolbar button {
            background-color: #12B7F5;
            color: white;
            border: none;
            padding: 5px 10px;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
        }

        .toolbar button:hover {
            background-color: #0E9AD7;
        }
    </style>
</head>
<body>
    <div class="container">
        <button id="start-screenshot" class="button">开始截图</button>
    </div>

    <div id="screenshot-container">
        <canvas id="screenshot-canvas"></canvas>
        <div class="selection-area" id="selection-area" style="display: none;"></div>
        <div class="toolbar" id="screenshot-toolbar" style="display: none;">
            <button id="confirm-screenshot">确认</button>
            <button id="cancel-screenshot">取消</button>
        </div>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            // 元素引用
            const startButton = document.getElementById('start-screenshot');
            const screenshotContainer = document.getElementById('screenshot-container');
            const canvas = document.getElementById('screenshot-canvas');
            const ctx = canvas.getContext('2d');
            const selectionArea = document.getElementById('selection-area');
            const toolbar = document.getElementById('screenshot-toolbar');
            const confirmButton = document.getElementById('confirm-screenshot');
            const cancelButton = document.getElementById('cancel-screenshot');

            // 截图状态
            let isCapturing = false;
            let isSelecting = false;
            let startX = 0;
            let startY = 0;
            let endX = 0;
            let endY = 0;
            let screenCapture = null;

            // 设置画布大小
            function setCanvasSize() {
                canvas.width = window.innerWidth;
                canvas.height = window.innerHeight;
            }

            // 开始截图
            async function startScreenshot() {
                try {
                    // 请求屏幕捕获
                    screenCapture = await navigator.mediaDevices.getDisplayMedia({
                        video: {
                            cursor: 'always'
                        }
                    });

                    // 获取视频轨道
                    const videoTrack = screenCapture.getVideoTracks()[0];
                    
                    // 创建视频元素以捕获屏幕
                    const videoElem = document.createElement('video');
                    videoElem.srcObject = screenCapture;
                    
                    // 当视频加载完成后,绘制到画布上
                    videoElem.onloadedmetadata = () => {
                        videoElem.play();
                        
                        // 设置画布大小
                        setCanvasSize();
                        
                        // 绘制视频帧到画布
                        ctx.drawImage(videoElem, 0, 0, canvas.width, canvas.height);
                        
                        // 停止视频轨道
                        videoTrack.stop();
                        
                        // 显示截图容器
                        screenshotContainer.style.display = 'block';
                        isCapturing = true;
                    };
                } catch (err) {
                    console.error('截图失败:', err);
                    alert('截图失败,请确保您已授予屏幕捕获权限。');
                }
            }

            // 更新选择区域
            function updateSelectionArea() {
                const width = Math.abs(endX - startX);
                const height = Math.abs(endY - startY);
                const left = Math.min(startX, endX);
                const top = Math.min(startY, endY);

                selectionArea.style.display = 'block';
                selectionArea.style.left = left + 'px';
                selectionArea.style.top = top + 'px';
                selectionArea.style.width = width + 'px';
                selectionArea.style.height = height + 'px';

                // 更新工具栏位置
                toolbar.style.display = 'flex';
                toolbar.style.left = (left + width + 5) + 'px';
                toolbar.style.top = (top + height + 5) + 'px';
            }

            // 将Base64数据转换为File对象
            function dataURLtoFile(dataurl, filename) {
                // 将Base64数据拆分为MIME类型和实际数据
                const arr = dataurl.split(',');
                const mime = arr[0].match(/:(.*?);/)[1]; // 获取MIME类型
                const bstr = atob(arr[1]); // 解码Base64数据
                let n = bstr.length;
                const u8arr = new Uint8Array(n);

                // 将解码后的数据转换为Uint8Array
                while (n--) {
                    u8arr[n] = bstr.charCodeAt(n);
                }

                // 创建并返回File对象
                return new File([u8arr], filename, { type: mime });
            }

            // 确认截图
            function confirmScreenshot() {
                if (!isCapturing) return;

                const width = Math.abs(endX - startX);
                const height = Math.abs(endY - startY);
                const left = Math.min(startX, endX);
                const top = Math.min(startY, endY);

                // 创建新画布以保存选定区域
                const resultCanvas = document.createElement('canvas');
                resultCanvas.width = width;
                resultCanvas.height = height;
                const resultCtx = resultCanvas.getContext('2d');

                // 将选定区域绘制到新画布
                resultCtx.drawImage(
                    canvas,
                    left, top, width, height,
                    0, 0, width, height
                );

                // 在这里获取截图结果
                // 如果想生成成一个Base64url
                const base64Url = resultCanvas.toDataURL();
                
                // 如果想生成成一个File对象
                const resultFile = dataURLtoFile(resultCanvas.toDataURL(), "截图.png")

                // 重置截图状态
                resetScreenshot();
            }

            // 取消截图
            function cancelScreenshot() {
                resetScreenshot();
            }

            // 重置截图状态
            function resetScreenshot() {
                isCapturing = false;
                isSelecting = false;
                selectionArea.style.display = 'none';
                toolbar.style.display = 'none';
                screenshotContainer.style.display = 'none';
                ctx.clearRect(0, 0, canvas.width, canvas.height);
            }

            // 事件监听器
            startButton.addEventListener('click', startScreenshot);
            confirmButton.addEventListener('click', confirmScreenshot);
            cancelButton.addEventListener('click', cancelScreenshot);

            // 鼠标事件处理
            canvas.addEventListener('mousedown', function(e) {
                if (!isCapturing) return;

                isSelecting = true;
                startX = e.clientX;
                startY = e.clientY;
                endX = e.clientX;
                endY = e.clientY;
                updateSelectionArea();
            });

            canvas.addEventListener('mousemove', function(e) {
                if (!isSelecting) return;

                endX = e.clientX;
                endY = e.clientY;
                updateSelectionArea();
            });

            canvas.addEventListener('mouseup', function() {
                isSelecting = false;
            });

            // 键盘快捷键
            document.addEventListener('keydown', function(e) {
                // Alt + A 开始截图
                if (e.altKey && e.key === 'a') {
                    e.preventDefault();
                    startScreenshot();
                }
                
                // Enter 确认截图
                if (e.key === 'Enter' && isCapturing) {
                    confirmScreenshot();
                }
                
                // Esc 取消截图
                if (e.key === 'Escape' && isCapturing) {
                    cancelScreenshot();
                }
            });

            // 窗口大小改变时重新设置画布大小
            window.addEventListener('resize', function() {
                if (isCapturing) {
                    setCanvasSize();
                }
            });
        });
    </script>
</body>
</html>

总结

姑且算是实现了这个需求,但是实现效果并不是很理想,只能说仅供参考吧

到此这篇关于用JavaScript实现浏览器截图功能的文章就介绍到这了,更多相关JS浏览器截图功能内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文