【源码分享】使用download属性将canvas保存为PNG格式(兼容移动端)

  • 原创
  • 作者:程序员三丰
  • 发布时间:2024-12-03 22:41
  • 浏览量:525
随着技术的迭代更新,前端越来越强大了,很多事情不再依赖服务端就能处理。比如本文介绍的前端通过Canvas就可以绘制图像,且支持下载。本文还对移动端的支持做了兼容性处理说明。

直接上代码~~

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <title>使用download属性将<canvas>保存为PNG格式</title>
    <style>
        html {
            font-family: sans-serif;
        }

        canvas {
            background: #fff;
            border: 1px dashed;
        }

        a {
            display: inline-block;
            background: #69c;
            color: #fff;
            padding: 5px 10px;
        }
    </style>
</head>

<body>
    <p>
        按下鼠标并移动来完成你的作画
        <a href="" download="my_painting.png">下载我的绘画</a>
    </p>

    <canvas width="300" height="300"></canvas>

    <script>
        var isDrawing = false
        const canvas = document.querySelector('canvas')
        const c = canvas.getContext('2d')
        c.fillStyle = 'hotpink'
        c.rect(0, 0, 640, 360)
        c.moveTo(10, 10)
        c.lineTo(100, 100)
        c.lineTo(500, 100)
        c.lineWidth = 10;
        c.strokeStyle = 'red'
        c.stroke()

        function draw(x, y) {
            if (isDrawing) {
                c.beginPath()
                c.arc(x, y, 10, 0, Math.PI * 2)
                c.closePath()
                c.fill()
            }
        }

        canvas.addEventListener('mousemove', (event) => {
            draw(event.offsetX, event.offsetY)
        })
        canvas.addEventListener('mousedown', () => (isDrawing = true))
        canvas.addEventListener('mouseup', () => (isDrawing = false))

        function dataURLtoBlob(dataURL) {
            // 去除dataURL头部信息,只保留base64编码部分
            var parts = dataURL.split(';base64,');
            var contentType = parts[0].split(':')[1];  // 获取MIME类型
            var byteCharacters = atob(parts[1]);  // 解码base64字符串

            // 创建ArrayBuffer
            var arrayBuffer = new ArrayBuffer(byteCharacters.length);
            var uint8Array = new Uint8Array(arrayBuffer);

            // 将解码后的字符转换为字节数组
            for (var i = 0; i < byteCharacters.length; i++) {
                uint8Array[i] = byteCharacters.charCodeAt(i);
            }

            // 创建Blob对象
            return new Blob([arrayBuffer], { type: contentType });
        }

        document
            .querySelector('a')
            .addEventListener(
                'click',
                (event) => {

                    // 先获取dataURL,然后将dataURL转成blobURL,才能下载成功。如果直接使用canvas.toBlob()获取的blobURL下载PNG文件无法打开
                    var dataURL = canvas.toDataURL()
                    var blob = dataURLtoBlob(dataURL);
                    var blobURL = URL.createObjectURL(blob);  // 生成Blob URL

                    event.target.href = blobURL

                    // 使用完成后记得释放Blob URL
                    setTimeout(() => {
                        URL.revokeObjectURL(blobURL)
                        console.log('done...')
                    }, 10000)
                }
            )
    </script>
</body>

</html>
声明:本文为原创文章,51blog.xyz和作者拥有版权,如需转载,请注明来源于51blog.xyz并保留原文链接:https://www.51blog.xyz/article/71

文章归档

强烈推荐的PHP全栈开发后台管理系统
buildadmin logo
Thinkphp8 Vue3 Element PLus TypeScript Vite Pinia

🔥BuildAdmin是一个永久免费开源,无需授权即可商业使用,且使用了流行技术栈快速创建商业级后台管理系统。

推荐文章

热门标签

PHP ThinkPHP ThinkPHP5.1 Go Mysql Mysql5.7 Redis Linux CentOS7 Git HTML CSS CSS3 Javascript JQuery Vue LayUI VMware Uniapp 微信小程序 docker wiki Confluence7 学习笔记 uView ES6 Ant Design Pro of Vue React ThinkPHP6.0 chrome 扩展 翻译工具 Nuxt SSR 服务端渲染 scrollreveal.js ThinkPHP8.0 Mac webman 跨域CORS vscode GitHub ECharts Canvas vue3 three.js 微信支付 PHP全栈开发 Python AI 人工智能 AI辅助 工作经验 实战笔记