画板canvas

实现一个画板:1.容器

canvas = document.getElementById('J-draw-canvas');
 ctx = canvas.getContext("2d");

getContext() 方法可返回一个对象,该对象提供了用于在画布上绘图的方法和属性;

                    2.绘画和记录步骤

ctx.beginPath();              // beginPath() 方法开始一条路径,或重置当前的路径
ctx.strokeStyle = 'black';
ctx.lineWidth = 5;
ctx.lineJoin = "round";    // 设置两条线相交时的拐角类型,默认尖角,设置为圆角
ctx.lineCap = "round";    // lineCap 属性设置或返回线条末端线帽的样式。
ctx.moveTo(lastX, lastY);  // 把路径移动到画布中的指定点,不创建线条
ctx.lineTo(x, y);               // 添加一个新点,然后在画布中创建从该点到最后指定点的线条
ctx.closePath();               // 创建从当前点回到起始点的路径
ctx.stroke();                 //  绘制

--------

ps: touches是当前屏幕上所有触摸点的列表;
     targetTouches是当前对象上所有触摸点的列表;
     changedTouches是涉及当前事件的触摸点的列表。

                    3.返回上一步

ctx.getImageData      // getImageData() 复制画布上指定矩形的像素数据,然后将这些数据放在一个数组里,需要返回上一步时就删除一组数据

                    4.清空

ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);    //  以绘图板宽高清空
preDrawAry = [];   // 步数数组为空

                    5.将canvas转成图片,保存路径上传

 var url = canvas.toDataURL('image/jpg');  // 向后端发请求保存

var $ = require('wiki-mobile-common:widget/lib/zepto/zepto.js');

var init = function () {
  
    var mousePressed = false;
    var lastX, lastY;
    var isMove = false;
    var isEnd = false;
    var canvas;
    var ctx;
    var preDrawAry = [];
    var submitLock = false;
    // 计算画板方法
    function calBoard() {
        var boardSize = $(window).width() * 0.94;
        var maxHeight = $(window).height() - 165;
        if (boardSize < maxHeight) {
            $('#J-draw-board').css({
                'margin-top': (maxHeight - boardSize) / 2 + 10,
                'margin-bottom': (maxHeight - boardSize) / 2 + 10,
                'margin-left': 0
            });
        }
        else {
            boardSize = maxHeight;
            $('#J-draw-board').css({
                'margin-top': '10px',
                'margin-bottom': '10px',
                'margin-left': ($(window).width() * 0.94 - boardSize) / 2
            });
        }
        $('#J-draw-board').width(boardSize).height(boardSize);
        $('#J-draw-canvas')[0].width = boardSize - 1;
        $('#J-draw-canvas')[0].height = boardSize - 1;
    }
    setTimeout(function () {
        calBoard();
        $('#J-draw-board').show();
        $('.draw-footer').show();
    }, 200);
    canvas = document.getElementById('J-draw-canvas');
    ctx = canvas.getContext("2d");

    // 选择笔的粗细
    $('.pen-size').on('tap', function () {
        $('.pen-size').removeClass('current');
        $(this).addClass('current');
    });

    // 绘画
    $('#J-draw-canvas').on('touchstart', function (e) {
        $('#J-draw-tips').hide();
        mousePressed = true;
        isMove = false;
        isEnd = false;
        var touch = event.changedTouches[0];
        Draw(touch.pageX - $(this).offset().left, touch.pageY - $(this).offset().top, false);
        // 当前绘图表面状态  
        var preData = ctx.getImageData(0, 0, canvas.width, canvas.height);
        // 当前绘图表面进栈  
        preDrawAry.push(preData);
        e.preventDefault();
    });
 
    $('#J-draw-canvas').on('touchmove', function (e) {
        isMove = true;
        var touch = event.changedTouches[0];
        if (mousePressed) {
            Draw(touch.pageX - $(this).offset().left, touch.pageY - $(this).offset().top, true);
        }
        e.preventDefault();
    });
 
    $('#J-draw-canvas').on('touchend', function (e) {
        mousePressed = false;
        isEnd = true;
        var touch = event.changedTouches[0];
        Draw(touch.pageX - $(this).offset().left, touch.pageY - $(this).offset().top, false);
        e.preventDefault();
    });

    // 清空画板
    $('#J-handle-clear').on('tap', function () {
        clearArea();
    });

    // 上一步
    $('#J-handle-revoke').on('tap', function () {
        prevStep();
    });

    // 提交,上传作品
    $('#J-draw-submit').on('tap', function () {
        if (preDrawAry.length < 3) {
            showTips('画的太简单了~', '再添几笔');
            return;
        }
        $('.input-name').show();
        $('#J-layer').height($(window).height()).css('display', 'block');
    });
    $('.upload-submit').on('tap', function () {
        if ($('.author-name').val() === '') {
            $('.input-name').hide();
            showTips('大侠留个名号', '朕知道了', 'add-name-btn');
        }else {
            uploadImage($('.author-name').val());
        }
    });
    $('#J-layer').on('touchstart', function () {
        $('.input-name').hide();
        clearTips();
        $(this).hide();
        e.preventDefault();
    });
    // tips关闭
    $('.tips-btn').live('tap', function () {
        clearTips();
        $('#J-layer').hide();
    }).on('touchstart', function (e) {
        e.preventDefault();
    });
    $('.tips-btn.add-name-btn').live('tap', function () {
        $('.input-name').show();
        $('#J-layer').css('display', 'block');
        $(this).removeClass('add-name-btn');
    });
    // 关闭默认行为
    $('.tips-layer').on('touchstart', function (e) {
        e.preventDefault();
    });
    
    // 画图
    function Draw(x, y, isDown) {
        if (isDown) {
            ctx.beginPath();
            ctx.strokeStyle = 'black';
            ctx.lineWidth = $('.pen-size.current').data('size');
            ctx.lineJoin = "round";
            ctx.lineCap = "round";
            ctx.moveTo(lastX, lastY);
            ctx.lineTo(x, y);
            ctx.closePath();
            ctx.stroke();
        }
        lastX = x; lastY = y;
        if (!isMove && isEnd) {
            ctx.beginPath();
            ctx.strokeStyle = 'black';
            ctx.arc(lastX, lastY, $('.pen-size.current').data('size'), 0, 2*Math.PI, true);
            ctx.closePath();
            ctx.fillStyle = 'black';
            ctx.fill();  
        }
    }
    // 上一步
    function prevStep() {
        if (preDrawAry.length > 0) {  
            var popData = preDrawAry.pop();
            ctx.putImageData(popData, 0, 0);
        }
        if (preDrawAry.length === 0) {
            $('#J-draw-tips').show();
        }
    }
    // 清画板
    function clearArea() {
        $('#J-draw-tips').show();
        ctx.setTransform(1, 0, 0, 1, 0, 0);
        ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
        preDrawAry = []; 
    } 
    // 上传作品
    function uploadImage(name) {
        if (preDrawAry.length <= 0) {
            return;
        }
        if (submitLock) {
            return;
        }
        var url = canvas.toDataURL('image/jpg');
        submitLock = true;
        $.post("/xx/api/publish", {
                content: url,
                name: name
        }, function (data) {
            if (data.errno === 0) {
                window.location.href = '/xx?drawingId=' + data.id + '#list';
            }else if (data.errno === 4) {
                showTips('画的太简单了~', '再添几笔');
                $('.input-name').hide();
                submitLock = false;
            }else if (data.errno === 7) {
                showTips('提交太快了,休息一会再画吧~', '休息一下');
                $('.input-name').hide();
                submitLock = false;
            }else {
                showTips('上传失败', '再传一次', 'add-name-btn');
                $('.input-name').hide();
                submitLock = false;
            }
        });
    }
    // 生成tips提示
    function showTips(content, btn, btnClass) {
        if (!!btnClass) {
           $('.tips-btn').addClass(btnClass); 
        }
        $('.tips-con').text(content);
        $('.tips-btn').text(btn);
        $('#J-layer').css('display', 'block');
        $('.tips-layer').show();
    }
    // 清空提示板
    function clearTips() {
        $('.tips-con').text('');
        $('.tips-btn').text('');
        $('.tips-layer').hide();
    }
}
<div class="main">
    <div class="draw-header">
        <div class="draw-submit" id="J-draw-submit">发布</div>
        <div class="go-home">
            <a href="/shiji/myshiji" class="go-home-link" id="J-go-home">
                <em class="layout-icons layout-icons_left-arrow"></em>
                回首页
            </a>
        </div>
    </div>
    <div class="draw-board" id="J-draw-board">
        <div class="draw-tips" id="J-draw-tips">幅图画</div>
        <canvas class="draw-canvas" width='0' height='0' id="J-draw-canvas"></canvas>
    </div>
    <div class="layer" id="J-layer"></div>
    <div class="input-name">
        <input class="author-name" type="text" placeholder="请输入你的昵称" maxlength="20"/>
        <div class="upload-submit-container"><input class="upload-submit" type="button" value="确定"/></div>
    </div>
    <div class="tips-layer">
        <div class="tips-con"></div>
        <div class="tips-btn"></div>
    </div>
    <div class="draw-footer">
        <div class="draw-handle">
            <div class="title">操作:</div>
            <div class="handle-btn handle-revoke" id="J-handle-revoke">
                <em class="layout-icons layout-icons_revoke"></em>撤销
            </div>
            <div class="handle-btn handle-clear" id="J-handle-clear">
                <em class="layout-icons layout-icons_delete"></em>清空
            </div>
        </div>
        <div class="draw-setting">
            <div class="title">笔触:</div>
            <ul class="pen-size-list">
                <li class="pen-size pen-size-small" data-size="2"><span></span></li>
                <li class="pen-size pen-size-middle current" data-size="4"><span></span></li>
                <li class="pen-size pen-size-big" data-size="6"><span></span></li>
            </ul>
        </div>
    </div>
</div>
原文地址:https://www.cnblogs.com/zhangxinxin111/p/5089140.html