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中文字镂空、透明值、阴影效果设置示例小结
Mar 07 HTML / CSS
CSS3 简写animation
May 10 HTML / CSS
用CSS3实现无限循环的无缝滚动的实例代码
Jul 04 HTML / CSS
使用纯 CSS 创作一个脉动 loader效果的源码
Sep 28 HTML / CSS
HTML5 canvas基本绘图之绘制矩形
Jun 27 HTML / CSS
canvas基础之图形验证码的示例
Jan 02 HTML / CSS
使用css如何制作时间ICON方法实践
Nov 12 HTML / CSS
html5-Canvas可以在web中绘制各种图形
Dec 26 HTML / CSS
在HTML5中使用MathML数学公式的简单讲解
Feb 19 HTML / CSS
HTML5和CSS3实例教程总结(推荐)
Jul 18 HTML / CSS
HTML5页面直接调用百度地图API获取当前位置直接导航目的地的实现代码
Mar 02 HTML / CSS
html5 input输入实时检测以及延时优化
Jul 18 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
PHPThumb图片处理实例
2014/05/03 PHP
win平台安装配置Nginx+php+mysql 环境
2016/01/12 PHP
一端时间轮换的广告
2006/06/26 Javascript
在浏览器窗口上添加遮罩层的方法
2012/11/12 Javascript
javascript设计模式之中介者模式Mediator
2014/12/30 Javascript
JS实现生成会变大变小的圆环实例
2015/08/05 Javascript
javascript实现别踩白块儿小游戏程序
2015/11/22 Javascript
Vue.js快速入门教程
2016/09/07 Javascript
jquery插入兄弟节点的操作方法
2016/12/07 Javascript
AngularJS 霸道的过滤器小结
2017/04/26 Javascript
使用Dropzone.js上传的示例代码
2017/10/10 Javascript
jQuery 禁止表单用户名、密码自动填充功能
2017/10/30 jQuery
Vue代码分割懒加载的实现方法
2017/11/23 Javascript
微信小程序module.exports模块化操作实例浅析
2018/12/20 Javascript
layui使用templet格式化表格数据的方法
2019/09/16 Javascript
JS+HTML实现自定义上传图片按钮并显示图片功能的方法分析
2020/02/12 Javascript
javascript History对象原理解析
2020/02/17 Javascript
javascript实现贪吃蛇经典游戏
2020/04/10 Javascript
react 生命周期实例分析
2020/05/18 Javascript
一文总结学习Python的14张思维导图
2017/10/17 Python
Python pyautogui模块实现鼠标键盘自动化方法详解
2020/02/17 Python
python:删除离群值操作(每一行为一类数据)
2020/06/08 Python
Python3中FuzzyWuzzy库实例用法
2020/11/18 Python
GNC健安喜官方海外旗舰店:美国著名保健品牌
2017/01/04 全球购物
绝对经典成功的大学生推荐信
2013/11/08 职场文书
总经理秘书工作职责
2013/12/26 职场文书
2014两会优秀的心得体会范文
2014/03/17 职场文书
音乐节策划方案
2014/06/09 职场文书
2014年教研工作总结
2014/12/06 职场文书
人事局接收函
2015/01/31 职场文书
放假通知范文
2015/04/14 职场文书
父亲节感言
2015/08/03 职场文书
小学中队委竞选稿
2015/11/20 职场文书
一行代码python实现文件共享服务器
2021/04/22 Python
关于nginx 实现jira反向代理的问题
2021/09/25 Servers
create-react-app开发常用配置教程
2022/06/25 Javascript