canvas拼图功能实现代码示例


Posted in HTML / CSS onNovember 21, 2018

最近做项目的时候遇到照片拼图的功能,便在这里分享自己的封装的canvas拼图功能,可能代码写的不好,如果有疑问或者是有更好的方法的,可以私聊我,或者是评论指出,感谢各位

实现的思路其实挺简单的,主要是通过服务端获取图片链接,图片宽度,图片高度,然后利用简单的递归实现就行了(注意移动端需要采用2倍数的比例,否则会出现图片模糊的问题)

/**

     * canvas绘图数据
     * @param {Object[]} option.photoData
     * @param {string} option.photoData[].photo - 照片的链接地址
     * @param {number} option.photoData[].width -  照片的宽度
     * @param {number} option.photoData[].height -  照片的高度
     * @param {Object[]} option.wordData
     * @param {string} option.wordData[].color - 文字的颜色
     * @param {number} option.wordData[].fontSize - 文字的大小
     * @param {string} option.wordData[].fontWeight -  文字的粗细
     * @param {number} option.wordData[].left - 文字的左边距
     * @param {number} option.wordData[].top -  文字的上边距
     * @param {string} option.wordData[].word -  文字的内容
     * @param {Object[]} option.iconData
     * @param {string} option.iconData[].photo - icon的链接地址
     * @param {number} option.iconData[].left -  icon的左边距
     * @param {number} option.iconData[].top -  icon的上边距
     * @param {number} option.iconData[].width -  icon的宽度
     * @param {number} option.iconData[].height -  icon的高度
     *
    */
function canvasDraw(option){

        var canvas = document.createElement('canvas'),
            ctx = canvas.getContext('2d'),
            clientWidth = document.documentElement.clientWidth,
            canvasHeight = 0,
            distance = 0,
            photoCount = 0,
            iconCount = 0;

        // canvas中手机上一倍绘图会模糊,需采用两倍,pc端不会。    
        clientWidth = clientWidth > 480? 480 * 2 : clientWidth * 2; 

        option.photoData.forEach(function(item,index,picArr){
            if (!index) {
                item.distance = 0;
            }else if(index){
                distance += Math.floor(clientWidth / option.photoData[index - 1].width * option.photoData[index - 1].height)
                item.distance = distance;
            }
            canvasHeight += Math.floor(clientWidth / item.width * item.height);
            item.imgHeight = Math.floor(clientWidth / item.width * item.height);
        })        

        console.log(option.photoData)

        if (ctx) {
            canvas.width = clientWidth;
            canvas.height  = canvasHeight + clientWidth / 4 * 2
        
            ctx.fillStyle = '#fff'
            ctx.fillRect(0, 0, canvas.width, canvas.height)

            // 绘制图片文字
            if(option.wordData.length){
                option.wordData.forEach(function(item,index){
                    ctx.fillStyle = item.color;
                    ctx.font = 'normal normal ' + item.fontWeight + ' ' + calculate(item.fontSize) + 'px Microsoft YaHei';
                    ctx.textAlign = 'left';
                    ctx.fillText(item.word, calculate(item.left), canvasHeight + calculate(item.top));    
                })
            }

            //按比例计算不同手机的百分比间距
            function calculate(num){
                return Math.floor(clientWidth * num / 750)
            }

            drawPhoto('photo0')

            function drawPhoto(photoDom){
                var photoDom = new Image();    
                photoDom.setAttribute('crossOrigin', 'Anonymous');
                photoDom.src = option.photoData[photoCount].photo;

                photoDom.onload = function(){
                    ctx.drawImage(photoDom, 0, option.photoData[photoCount].distance, clientWidth, option.photoData[photoCount].imgHeight);
                    photoCount++;

                    if (photoCount == option.photoData.length) {

                        drawIcon('icon0')

                        function drawIcon(iconDom){
                            var iconDom = new Image();    
                            iconDom.setAttribute('crossOrigin', 'Anonymous');
                            iconDom.src = option.iconData[iconCount].icon;

                            iconDom.onload = function(){
                                ctx.drawImage(iconDom, calculate(option.iconData[iconCount].left), canvasHeight + calculate(option.iconData[iconCount].top), calculate(option.iconData[iconCount].width), calculate(option.iconData[iconCount].height))
                                iconCount++;

                                if (iconCount == option.iconData.length) {
                                    var imageURL = canvas.toDataURL("image/jpeg")
                                    document.getElementsByClassName('shareImg')[0].setAttribute('src', imageURL)

                                    //将闭包引用清除,释放内存;
                                    drawPhoto = null;

                                }else{
                                    drawIcon('icon' + iconCount)
                                }
                            }    
                        }                                 
                    }else{
                        drawPhoto('photo'+ photoCount)
                        
                    }    
                }                                                
            }

        }else{
            console.log('不支持canvas')
        }
    }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

HTML / CSS 相关文章推荐
使用CSS实现阅读进度条
Feb 27 HTML / CSS
HTML5和CSS3让网页设计提升到下一个高度
Aug 14 HTML / CSS
结合CSS3的布局新特征谈谈常见布局方法
Jan 22 HTML / CSS
简单掌握CSS3中resize属性的用法
Apr 01 HTML / CSS
css3 仿写阿里云水纹效果的示例代码
Feb 10 HTML / CSS
css3给背景图片加颜色遮罩的方法
Nov 05 HTML / CSS
CSS3 实现的火焰动画
Dec 07 HTML / CSS
video结合canvas实现视频在线截图功能
Jun 25 HTML / CSS
使用HTML和CSS实现的标签云效果(附demo)
Feb 03 HTML / CSS
简单介绍 http请求响应参数、无连接无状态、MIME、状态码、端口、telnet、curl
Mar 31 HTML / CSS
巧用 -webkit-box-reflect 倒影实现各类动效(小结)
Apr 22 HTML / CSS
详解CSS故障艺术
May 25 HTML / CSS
详解Canvas 跨域脱坑实践
Nov 07 #HTML / CSS
浅谈移动端网页图片预加载方案
Nov 05 #HTML / CSS
Canvas中设置width与height的问题浅析
Nov 01 #HTML / CSS
html5 postMessage前端跨域并前端监听的方法示例
Nov 01 #HTML / CSS
HTML5之消息通知的使用(Web Notification)
Oct 30 #HTML / CSS
详解Html5页面实现下载文件(apk、txt等)的三种方式
Oct 22 #HTML / CSS
html5 http的轮询和Websocket原理
Oct 19 #HTML / CSS
You might like
用PHP写的MySQL数据库用户认证系统代码
2007/03/22 PHP
Win2003服务器安全加固设置--进一步提高服务器安全性
2007/05/23 PHP
PHP 飞信好友免费短信API接口开源版
2010/07/22 PHP
php array_push()数组函数:将一个或多个单元压入数组的末尾(入栈)
2011/07/12 PHP
Codeigniter框架实现获取分页数据和总条数的方法
2014/12/05 PHP
Yii使用Captcha验证码的方法
2015/12/28 PHP
PHP中addslashes与mysql_escape_string的区别分析
2016/04/25 PHP
PHP大文件分割分片上传实现代码
2020/12/09 PHP
jquery获取tr中控件值并操作tr实现思路
2013/03/27 Javascript
JS实现至少包含字母、大小写数字、字符的密码等级的两种方法
2015/02/03 Javascript
jQuery DOM插入节点操作指南
2015/03/03 Javascript
js正则表达式匹配数字字母下划线等
2015/04/14 Javascript
浅谈JavaScript的Polymer框架中的事件绑定
2015/07/29 Javascript
JQuery解析XML数据的几个简单实例
2016/05/18 Javascript
webpack使用 babel-loader 转换 ES6代码示例
2017/08/21 Javascript
不使用 JS 匿名函数理由
2017/11/17 Javascript
CKEditor4配置与开发详细中文说明文档
2018/10/08 Javascript
JS实现判断移动端PC端功能
2020/02/21 Javascript
详解vue修改elementUI的分页组件视图没更新问题
2020/11/13 Javascript
layui使用及简单的三级联动实现教程
2020/12/01 Javascript
[04:42]5分钟带你了解什么是DOTA2(第一期)
2017/02/07 DOTA
python实现获取Ip归属地等信息
2016/08/27 Python
python如何实现int函数的方法示例
2018/02/19 Python
在python中将list分段并保存为array类型的方法
2019/07/15 Python
Django 后台带有字典的列表数据与页面js交互实例
2020/04/03 Python
python读取hdfs并返回dataframe教程
2020/06/05 Python
Python实现Keras搭建神经网络训练分类模型教程
2020/06/12 Python
详解python metaclass(元类)
2020/08/13 Python
如何通过python检查文件是否被占用
2020/12/18 Python
python如何修改文件时间属性
2021/02/05 Python
详解Html5页面实现下载文件(apk、txt等)的三种方式
2018/10/22 HTML / CSS
白宫黑市官网:White House Black Market
2016/11/17 全球购物
全球性的在线时尚男装零售商:boohooMAN
2016/12/17 全球购物
《春天来了》教学反思
2014/04/07 职场文书
2019行政前台转正申请书范文3篇
2019/08/15 职场文书
Java Redisson多策略注解限流
2022/09/23 Java/Android