javascript - Canvas 固定绘图点

标签 javascript canvas

我已经创建了一个绘图 Canvas 。在 JavaScript 中。 但是当我快速移动鼠标时,我没有一条完整的线,而是一 strip 有点的线。 我为此使用了圆弧,我不知道有更好的选择来绘制线条

我该如何解决这个问题?

已经谢谢了

<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();

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

关于javascript - Canvas 固定绘图点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34833080/

相关文章:

javascript - html5 : Show an image OVER the canvas

canvas - 使用 ThreeJS 更新 `THREE.Sprite` 内的文本

javascript - 传递数组时,调用和 apply 都会为 String.prototype.toUppercase 产生相同的结果

javascript - JQplot barRenderer "y-axis"值从负值开始

javascript - 通知我网站的 Android 用户从网站安装 Android 应用程序?

Android:绘制基本的圆形轮廓到 RelativeLayout

javascript - Javascript Canvas 游戏的边界

javascript - 使用格式化程序绑定(bind)编辑图标时,Angular8(制表符)中未触发 onclick 事件

javascript - 错误 : No Such Package when bundling Meteor. js 应用程序

javascript - 如何使用单击事件处理程序在点之间画线?