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 相关文章推荐
详解css3 object-fit属性
Jul 27 HTML / CSS
CSS3 重置iphone浏览器按钮input,select等表单元素的默认样式
Oct 11 HTML / CSS
利用CSS3动画实现圆圈由小变大向外扩散的效果实例
Sep 10 HTML / CSS
详解css position 5种不同的值的用法
Jul 30 HTML / CSS
CSS3 box-shadow属性实例详解
Jun 19 HTML / CSS
CSS3中animation实现流光按钮效果
Dec 21 HTML / CSS
基于 HTML5 Canvas实现 的交互式地铁线路图
Mar 05 HTML / CSS
解析HTML5的存储功能和web SQL的相关操作方法
Feb 19 HTML / CSS
基于HTML5陀螺仪实现ofo首页眼睛移动效果的示例
Jul 31 HTML / CSS
关于解决iframe标签嵌套问题的解决方法
Mar 04 HTML / CSS
CSS3实现的侧滑菜单
Apr 27 HTML / CSS
el-form每行显示两列底部按钮居中效果的实现
Aug 05 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
连接到txt文本的超链接,不直接打开而是点击后下载的处理方法
2009/07/01 PHP
php以fastCGI的方式运行时文件系统权限问题及解决方法
2015/05/11 PHP
PHP针对字符串开头和结尾的判断方法
2016/07/11 PHP
php实现图片按比例截取的方法
2017/02/06 PHP
CI框架教程之优化验证码机制详解【验证码辅助函数】
2019/04/16 PHP
js 实现css风格选择器(压缩后2KB)
2012/01/12 Javascript
JavaScript执行效率与性能提升方案
2012/12/21 Javascript
从数组中随机取x条不重复数据的JS代码
2013/12/24 Javascript
node.js中的fs.futimesSync方法使用说明
2014/12/17 Javascript
使用AOP改善javascript代码
2015/05/01 Javascript
jQuery+Ajax+PHP+Mysql实现分页显示数据实例讲解
2015/09/27 Javascript
用JS动态改变表单form里的action值属性的两种方法
2016/05/25 Javascript
JS弹出窗口的运用与技巧大全
2016/11/01 Javascript
JavaScript算法教程之sku(库存量单位)详解
2017/06/29 Javascript
vue axios登录请求拦截器
2018/04/02 Javascript
在element-ui的select下拉框加上滚动加载
2019/04/18 Javascript
js时间戳转yyyy-MM-dd HH-mm-ss工具类详解
2019/04/30 Javascript
微信小程序实现手势滑动效果
2019/08/26 Javascript
浅谈laytpl 模板空值显示null的解决方法及简单的js表达式
2019/09/19 Javascript
解决vue 使用axios.all()方法发起多个请求控制台报错的问题
2020/11/09 Javascript
[03:38]2014DOTA2西雅图国际邀请赛 VG战队巡礼
2014/07/07 DOTA
[03:55]2014DOTA2国际邀请赛 Fnatic经理采访赢DK在情理之中
2014/07/10 DOTA
[01:00:59]VP VS VG Supermajor小组赛胜者组第二轮 BO3第二场 6.2
2018/06/03 DOTA
python读取csv文件示例(python操作csv)
2014/03/11 Python
Pycharm技巧之代码跳转该如何回退
2017/07/16 Python
python中numpy.zeros(np.zeros)的使用方法
2017/11/07 Python
python实现简单遗传算法
2018/03/19 Python
Django处理多用户类型的方法介绍
2019/05/18 Python
Python实现一个数组除以一个数的例子
2019/07/20 Python
PyTorch使用cpu加载模型运算方式
2020/01/13 Python
Python PyPDF2模块安装使用解析
2020/01/19 Python
培训主管的职业生涯规划
2014/03/06 职场文书
财务人员担保书
2014/05/13 职场文书
商务英语邮件开头问候语
2015/11/10 职场文书
职工趣味运动会开幕词
2016/03/04 职场文书
应用最多的公文《通知》如何写?
2019/04/02 职场文书