手机端绘图板制作

实现套路:利用canvas的api,绘制图片,将canvas图片转成base64 保存在后台。后台将base64转换为png格式。前端请求就可看到显示的图片了。
效果图1:效果图1
效果图2:效果图2

所需图片:所需图片

//html 代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=750, user-scalable=0">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="format-detection" content="telephone=no">
    <meta name="keywords" content="">
    <meta name="description" content="">
    <link rel="stylesheet" href="app_shouqian.css">
    <script src="jquery-2.1.4.js"></script>
    <script src="jquery.easing.min.js"></script>
    <title></title>
    <script>
    </script>
    <style>
        .canImg {
            position: absolute;
        ;
            left: 10px;
            top: 10px;
            width: 100px;
            height: 100px;
            background-color: #000;
        }

        .canImg img {
            width: 100px;
            height: 100px;
        }
    </style>
</head>

<body>
<div class="wrap ">
    <div class="header clearfix">
        <div class="btn left btn-undo cancel">首页</div>
        <div class="btn left btn-reset" id="clear_btn">重做</div>
        <div class="btn right btn-go save" id='img_btn'>发送</div>
    </div>
    <div class="container" style="background: #ff6633;">
        <canvas id="canvas">
            浏览器不支持canvas动画效果
        </canvas>
    </div>
    <div class="footer">
        <div class="pLi clearfix ">
            <span class="pn left pn1 " data-width="20">马克笔</span>
            <span class="pn left pn2 active" data-width="10">画笔</span>
            <span class="pn left pn3 " data-width="2">钢笔</span>
            <span class="pn rubber left" data-width="50">橡皮</span>
            <span class="colors right" id="js_colorBar"></span>
        </div>
        <div class="cLi hidden">
            <div class="pn"></div>
            <ul class="cLs clearfix">
                <li class="left active"></li>
                <li class="left"></li>
                <li class="left"></li>
                <li class="left"></li>
                <li class="left"></li>
                <li class="left"></li>
                <li class="left"></li>
                <li class="left"></li>
                <li class="left"></li>
                <li class="left"></li>
            </ul>
        </div>
    </div>
    <div class="pop-box hidden">
        <div>
            <img id="pro-img" src="" />
            <p id='btn-success'>提交成功</p>
        </div>
    </div>
</div>

<script src="app_shouqian.js"></script>
<script>
    $(function() {
        //获取活动id

        shouhui.photoUrl = './images/';
        shouhui.ajaxUrl = "";
        shouhui.indexUrl = "";

        shouhui.rand = '0';
        shouhui.isTest = '1';
        shouhui.recheck = '1';
        shouhui.initEvent();
    });
</script>
</body>

</html>
//css代码
body {
    background: #fff;
    -webkit-text-size-adjust: 100%;
    -ms-text-size-adjust: 100%;
}


/*css resert*/

html,
body,
div,
p,
span,
label,
img,
a,
ol,
ul,
dl,
dt,
dd,
li,
table,
tr,
td,
th,
tbody,
thead,
tfoot,
form,
fieldset,
legent,
h1,
h2,
h3,
h4,
h5,
h6,
strong,
b,
em,
blockquote,
cite,
pre,
code,
hr,
br,
input,
button,
textarea,
article,
aside,
details,
figcaption,
figure,
footer,
header,
group,
menu,
nav,
section {
    padding: 0px;
    margin: 0px;
}

* {
    padding: 0px;
    margin: 0px;
    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
    -webkit-appearance: none;
    outline: 0 none;
}


/* 要注意表单元素并不继承父级 font 的问题 */

button,
input,
select,
textarea {
    font: 100% serif;
}

img,
input,
select {
    vertical-align: middle;
}

h1,
h2,
h3,
h4,
h5,
h6 {
    font-weight: normal;
    font-size: 1em;
}

ol,
ul {
    list-style-type: none;
}



a img {
    border: 0 none;
    cursor: pointer;
}

fieldset,
img {
    border: 0 none;
}



:focus {
    outline: 0 none;
}

caption,
cite,
code,
em,
th,
var,
i {
    font-weight: normal;
    font-style: normal;
}



/******常用****/

.clearfix:before,
.clearfix:after {
    content: "";
    display: table;
}

.clearfix:after {
    clear: both;
}

.clearfix {
    zoom: 1;
}

.clear {
    clear: both;
    height: 0;
    width: 0;
    display: block;
    visibility: hidden;
    overflow: hidden;
}

.clearit {
    clear: both;
    zoom: 1;
}

.hidden {
    display: none;
}

.vhidden {
    visibility: hidden;
}

.hide-txt {
    overflow: hidden;
    text-indent: 100%;
    white-space: nowrap;
}

.left {
    float: left;
    display: inline;
}

.right {
    float: right;
    display: inline;
}

.fnone {
    float: none;
}

.txtleft {
    text-align: left;
}

.txtright {
    text-align: right;
}

.txtcenter {
    text-align: center;
}

.middle {
    vertical-align: middle;
}

.noborder {
    border: 0 none !important;
}

.nobg {
    background: none !important;
}

.sub {
    vertical-align: sub;
}

.sup {
    vertical-align:middle ;
}

.cursor {
    cursor: pointer;
}

.zoom {
    zoom: 1;
}

.vtop {
    vertical-align: top;
}

.wrap {
    width: 100%;
    position: absolute;
    ;
    left: 0;
    top: 0;
    bottom: 0;
    background: #fdfdfd;
    /*background: url(mob_shouqian_bg.jpg?v=323) no-repeat;*/
    /*background-size: 100% 100%;*/
    overflow: hidden;
}


/*header*/

.header {
    padding: 0 30px;
    height: 86px;
    border-bottom: 1px solid #eee;
    background: rgba(255, 255, 255, .9);
}

.header .btn {
    color: #666;
    font-size: 32px;
    line-height: 86px;
    height: 86px;
}

.header .btn-undo {
    background: url(./images/undo-icon.png) no-repeat center right;
    padding-right: 74px;
    margin-right: 50px;
}

.header .btn-reset {
    background: url(./images/reset-icon.png) no-repeat center left;
    padding-left: 74px;
}

.header .btn-go {
    color: #32b16c;
}


/*container*/

.container {
    width: 100%;
    position: absolute;
    ;
    left: 0;
    top: 87px;
    bottom: 211px;
    padding: 0
}

.container canvas {
    width: 100%;
    height: 100%;
    position: absolute;
    ;
    left: 0;
    top: 0;
}


/*footer*/

.footer {
    display: none;
    position: fixed;
    left: 0px;
    bottom: 0px;
    z-index: 11;
    width: 100%;
    height: 49px;
    border-top: 1px solid #ccc;
    background: #fff;
}

.footer {
    width: 100%;
    height: 210px;
    border-top: 1px solid #fc0;
    display: block;
    background: #ffcc00;
}

.footer .pLi {
    padding: 84px 70px 0 80px;
    position: absolute;
    left: 0;
    top: 0;
}

.footer .pLi .pn {
    width: 76px;
    height: 314px;
    margin-right: 40px;
    text-indent: -999em;
}

.footer .pLi .pn.active {
    margin-top: -55px;
}

.footer .pLi .pn1 {
    background: url(./images/pan0.png) no-repeat;
}

.footer .pLi .pn2 {
    background: url(./images/pan1.png) no-repeat;
}

.footer .pLi .pn3 {
    background: url(./images/pan2.png) no-repeat;
}

.footer .pLi .rubber {
    background: url(./images/rubber.png) no-repeat;
}

.footer .pLi .colors {
    width: 100px;
    height: 100px;
    background: url(./images/color.png) no-repeat;
    margin-top: 15px;
}

.footer .cLi {
    width: 100%;
    height: 210px;
    position: absolute;
    left: 0;
    top: 0
}

.footer .cLi .pn {
    position: absolute;
    left: 65px;
    top: 30px;
    width: 76px;
    height: 314px;
    background: url(./images/pan1.png) no-repeat;
}

.footer .cLi .cLs {
    margin-left: 215px;
    height: 180px;
    width: 550px;
    padding-top: 30px;
}

.footer .cLi .cLs li {
    width: 60px;
    height: 60px;
    border-radius: 50%;
    margin: 0 50px 30px 0;
}

.footer .cLi .cLs li.active {
    border: 8px solid #ebebeb;
    margin: -8px 42px 22px -8px;
}

.footer .cLi .cLs li:nth-child(1) {
    background-color: #e30052;
}

.footer .cLi .cLs li:nth-child(2) {
    background-color: #32b16c;
}

.footer .cLi .cLs li:nth-child(3) {
    background-color: #f19715;
}

.footer .cLi .cLs li:nth-child(4) {
    background-color: #00b8ec;
}

.footer .cLi .cLs li:nth-child(5) {
    background-color: #5f549e;
}

.footer .cLi .cLs li:nth-child(6) {
    background-color: #b6a900;
}

.footer .cLi .cLs li:nth-child(7) {
    background-color: #005752;
}

.footer .cLi .cLs li:nth-child(8) {
    background-color: #03004a;
}

.footer .cLi .cLs li:nth-child(9) {
    background-color: #824e00;
}

.footer .cLi .cLs li:nth-child(10) {
    background-color: #362e2b;
}


/*弹层*/

.pop-box {
    position: absolute;
    ;
    left: 0;
    top: 0;
    bottom: 0;
    width: 100%;
    background: rgba(0, 0, 0, .5);
    z-index: 99999
}

.pop-box>div {
    width: 480px;
    padding: 60px 10px 60px;
    background: #fff;
    position: absolute;
    left: 50%;
    margin-left: -250px;
    top: 400px;
    text-align: center;
}

.pop-box>div img {
    width: 100px;
    height: 100px;
    margin-bottom: 60px;
}

.pop-box>div p {
    font-size: 4em;
}

.pop-box>div .close {
    width: 80px;
    height: 80px;
    position: absolute;
    right: 20px;
    top: 20px;
    background: url(./images/icon-close.png) no-repeat;
    background-size: 100%;
    text-indent: -999em;
}


/*动画*/


/*灰色背景*/

.bg-gray .header {
    border-bottom: 1px solid #c0c0c0;
}

.bg-gray .container {
    background: #ccc;
}

.bg-gray .footer {
    border-top: 1px solid #c0c0c0;
}


/*选择画笔*/

.panChecked {
    animation: panUp 500ms ease 1 forwards;
    -webkit-animation: panUp 500ms ease 1 forwards;
}

.panDelChecked {
    animation: panDown 500ms ease 1 forwards;
    -webkit-animation: panDown 500ms ease 1 forwards;
}

@keyframes panUp {
    0% {
        transform: translateY(55px);
        -webkit-transform: translateY(55px);
    }
    100% {
        transform: translateY(0);
        -webkit-transform: translateY(0);
    }
}

@-webkit-keyframes panUp {
    0% {
        transform: translateY(55px);
        -webkit-transform: translateY(55px);
    }
    100% {
        transform: translateY(0);
        -webkit-transform: translateY(0);
    }
}

@keyframes panDown {
    0% {
        transform: translateY(-55px);
        -webkit-transform: translateY(-55px);
    }
    100% {
        transform: translateY(0);
        -webkit-transform: translateY(0);
    }
}

@-webkit-keyframes panDown {
    0% {
        transform: translateY(-55px);
        -webkit-transform: translateY(-55px);
    }
    100% {
        transform: translateY(0);
        -webkit-transform: translateY(0);
    }
}


/*画笔到颜色盘*/


/*颜色盘*/

.colorIn {
    animation: colorIn 300ms ease 1 forwards;
    -webkit-animation: colorIn 300ms ease 1 forwards;
}

.colorOut {
    animation: colorOut 300ms ease 1 forwards;
    -webkit-animation: colorOut 300ms ease 1 forwards;
}

@keyframes colorIn {
    0% {
        transform: scale(0);
        -webkit-transform: scale(0);
    }
    100% {
        transform: scale(1);
        -webkit-transform: scale(1);
    }
}

@-webkit-keyframes colorIn {
    0% {
        transform: scale(0);
        -webkit-transform: scale(0);
    }
    100% {
        transform: scale(1);
        -webkit-transform: scale(1);
    }
}

@keyframes colorOut {
    0% {
        transform: scale(1);
        -webkit-transform: scale(1);
    }
    100% {
        transform: scale(0);
        -webkit-transform: scale(0);
    }
}

@-webkit-keyframes colorOut {
    0% {
        transform: scale(1);
        -webkit-transform: scale(1);
    }
    100% {
        transform: scale(0);
        -webkit-transform: scale(0);
    }
}
//js代码 app_shouhui.js
var shouhui = {
        stopAnimate: "webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend",
        websocketUrl: "",
        sessionID: 0,
        companyID: 0,
        hID: 0,
        userID: 0,
        photoUrl: "",
        isTest: 2,
        rand: 0,
        recheck: 0
    },
    flag = !0,
    canvasWidth = $("#canvas").width(),
    canvasHeight = $("#canvas").height(),
    strokeColor = "rgb(277,0,82)",
    lineWidth = 10,
    isMouseDown = !1,
    lastLoc = {x: 0, y: 0},
    curLoc = {x: 0, y: 0},
    imgArr = [],
    isErase = !1,
    canvas = document.getElementById("canvas"),
    context = canvas.getContext("2d");
canvas.width = canvasWidth, canvas.height = canvasHeight,

    //手绘初始化
    shouhui.initEvent = function () {
        function h(a) {
            var b = document.createElement("canvas");
            return b.width = a.width, b.height = a.height, a.toDataURL() == b.toDataURL()
        }

        function i(a) {
            isMouseDown = !0, lastLoc = m(a.x, a.y), context.save(), context.beginPath(), context.moveTo(lastLoc.x, lastLoc.y)
        }

        function j() {
            isMouseDown = !1;
            var a = canvas.toDataURL();
            imgArr.push(a)
        }


        //绘制图形函数
        function k(a) {
            curLoc = m(a.x, a.y), isErase ? (context.globalCompositeOperation = "destination-out", context.lineTo(curLoc.x, curLoc.y), context.strokeStyle = "rgba(255,255,255,1)", context.lineWidth = 100, context.stroke()) : (context.globalCompositeOperation = "source-over", context.lineTo(curLoc.x, curLoc.y), context.strokeStyle = "rgba(" + f[g] + ",.9)", context.lineWidth = lineWidth, "20" == context.lineWidth ? (context.strokeStyle = "rgba(" + f[g] + ",.1)", context.miterLimit = 5) : "2" == context.lineWidth && (context.miterLimit = 10, context.lineCap = "round"), context.stroke()), lastLoc = curLoc
        }

        function m(a, b) {
            var c = canvas.getBoundingClientRect();
            return {x: Math.round(a - c.left), y: Math.round(b - c.top)}
        }

        var a, b, c, d, e, f, g;
        $(".cancel").on("click", function () {
            location.href = shouhui.indexUrl;
        }),
        $("#clear_btn").click(function () {
            context.clearRect(0, 0, canvasWidth, canvasHeight), imgArr = []
        }),
        a = 1, b = 1, c = 1, f = ["227, 0, 82", "50, 177, 108", "241, 151, 21", "0, 184, 236", "95, 84, 158", "182, 169, 0", "0, 87, 82", "3, 0, 74", "130, 78, 0", "54, 46, 43"], g = 0,
            //画笔类型
            $(".pLi .pn").on("click", function () {
                a = $(".pLi .pn").index(this),
                    $(".pLi .pn").removeClass("panChecked"),
                    $(".pLi .pn").removeClass("panDelChecked"),
                a == c || (
                    b = c, c = a,
                        $(".pLi .pn:eq(" + b + ")").addClass("panDelChecked"),
                        $(".pLi .pn:eq(" + b + ")").removeClass("active"),
                        $(this).addClass("panChecked"),
                        $(this).addClass("active")
                ),
                    lineWidth = $(this).attr("data-width"),
                    isErase = "3" == a ? !0 : !1
            }),
            //取色器
            $("#js_colorBar").on("click", function () {
                isErase = !1, 3 == a && (
                    $(".pLi .pn:eq(" + a + ")").removeClass("active"),
                        $(".pLi .pn:eq(" + b + ")").addClass("active"),
                        a = b, c = b
                ),
                    d = $(".pLi .pn:eq(" + a + ")").offset().left,
                    e = $(".pLi .pn:eq(" + a + ")").offset().top - ($(window).height() - 210),
                    $(".cLi").removeClass("hidden"),
                    $(".cLi .pn").css({left: d, top: e}),
                    $(".cLi .pn").animate({left: 65, top: 30}, 300, "linear"),
                    $(".pLi").animate({top: 210}, 300, "linear"),
                    $(".pLi .pn:eq(" + a + ")").css("opacity", 0),
                    $(".cLi .cLs li").removeClass("colorOut"),
                    $(".cLi .cLs li").addClass("colorIn"),
                    $(".cLi .pn").css("background", "url(" + shouhui.photoUrl + "pan" + a + ".png)"),
                    lineWidth = $(".pLi .pn:eq(" + a + ")").attr("data-width")
            }),
            $(".cLi .pn").on("click", function () {
                $(".cLi .cLs li").removeClass("colorIn"),
                    $(".cLi .cLs li").addClass("colorOut"),
                    $(".cLi .pn").animate({left: d, top: e}, 300, "linear"),
                    $(".pLi").animate({top: 0}, 300, "linear"),
                    setTimeout(function () {
                        $(".cLi ").addClass("hidden"),
                            $(".pLi .pn:eq(" + a + ")").css("opacity", 1)
                    }, 300)
            }),
            $(".cLi li").on("click", function () {
                $(".cLi li").removeClass("active"),
                    $(this).addClass("active"),
                    g = $(".cLi li").index(this)
            }),
            //发送canvas到后台
            $("#img_btn").on("click", function () {
                if (h(canvas)) return $("#btn-success").html("您还没有留下大名呢~"),
                    $("#pro-img").attr("src", shouhui.photoUrl + "icon-warn.png"),
                    $(".pop-box").fadeIn("slow"),
                    setTimeout(function () {
                        $(".pop-box").fadeOut("slow")
                    }, 1e3), void 0;
                var a = canvas.toDataURL("image/png"),
                    b = new Image;
                b.src = a,
                    context.clearRect(0, 0, canvasWidth, canvasHeight),
                    imgArr = [],
                    shouhui.fire("", {url: a})
            }),
            context.lineCap = "round",
            context.lineJoin = "round",
            canvas.onmousedown = function (a) {
                a.preventDefault(),
                    i({x: a.clientX, y: a.clientY})
            },
            canvas.onmouseup = function (a) {
                a.preventDefault(), j()
            },
            canvas.onmouseout = function (a) {
                a.preventDefault(), j()
            },
            canvas.onmousemove = function (a) {
                a.preventDefault(), isMouseDown && k({x: a.clientX, y: a.clientY})
            },
            canvas.addEventListener("touchstart", function (a) {
                a.preventDefault(), touch = a.touches[0], i({x: touch.pageX, y: touch.pageY})
            }),
            canvas.addEventListener("touchmove", function (a) {
                a.preventDefault(), isMouseDown && (touch = a.touches[0], k({x: touch.pageX, y: touch.pageY}))
            }),
            canvas.addEventListener("touchend", function (a) {
                a.preventDefault(), j()
            })
    },
    //发送函数
    shouhui.fire = function (a, b) {
        // console.log(b.url);
        $.post(shouhui.ajaxUrl, {url: 1, params: b.url}, function (idata) {
            $("#pro-img").attr("src", shouhui.photoUrl + "icon-warn.png");
            $(".pop-box").fadeIn("slow");
            setTimeout(function () {
                location.href = shouhui.indexUrl;
            }, 1e3);
            // console.log(idata);
        }, "json");

    };

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值