画布修复绘图点

Canvas fix drawing points

本文关键字:绘图 布修复      更新时间:2023-09-26

我创建了一个绘图画布。在javascript中。但是当我快速移动鼠标时,我没有一条完整的线,而是一条带有点的线。我为此使用了弧形,我不知道是否有更好的选择来绘制线条

我该如何解决这个问题?

已经谢谢了

<script type="application/javascript" src="jquery.js"></script>
<script>
    var canvas;
    var ctx;
    var StartDraw = false;
    var dikte = 7;
$(document).ready(DoInit());
    function DoInit()
    {
         canvas = document.getElementById("canvas");
         ctx = canvas.getContext('2d');
        $(".kleur").on('click',doKleur);
        $("canvas").on('mouseup',DoUp);
        $("canvas").on('mousedown',DoDown);
        $("canvas").on('mousemove',DoMove)
        $("#dikte").on('change',doDikte);
        $(".clear").on('click',clear);
    }
    function doDikte(){
        dikte  = this.value;
    }
    function clear(){
       ctx.clearRect(0,0,canvas.width,canvas.height);
    }
    function doKleur(){
        ctx.fillStyle = this.id;
    }
    function DoDown()
    {
        StartDraw = true;
    }
    function DoUp()
    {
        StartDraw = false;
    }
    function DoDot(x,y)
    {
            ctx.beginPath();
            ctx.arc(x, y, dikte, 0, Math.PI * 2, false);
            ctx.closePath();
            ctx.fill();
    }
    function DoMove(event)
    {
        if(StartDraw)
        {
            DoDot(event.offsetX, event.offsetY)
        }
    }

</script>
<style>
    canvas
    {
        border: solid 5px red;
        border-radius: 15px;
    }
</style>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<canvas id="canvas" width="1000" height="650"></canvas>
<input class="kleur" type="button" id="blue" value="blauw">
<input class="kleur" type="button" id="green" value="groen">
<input class="kleur" type="button" id="red" value="rood">
<input class="kleur" type="button" id="black" value="zwart">
<input class="kleur" type="button" id="orange" value="oranje">
<input type="button" class="clear" value="clear">
<input type="range" id="dikte" min="1" max="35" value="7">
</body>
</html>

您需要检查鼠标何时刚刚被单击、何时被按住、何时释放或只是快速单击。您需要在拖动鼠标时绘制线段,如果是快速单击,则需要绘制一个点。

我更喜欢将所有鼠标

事件捆绑到一个函数中,然后创建一个抽象的鼠标对象,然后用于满足我的任何需求。

当我处理鼠标事件时,无论是移动还是单击,我做的最后一件事就是保存按钮状态。这意味着下次调用鼠标事件时,我通过检查上次和当前鼠标按钮状态来知道按钮是刚刚单击、正在按住还是刚刚向上。您可能会说mousedownmouseup事件已经为您做到了这一点,是的,它们确实如此,您没有理由不使用它们。从长远来看,我只是发现它更容易,因为我可以操纵鼠标状态。

因此,当鼠标第一次向下时,记录坐标,

然后在鼠标移动时,从最后一个坐标到新坐标画一条线。当鼠标按钮上升时,然后快速检查它是否只是一个要绘制的点,如果是,则不执行任何操作。

下面是一个示例。鼠标代码位于底部,mouse.buttonRaw是当前鼠标按钮状态的位字段,其中第一位为左边,第二位为中间,第三位为右。

var mouse;
document.body.innerHTML = "Use mouse to draw on the this snippet.";
var demo = function(){
    var canvas = (function(){
        var canvas = document.getElementById("canv");
        if(canvas !== null){
            document.body.removeChild(canvas);
        }
        // creates a blank image with 2d context
        canvas = document.createElement("canvas"); 
        canvas.id = "canv";    
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight; 
        canvas.style.position = "absolute";
        canvas.style.top = "0px";
        canvas.style.left = "0px";
        canvas.style.zIndex = 1000;
        canvas.ctx = canvas.getContext("2d"); 
        document.body.appendChild(canvas);
        return canvas;
    })();
    var ctx = canvas.ctx;
    
    if(mouse !== undefined){  // if the mouse exists 
        mouse.removeMouse(); // remove previous events
    }
    var canvasMouseCallBack = undefined;  // if needed
    // my mouse handler has more functionality than needed but to lazy to clean it ATM
    mouse = (function(){
        var mouse = {
            x : 0, 
            y : 0,
            w : 0, 
            alt : false, 
            shift : false, 
            ctrl : false,
            interfaceId : 0, 
            buttonLastRaw : 0,  
            buttonRaw : 0,
            over : false,  // mouse is over the element
            bm : [1, 2, 4, 6, 5, 3], // masks for setting and clearing button raw bits;
            getInterfaceId : function () { return this.interfaceId++; }, // For UI functions
            startMouse:undefined,
            mouseEvents : "mousemove,mousedown,mouseup,mouseout,mouseover,mousewheel,DOMMouseScroll".split(",")
        };
        function mouseMove(e) {
            var t = e.type, m = mouse;
            m.x = e.offsetX; 
            m.y = e.offsetY;
            if (m.x === undefined) { m.x = e.clientX; m.y = e.clientY; }
            m.alt = e.altKey;
            m.shift = e.shiftKey;
            m.ctrl = e.ctrlKey;
            if (t === "mousedown") { m.buttonRaw |= m.bm[e.which-1];
            } else if (t === "mouseup") { m.buttonRaw &= m.bm[e.which + 2];
            } else if (t === "mouseout") { m.buttonRaw = 0; m.over = false;
            } else if (t === "mouseover") { m.over = true;
            } else if (t === "mousewheel") { m.w = e.wheelDelta;
            } else if (t === "DOMMouseScroll") { m.w = -e.detail;}
            // call mouse callback if set
            if (canvasMouseCallBack) { canvasMouseCallBack(mouse); }
            e.preventDefault();
        }
        // function to add events to element
        function startMouse(element){
            if(element === undefined){
                element = document;
            }
            mouse.element = element;
            mouse.mouseEvents.forEach(
                function(n){
                    element.addEventListener(n, mouseMove);
                }
            );
            element.addEventListener("contextmenu", function (e) {e.preventDefault();}, false);
        }
        // function to remove events
        mouse.removeMouse = function(){
            if(mouse.element !== undefined){
                mouse.mouseEvents.forEach(
                    function(n){
                        mouse.element.removeEventListener(n, mouseMove);
                    }
                );
                canvasMouseCallBack = undefined;
            }
        }
        mouse.mouseStart = startMouse;
        return mouse;
    })();
    // if there is a canvas add the mouse event else add to document
    if(typeof canvas !== "undefined"){
        mouse.mouseStart(canvas);
    }else{
        mouse.mouseStart();
    }
    // for the previouse mouse state
    var lastMouseButton = 0;
    var x,y,xx,yy; //for saving line segments drawn
    // set up drawing
    ctx.fillStyle = "red";
    ctx.strokeStyle = "red";
    ctx.lineWidth = 10;
    ctx.lineJoin = "round";
    ctx.lineCap = "round";
    // set the mouse callback function. It is called for every mouse event
    canvasMouseCallBack = function(mouse){
        // is the first (left) button down and the last button state up?
        if((mouse.buttonRaw & 1) === 1 && (lastMouseButton & 1) === 0){
            x = mouse.x;  // save the mouse coordinates
            y = mouse.y;
        }else
        // is both the mouse button down and the last one down 
        if((mouse.buttonRaw & 1) === 1 && (lastMouseButton & 1) === 1){
            xx = x;  // yes move the last coordinate to the 
            yy = y;  // start of the line segment
            x = mouse.x;  // get the mouse coords for the end of the line seg
            y = mouse.y;
            ctx.beginPath();  // draw the line segment
            ctx.moveTo(x,y);
            ctx.lineTo(xx,yy);
            ctx.stroke();
        }else
        // has the mouse just been released
        if( (mouse.buttonRaw  & 1) === 0 && (lastMouseButton & 1) === 1){
            if(xx === undefined){  // if xx is undefined then no line segment 
                                   // has been drawn so need to ad just a point
                ctx.beginPath();  // draw a point at the last mouse point
                ctx.arc(x,y,5,0,Math.PI*2);
                ctx.fill();
            }
            xx = undefined;  // clear the line segment start
            
        }
        // save the last mouse start
        lastMouseButton = mouse.buttonRaw;
    }
}
// resize demo to fit window if needed
window.addEventListener("resize",demo);
// start the demo
demo();

您可能还对这个答案感兴趣,该答案也涉及绘图,但演示了如何平滑正在绘制的线条,因为鼠标输入可能非常脏。平滑线条