继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

canvas入门实战--邀请卡生成与下载

守候i
关注TA
已关注
手记 55
粉丝 1.7万
获赞 966

1.前言

写了很多的javascript和css3的文章,是时候写一篇canvas的了。canvas是html5提供的一个新的功能!至于作用,就是一个画布。然后画笔就是javascript。canvas的用途非常的广,特别是html5游戏以及数据可视化这两个方面。现在canvas给我的感觉就和css3一样,可以不用太厉害,但是必须要会基础的用法。但是以后对canvas的需求,肯定会越来越大。所以canvas很值得学习,而且学好canvas,就是很好的一个加分项。对于这篇文章,我也是以canvas初学者的角度写的,会有很多改善的地方。如果大家觉得我有什么可以改善的,或者建议,欢迎指点迷津!代码已上传github,需要的欢迎star(downloadImg)。

大家看这篇文章之前,要了解javascript的一些基础,也要看着了解一些canvas的api(canvas-MSN教程canvas菜鸟教程

2.邀请卡实例

邀请卡自动生成这个会有的,毕竟有时候,很多邀请卡都是一样的,就是被邀请的人不一样而已,也就是说,整个邀请卡,就是一个名字不一样,那么下面。就写一套代码,根据名字生成邀请卡!

2-1.运行效果

html代码

<html><head>    <meta charset="utf-8">    <title>下载图片</title>    <style>        .set-option {            float: left;            width: 400px;        }        .set-option .text {            width: 200px;            height: 40px;            padding-left: 10px;            border-radius: 4px;            border: 1px solid #ccc;        }        .set-option td {            padding: 10px 0;        }        .set-option td:first-child {            text-align: right;            padding-right: 10px;        }        .set-option p {            margin: 0;            line-height: 16px;        }        .check-box {            width: 16px;            height: 16px;            margin: 0;            vertical-align: top;        }        button {            width: 200px;            height: 50px;            border: none;            color: #fff;            font-size: 16px;            cursor: pointer;            display: block;            margin: 10px auto;        }        button:hover {            opacity: .9;        }        .btn-all {            background: #f90;        }        .btn-save {            background: #09f;        }        .btn-download {            background: #4CAF50;        }    </style></head><body><div>    <div class="set-option">        <table>            <tr>                <td>画布尺寸</td>                <td><input type="text" class="text" id="size"/></td>            </tr>            <tr>                <td>背景图片</td>                <td><input type="file" id="file"/></td>            </tr>            <tr>                <td>用户名</td>                <td>                    <input type="text" class="text" id="user-name"/>                </td>            </tr>            <tr>                <td>用户名x坐标</td>                <td>                    <input type="number" class="text" id="text-option-x"/></br>                    <p><input type="checkbox" class="check-box" value="1" id="is-center-x">居中显示</p>                </td>            </tr>            <tr>                <td>用户名y坐标</td>                <td>                    <input type="number" class="text" id="text-option-y"/></br>                    <p><input type="checkbox" class="check-box" value="1" id="is-center-y">居中显示</p>                </td>            </tr>            <tr>                <td>用户名字体大小</td>                <td><input type="number" class="text" id="text-size"/></td>            </tr>            <tr>                <td>文字颜色</td>                <td><input type="text" class="text" id="text-color"/></td>            </tr>            <tr>                <td>图片类型</td>                <td>                    <select type="text" class="text" id="img-type">                        <option value="jpg">jpg</option>                        <option value="png">png</option>                    </select>                </td>            </tr>        </table>        <button id="save-image" class="btn-save">效果预览</button>        <button id="download-img" class="btn-download">下载当前图片</button>        <button id="download-all" class="btn-all">批量导出</button>    </div>    <div class="show-canvas">        <canvas width=200 height=200 id="thecanvas"></canvas>    </div></div></body></html>

效果如图,那么大家细想一下,关于一张邀请卡,有什么东西是需要改变的!看到上图相比不难发现!有如下需要改变的属性:图片的大小,图片,用户名,用户名的坐标(x,y,x轴是否居中,y轴是否居中),用户名字体的大小,用户名字体的颜色,以及下载图片的类型。

这样就得到了如下的参数(大家看到有些参数是有值的,可以想成默认值就行了)

var option = {    img: '111.jpg',    width: 500,    height: 350,    fontSize: "20px Microsoft YaHei",    color: "black",    text: '守候',    imgType: 'jpg',    x: 30,    y: 30,    xCenter: false,    yCenter: false,};

2-2.步骤

1.初步效果

根据上面的参数,先初步画一个效果,代码基本都是一个写法,没什么技巧

//画图function draw(obj) {    var canvas = document.getElementById("thecanvas");    //画布大小
    canvas.width = obj.width;
    canvas.height = obj.height;    //设置图片
    var img = new Image();
    img.src = obj.img;    var ctx = canvas.getContext("2d");    //设置字体的坐标
    var _x = obj.x, _y = obj.y;    //是否居中显示
    if (obj.xCenter) {
        _x = obj.width / 2;
    }    if (obj.yCenter) {
        _y = obj.height / 2;
    }    //图片加载后
    img. = function () {        //先画图片
        ctx.drawImage(img, 0, 0);        //设置文字的大小
        ctx.font = obj.fontSize;        //设置文字的颜色
        ctx.fillStyle = obj.color;        //设置文字坐标
        if (obj.xCenter) {
            ctx.textAlign = "center";
        }        //画文字
        ctx.fillText(obj.text, _x, _y);
    };
}window. = function () {
    draw(option);
}

2.动态改变参数

看到图已经画好了,工作其实已经完成一半了!

下面就是动态改变参数!这一步其实很简单。
首先,改变画布的尺寸

//画布尺寸//获取按钮var size = document.getElementById("size");size.addEventListener("blur", function () {    //根据空格,区分高宽
    var _width = parseInt(size.value.replace(/(^\s*)|(\s*$)/g, "").split(/\s+/)[0]),
        _height = parseInt(size.value.replace(/(^\s*)|(\s*$)/g, "").split(/\s+/)[1]);    //把参数的width和height改掉
    option.width = _width || 100;
    option.height = _height || 100;    //重新画图
    draw(option);
});

上面代码设置了,只要输入框失去了焦点,就会改变画布的大小,下面来运行下,看下效果(gif图差强人意,大家看懂就好)

canvas没有层级的说法,只要改canvas,都要重绘。哪怕就是一个字移动一个像素。

做好了这个,下面做选择图片的功能!

//选择图片//获取图片控件var file = document.getElementById("file"), imagesFile, imageData;
file.addEventListener('change', function (e) {    //获取图片
    imagesFile = e.target.files[0];    //把图片转base64
    var reader = new FileReader();
    reader.readAsDataURL(imagesFile);    //图片加载后
    reader. = function (e) {        //设置option的img属性,再冲洗年绘制
        imageData = this.result;
        option.img = imageData;
        draw(option);
    }
});

下面开始改文字,用户名这个有点不一样,我以空格分割。如果输入多个用户名,以第一个用户名重绘。下面代码,注释就不写了,还是和上面的逻辑一样!

//用户名var userName = document.getElementById("user-name");
userName.addEventListener("blur", function () {    var _text = userName.value.replace(/(^\s*)|(\s*$)/g, "").split(/\s+/);
    option.text = _text[0];
    draw(option);
});

下面开始用户名的坐标,代码方面,也是改option的相关属性

    optionXCenter.addEventListener("change", function () {        if (optionXCenter.checked) {
            option.xCenter = true;
        }        else {
            option.xCenter = false;
            option.x = parseInt(optionX.value);
        }
        draw(option);
    });    //纵坐标
    var optionY = document.getElementById("text-option-y");
    optionY.value = option.y;    var optionYCenter = document.getElementById("is-center-y");
    optionY.addEventListener("input", function () {        if (optionYCenter.checked) {
            option.yCenter = true;
        }        else {
            option.yCenter = false;
            option.y = parseInt(optionY.value);
        }
        draw(option);
    });    //是否垂直居中显示
    optionYCenter.addEventListener("change", function () {        if (optionYCenter.checked) {
            option.yCenter = true;
        }        else {
            option.yCenter = false;
            option.y = parseInt(optionY.value);
        }
        draw(option);
    });


是否水平居中显示

其他的属性,字体大小和颜色,基本是一样的代码,运行的效果图我不放了!

//字体颜色var textColor = document.getElementById("text-color");
textColor.addEventListener("blur", function () {
    textColor.value === "" ? option.color = "#fff" : option.color = '#' + textColor.value;
    draw(option);
});//字体大小var textSize = document.getElementById("text-size");
textSize.addEventListener("input", function () {
    textSize.value === "" ? option.fontSize = '20px Microsoft YaHei' : option.fontSize = textSize.value + 'px Microsoft YaHei';
    draw(option);
});

3.按钮操作

效果预览

就是预览当前canvas的一个效果,这个就很简单了,就是新开一个窗口,然后把图片写进去而已

//预览图片function saveImageInfo() {    var mycanvas = document.getElementById("thecanvas");    //生成图片
    var image = mycanvas.toDataURL("image/png");    var w = window.open('about:blank', 'image from canvas');    //把图片新进新的窗口
    w.document.write("<img src='" + image + "' alt='from canvas'/>");
}var saveButton = document.getElementById("save-image");
saveButton.addEventListener('click', saveImageInfo);

下载当前图片

下载图片这个,基本也是写法的,都是些记忆的东西

//图片类型var imgType = document.getElementById("img-type");
imgType.addEventListener("change",function () {
    option.imgType=this.value;
});//下载图片function downloadImg(fileName) {    //获取canvas
    var myCanvas = document.getElementById("thecanvas");    //设置图片类型
    var image = myCanvas.toDataURL("image/" + option.imgType).replace("image/" + option.imgType, "image/octet-stream");    var save_link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
    save_link.href = image;    //设置下载图片的名称
    save_link.download = fileName + '.' + option.imgType;    //下载图片
    var event = document.createEvent('MouseEvents');
    event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
    save_link.dispatchEvent(event);
}

批量下载图片

这个复杂一点,但也不难,下面一步一步来!

1.首先批量导出,那么用户名我这里是使用空格分割,那么现在我在option里面,弄一个字段textAll,所有文字的集合。all代表是否是批量下载。fn属性代表回调函数

//批量导出var downloadAll = document.getElementById("download-all");
downloadAll.addEventListener('click', function () {    var _text = userName.value.replace(/(^\s*)|(\s*$)/g, "").split(/\s+/);
    option.textAll = _text;
    option.all = true;
    option.fn = downloadImg;
    draw(option);
});

2.然后修改绘制的函数draw,判断是否是全部绘制的情况!

function draw(obj) {    var canvas = document.getElementById("thecanvas");    //画布大小
    canvas.width = obj.width;
    canvas.height = obj.height;    //设置图片
    var img = new Image();
    img.src = obj.img;    var ctx = canvas.getContext("2d");    //设置字体的坐标
    var _x = obj.x, _y = obj.y;    //是否居中显示
    if (obj.xCenter) {
        _x = obj.width / 2;
    }    if (obj.yCenter) {
        _y = obj.height / 2;
    }    //图片加载后
    img. = function () {        //是否是全部打印
        if(obj.all){            //遍历textAll
            for(var i=0;i<obj.textAll.length;i++){                //绘制图片
                ctx.drawImage(img,0,0);                //设置字体大小
                ctx.font=obj.fontSize;                //设置字体颜色
                ctx.fillStyle=obj.color;                //是否居中显示
                if(obj.xCenter){
                    ctx.textAlign="center";
                }                //绘制文字
                ctx.fillText(obj.textAll[i], _x,_y);                //是否回调
                if(obj.fn){
                    obj.fn(obj.textAll[i]);
                }
            }            //最后取消全部批量下载
            defult.all=false;
        }        else{
            ctx.drawImage(img,0,0);
            ctx.font=obj.fontSize;
            ctx.fillStyle=obj.color;            if(obj.xCenter){
                ctx.textAlign="center";
            }
            ctx.fillText(obj.text, _x,_y);
        }
    };
}

3.小结

关于canvas入门的第一篇文章,就写到这里了。写完之后,也发现自己对canvas的也是有很多的不懂!上文的这例子,知识canvas很简单的一个入门实例。canvas如果深入学习,能做到很多让人惊讶的效果,这个得以后要加强学习,如果发现些值得记录的知识,我也会写文章。canvas是一个非常值得学习的知识,也是很有趣的一个知识。期待与大家有更多的交流和学习!


打开App,阅读手记
1人推荐
发表评论
随时随地看视频慕课网APP