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的transition效果和transfor效果示例介绍
Oct 30 HTML / CSS
css3 media 响应式布局的简单实例
Aug 03 HTML / CSS
HTML5 本地存储实现购物车功能
Sep 07 HTML / CSS
HTML5中语义化 b 和 i 标签
Oct 17 HTML / CSS
html5的canvas元素使用方法介绍(画矩形、画折线、圆形)
Apr 14 HTML / CSS
html5 Canvas实现图片旋转的示例
Jan 15 HTML / CSS
小程序canvas中文字设置居中锚点
Apr 16 HTML / CSS
HTML5 body设置全屏背景图片的示例代码
Dec 08 HTML / CSS
CSS3实现模糊背景的三种效果示例
Mar 30 HTML / CSS
CSS实现多个元素在盒子内两端对齐效果
Mar 30 HTML / CSS
CSS实现渐变色边框(Gradient borders)的5种方法
Mar 25 HTML / CSS
flex布局中使用flex-wrap实现换行的项目实践
Jun 21 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之第三天
2006/10/09 PHP
深入探讨PHP中的内存管理问题
2011/08/31 PHP
PHP 通过Socket收发十六进制数据的实现代码
2013/08/16 PHP
详解php中反射的应用
2016/03/15 PHP
用php定义一个数组最简单的方法
2019/10/04 PHP
XHTML-Strict 内允许出现的标签
2006/12/11 Javascript
[JS源码]超长文章自动分页(客户端版)
2007/01/09 Javascript
基于jquery实现的上传图片及图片大小验证、图片预览效果代码
2011/04/12 Javascript
高效的获取当前元素是父元素的第几个子元素
2013/10/15 Javascript
jquery制作弹窗提示窗口代码分享
2014/03/02 Javascript
js点击事件链接的问题解决
2014/04/25 Javascript
angular中子控制器向父控制器传值的实例
2018/10/08 Javascript
使用vue for时为什么要key【推荐】
2019/07/11 Javascript
Vue指令之 v-cloak、v-text、v-html实例详解
2019/08/08 Javascript
在vue和element-ui的table中实现分页复选功能
2019/12/04 Javascript
微信小程序实现购物车功能
2020/11/18 Javascript
JS创建自定义对象的六种方法总结
2020/12/15 Javascript
[19:26]TNC vs EG (BO3)
2018/06/07 DOTA
python操作xml文件详细介绍
2014/06/09 Python
Python实现将n个点均匀地分布在球面上的方法
2015/03/12 Python
win系统下为Python3.5安装flask-mongoengine 库
2016/12/20 Python
Python实现希尔排序算法的原理与用法实例分析
2017/11/23 Python
python+pandas生成指定日期和重采样的方法
2018/04/11 Python
python实现随机调用一个浏览器打开网页
2018/04/21 Python
Python使用googletrans报错的解决方法
2018/09/25 Python
分享29个基于Bootstrap的HTML5响应式网页设计模板
2015/11/19 HTML / CSS
浅析数据存储的三种方式 cookie sessionstorage localstorage 的异同
2020/06/04 HTML / CSS
希腊香水和化妆品购物网站:Parfimo.gr
2019/10/03 全球购物
当当网软件测试笔试题
2015/11/24 面试题
传播学毕业生求职信
2013/10/11 职场文书
写演讲稿要注意的六件事
2014/01/14 职场文书
小升初自荐信范文
2015/03/05 职场文书
海洋天堂观后感
2015/06/05 职场文书
检讨书之工作不认真
2019/08/14 职场文书
Idea连接MySQL数据库出现中文乱码的问题
2021/04/14 MySQL
Python绘画好看的星空图
2022/03/17 Python