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中的content属性使用示例
Jul 20 HTML / CSS
css3+伪元素实现鼠标移入时下划线向两边展开的效果
Apr 25 HTML / CSS
CSS3自定义滚动条样式的示例代码
Aug 21 HTML / CSS
HTML5+CSS3 实现灵动的动画 TAB 切换效果(DEMO)
Sep 15 HTML / CSS
HTML5的Geolocation地理位置定位API使用教程
May 12 HTML / CSS
html5中为audio标签增加停止按钮动作实现方法
Jan 04 HTML / CSS
突袭HTML5之Javascript API扩展4—拖拽(Drag/Drop)概述
Jan 31 HTML / CSS
HTML5+Canvas+CSS3实现齐天大圣孙悟空腾云驾雾效果
Apr 26 HTML / CSS
HTML块级标签汇总(小篇)
Jul 13 HTML / CSS
使用spring mvc+localResizeIMG实现HTML5端图片压缩上传的功能
Dec 16 HTML / CSS
Html5原创俄罗斯方块(基于canvas)
Jan 07 HTML / CSS
如何利用 CSS Overview 面板重构优化你的网站
Oct 24 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如何透过ODBC来存取数据库
2006/10/09 PHP
表单复选框向PHP传输数据的代码
2007/11/13 PHP
php设计模式 Observer(观察者模式)
2011/06/26 PHP
一个显示某段时间内每个月的方法 返回由这些月份组成的数组
2012/05/16 PHP
ecshop 2.72如何修改后台访问地址
2015/03/03 PHP
如何使用json在前后台进行数据传输实例介绍
2013/04/11 Javascript
一款jquery特效编写的大度宽屏焦点图切换特效的实例代码
2013/08/05 Javascript
js的hasownproperty使用示例
2014/03/02 Javascript
js函数名与form表单元素同名冲突的问题
2014/03/07 Javascript
JavaScript字符串对象fromCharCode方法入门实例(用于把Unicode值转换为字符串)
2014/10/17 Javascript
jQuery处理图片加载失败的常用方法
2015/06/08 Javascript
jQuery实现的给图片点赞+1动画效果(附在线演示及demo源码下载)
2015/12/31 Javascript
WEB前端开发框架Bootstrap3 VS Foundation5
2016/05/16 Javascript
深入理解jQuery之事件移除
2016/06/02 Javascript
jQuery Easyui datagrid/treegrid 清空数据
2016/07/09 Javascript
两种JavaScript的AES加密方式(可与Java相互加解密)
2016/08/02 Javascript
ionic实现下拉刷新载入数据功能
2017/05/11 Javascript
深入理解Promise.all
2018/08/08 Javascript
node.js 基于cheerio的爬虫工具的实现(需要登录权限的爬虫工具)
2019/04/10 Javascript
JavaScript 正则应用详解【模式、欲查、反向引用等】
2020/05/13 Javascript
js实现滑动滑块验证登录
2020/07/24 Javascript
[58:57]2018DOTA2亚洲邀请赛3月29日小组赛B组 Effect VS VGJ.T
2018/03/30 DOTA
基于Python的接口测试框架实例
2016/11/04 Python
Python实现批量压缩图片
2018/01/25 Python
关于ResNeXt网络的pytorch实现
2020/01/14 Python
python 串行执行和并行执行实例
2020/04/30 Python
python tkiner实现 一个小小的图片翻页功能的示例代码
2020/06/24 Python
理财投资建议书
2014/03/12 职场文书
法人单位适用的授权委托书
2014/09/19 职场文书
民事诉讼代理授权委托书范本
2014/10/08 职场文书
导师工作推荐信
2015/03/27 职场文书
亮剑观后感
2015/06/05 职场文书
高中开学感言
2015/08/01 职场文书
班主任寄语2016
2015/12/04 职场文书
简述Java中throw-throws异常抛出
2021/08/07 Java/Android
SpringBoot整合阿里云视频点播的过程详解
2021/12/06 Java/Android