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和jquery
Nov 21 HTML / CSS
结合 CSS3 transition transform 实现简单的跑马灯效果的示例
Feb 07 HTML / CSS
用css3实现转换过渡和动画效果
Mar 13 HTML / CSS
HTML5新表单元素_动力节点Java学院整理
Jul 12 HTML / CSS
HTML5实现的震撼3D焦点图动画的示例代码
Sep 26 HTML / CSS
html5 乒乓球(碰撞检测)实例二
Jul 25 HTML / CSS
深入探究HTML5的History API
Jul 09 HTML / CSS
如何避免常见的6种HTML5错误用法
Nov 06 HTML / CSS
Canvas制作的下雨动画的示例
Mar 06 HTML / CSS
h5移动端调用支付宝、微信支付的实现
Jun 08 HTML / CSS
解决html5中的video标签ios系统中无法播放使用的问题
Aug 10 HTML / CSS
HTML页面滚动时部分内容位置固定不滚动的实现
Apr 14 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
《被神捡到的男人》动画化计划进行中!
2020/03/06 日漫
[原创]php实现数组按拼音顺序排序的方法
2017/05/03 PHP
Laravel中任务调度console使用方法小结
2017/05/07 PHP
PHP中创建和编辑Excel表格的方法
2018/09/13 PHP
详解PHP PDO简单教程
2019/05/28 PHP
javascript delete 使用示例代码
2010/03/29 Javascript
Chrome中JSON.parse的特殊实现
2011/01/12 Javascript
基于jquery的地址栏射击游戏代码
2011/03/10 Javascript
jquery调用asp.net 页面后台的实现代码
2011/04/27 Javascript
JavaScript获取多个数组的交集简单实例
2013/11/11 Javascript
JQuery下拉框应用示例介绍
2014/04/23 Javascript
nodejs初步体验篇
2015/11/23 NodeJs
jQuery动态添加及删除表单上传元素的方法(附demo源码下载)
2016/01/15 Javascript
JS中script标签defer和async属性的区别详解
2016/08/12 Javascript
详解React 16 中的异常处理
2017/07/28 Javascript
vue2.0项目中使用Ueditor富文本编辑器示例代码
2017/08/14 Javascript
vue init失败简单解决方法(终极版)
2017/12/22 Javascript
jQuery实现购物车的总价计算和总价传值功能
2018/11/28 jQuery
js实现无限瀑布流实例方法
2019/09/16 Javascript
[42:22]DOTA2上海特级锦标赛C组小组赛#1 OG VS Archon第一局
2016/02/27 DOTA
Python中的is和==比较两个对象的两种方法
2017/09/06 Python
python3 cvs将数据读取为字典的方法
2018/12/22 Python
Python使用Excel将数据写入多个sheet
2020/05/16 Python
浅谈keras中的Merge层(实现层的相加、相减、相乘实例)
2020/05/23 Python
可持续未来的时尚基础:Alternative Apparel
2019/05/06 全球购物
Brora官网:英国领先的羊绒服装品牌
2019/08/28 全球购物
Derek Rose官网:英国高档睡衣、家居服和内衣品牌
2020/01/18 全球购物
抽象方法、抽象类怎样声明
2014/10/25 面试题
应届生求职推荐信
2013/10/28 职场文书
行政文员岗位职责
2013/11/08 职场文书
法律六进活动方案
2014/03/13 职场文书
金融与证券专业求职信
2014/06/22 职场文书
环卫工作汇报材料
2014/10/28 职场文书
2014年后勤工作总结
2014/11/18 职场文书
2014年社区妇联工作总结
2014/12/02 职场文书
2015年信访工作总结
2015/04/07 职场文书