学写一个字

July 9, 2021 · 程序 · 6404次阅读

这里是我用html5制作的web APP,功能比较少,待扩充。

这个web APP是通过慕课网,学习liuyubobobo老师的《学写一个字》课程而制作的,功能还比较简单,我可能会慢慢完善它。传送门

最终效果

您的浏览器不支持canvas
清 除

HTML部分

    <canvas id="canvas">您的浏览器不支持canvas</canvas>
    <div id="controller">
        <div id="black_btn" class="color_btn color_btn_selected"></div>
        <div id="blue_btn" class="color_btn"></div>
        <div id="red_btn" class="color_btn"></div>
        <div id="yellow_btn" class="color_btn"></div>
        <div id="green_btn" class="color_btn"></div>
        <div id="orange_btn" class="color_btn"></div>
        <div id="clear_btn" class="op_btn">清 除</div>
        <div class="clearfix"></div>
    </div>

CSS部分

#canvas{
    display: block;
    margin: 0 auto;
}
#controller{
    margin: 0 auto;
}
.op_btn{
    float: right;
    margin: 10px 0 0 10px;
    border: 2px solid #aaa;
    width: 80px;
    height: 40px;
    line-height: 40px;
    font-size: 20px;
    text-align: center;
    border-radius: 5px 5px;
    cursor: pointer;
    background-color: white;
    font-weight: bold;
    font-family: Microsoft Yahei,Arial;
}
.op_btn:hover{
    background-color: #def;
}
.clearfix{
    clear: both;
}
.color_btn{
    float: left;
    margin: 5px 5px 0 0;
    border: 5px solid white;
    border-radius: 5px 5px;
    cursor: pointer;
}
.color_btn:hover{
    border: 5px solid violet;
}
.color_btn_selected{
    border: 5px solid violet;
}
#black_btn{
    background-color: black;
}
#blue_btn{
    background-color: blue;
}
#red_btn{
    background-color: red;
}
#yellow_btn{
    background-color: yellow;
}
#green_btn{
    background-color: green;
}
#orange_btn{
    background-color: orange;
}

javascript部分

$(function(){
    var canvasWidth = Math.min(700, $(window).width() - 70);
    var canvasHeight = canvasWidth;
    var strokeColor = 'black';
    var isMouseDown = false;
    var lastLoc = {x:0,y:0};
    var lastTimestamp = 0;
    var lastLineWidth = -1;
    var canvas = document.getElementById('canvas');
    var context = canvas.getContext('2d');
    canvas.width = canvasWidth;
    canvas.height = canvasHeight;
    $('#controller').css('width',canvasWidth + 'px');
    $('.color_btn').css({'width':canvasWidth/10 + 'px','height':canvasWidth/10 + 'px'});
    drawGrid();
    $('#clear_btn').click(function(e){
        context.clearRect(0,0,canvasWidth,canvasHeight);
        drawGrid();
    });
    $('.color_btn').click(function(e){
        $('.color_btn').removeClass('color_btn_selected');
        $(this).addClass('color_btn_selected');
        strokeColor = $(this).css('background-color');
    });
    function beginStroke(point){
        isMouseDown = true;
        lastLoc = windowsToCanvas(point.x,point.y);
        lastTimestamp = new Date().getTime();
    };
    function endStroke(){
        isMouseDown = false;
    };
    function moveStroke(point){
        var curLoc = windowsToCanvas(point.x,point.y);
        var curTimestamp = new Date().getTime();
        var s = calcDistance(curLoc,lastLoc);
        var t = curTimestamp - lastTimestamp;
        var lineWidth = calcLineWidth(t,s);
        // draw
        context.beginPath();
        context.moveTo(lastLoc.x,lastLoc.y);
        context.lineTo(curLoc.x,curLoc.y);
        context.strokeStyle = strokeColor;
        context.lineWidth = lineWidth;
        context.lineCap = 'round';
        context.lineJoin = 'round';
        context.stroke();
        lastLoc = curLoc;
        lastTimestamp = curTimestamp;
        lastLineWidth = lineWidth;
    };
    canvas.onmousedown = function(e){
        e.preventDefault();
        // console.log('mouse down');
        beginStroke({x:e.clientX,y:e.clientY});
    };
    canvas.onmouseup = function(e){
        e.preventDefault();
        // console.log('mouse up');
        endStroke();
    };
    canvas.onmouseout = function(e){
        e.preventDefault();
        // console.log('mouse out');
        endStroke();
    };
    canvas.onmousemove = function(e){
        e.preventDefault();
        if(isMouseDown){
            // console.log('mouse move');
            moveStroke({x:e.clientX,y:e.clientY})
        }
    };
    canvas.addEventListener('touchstart',function(e){
        e.preventDefault();
        touch = e.touches[0];
        beginStroke({x:touch.clientX,y:touch.clientY});
    });
    canvas.addEventListener('touchmove',function(e){
        e.preventDefault();
        touch = e.touches[0];
        moveStroke({x:touch.clientX,y:touch.clientY});
    });
    canvas.addEventListener('touchend',function(e){
        e.preventDefault();
        endStroke();
    });
    // 线条粗细
    function calcLineWidth(t,s){
        var maxLineWidth = Math.min(30, canvasWidth / 30);
        var minLineWidth = 1;
        var maxStrokeV   = 10;
        var minStrokeV   = 0.1;
        var v = s / t;
        var resultLineWidth;
        if(v <= minStrokeV){
            resultLineWidth = maxLineWidth;
        }
        else if(v >= maxStrokeV){
            resultLineWidth = minLineWidth;
        }
        else{
            resultLineWidth = maxLineWidth - (v * minStrokeV)/(maxStrokeV - minStrokeV) * (maxLineWidth - minLineWidth);
        }
        if(lastLineWidth == -1){
            return resultLineWidth;
        }
        else{
            return lastLineWidth * 0.9  + resultLineWidth * 0.1;
        }
    };
    // 两点间距离
    function calcDistance(loc1,loc2){
        return Math.sqrt((loc1.x - loc2.x) * (loc1.x - loc2.x) + (loc1.y - loc2.y) * (loc1.y - loc2.y))
    };
    // 窗口坐标转canvas坐标
    function windowsToCanvas(x,y){
        var bbox = canvas.getBoundingClientRect();
        return {x:Math.round(x - bbox.left),y:Math.round(y - bbox.top)};
    };
    // 绘制网格
    function drawGrid(){
        context.save();
        context.strokeStyle = "rgb(230,11,9)";
        context.lineWidth = 6;
        context.strokeRect(3,3,canvasWidth - 6,canvasHeight - 6);
        context.lineWidth = 1;
        drawDashes(context, 0, 0, canvasWidth, canvasHeight);
        drawDashes(context, canvasWidth, 0, 0, canvasHeight);
        drawDashes(context, canvasWidth / 2, 0, canvasWidth / 2, canvasHeight);
        drawDashes(context, 0, canvasHeight / 2, canvasWidth, canvasHeight / 2);
        context.restore();
    };
    // 绘制虚线
    function drawDashes(ctx, x1, y1, x2, y2, dashLength){
        ctx.beginPath();
        var dashLen = dashLength === undefined ? 5:dashLength;
        xpos = x2 - x1;
        ypos = y2 - y1;
        numDashs = Math.floor(Math.sqrt(xpos*xpos + ypos*ypos)/dashLen);
        for (var i = 0; i < numDashs; i++) {
            if(i%2 === 0){
                ctx.moveTo(x1 + (xpos/numDashs)*i, y1 + (ypos/numDashs)*i);
            }
            else{
                ctx.lineTo(x1 + (xpos/numDashs)*i, y1 + (ypos/numDashs)*i);
            }
        };
        ctx.stroke();
        ctx.closePath();
    };
});

喝杯水 ENJOY 1

canvasweb app

最后编辑于3年前

添加新评论

avatar

朱益雷

有趣的灵魂万里挑一

10

文章数

0

评论数

3

分类

热死辣

新鲜出炉の评论

无最新回复