4

キャンバスを使用してスケッチアプリに取り組んでいます。私のコードで消しゴムを動作させることができないようです。Stack Overflow から多くの回答を試しましたが、ほとんどが機能しません。

例えば:

  1. の設定globalcompositeoperation
  2. alpha0に設定
  3. clearRect消去するために使用します。これは機能しましたが、ブラウザが非常に遅くなりました。

だから私は誰かがこれについて私を助けてくれることを望んでいました.

ここにデモがあり、ここに私のコードがあります:

<html>
    <head>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
        <style type="text/css">
            /*#canvas{background: #F6F683}*/
            .canvasBackground{ position: absolute; top: 8px; left: 8px; width: 1000px; height: 2400px;z-index: -10;}
            #main { position: fixed; top: 5px; left: 1020px; width: 280px; height: 250px;}
            .icon{ cursor: pointer; cursor: hand; }
        </style>
        <script type="text/javascript" src="../js/jquery-1.9.1.js"></script>
        <script type="text/javascript">
            var lWidthE = 15;    //Line width eraser
            var lWidthM = 2;    //Line width marker

            $(document).ready(function() {
                $('.canvasBackground').css("background-image", "url(http://s22.postimg.org/i83b7ztch/notepad_page.png)");
            });

            var canvas;
            var ctx;

            var started = false;
            var lastx = 0;
            var lasty = 0;

            var memCanvas;
            var memCtx;

            var pointerCanvas;
            var pCtx;

            var points = [];

            function init() {
                // Bind canvas to listeners
                canvas = document.getElementById('canvas');
                canvas.addEventListener('mousedown', mouseDown, false);
                document.addEventListener('mousemove', mouseMove, false);
                document.addEventListener('mouseup', mouseUp, false);

                ctx = canvas.getContext('2d');

                // create an in-memory canvas
                memCanvas = document.createElement('canvas');
                memCanvas.width = 1000;
                memCanvas.height = 2400;
                memCtx = memCanvas.getContext('2d');
                ctx.lineJoin = 'round';
                ctx.lineCap = 'round';
            }

            function ctx_stuff() {
                if (v) {
                    ctx.lineWidth = lWidthE;
                    ctx.globalCompositeOperation = "source-over";
                    ctx.strokeStyle = "rgba(246,246,131,0)";
                }
                else {
                    ctx.lineWidth = lWidthM;
                    ctx.globalCompositeOperation = "source-over";
                    ctx.strokeStyle = "rgba(0,0,0,1)";
                }
            }

            function mouseDown(e) {
                var m = getMouse(e, canvas);
                points.push({
                    x: m.x,
                    y: m.y
                });
                started = true;
                ctx.clearRect(0, 0, 1000, 2400);
                // put back the saved content
                ctx.drawImage(memCanvas, 0, 0);
                memCtx.clearRect(0, 0, 1000, 2400);
                memCtx.drawImage(canvas, 0, 0);
                drawPoints(ctx, points);
            }

            function mouseMove(e) {
                if (started) {//to doodle
                    ctx.clearRect(0, 0, 1000, 2400);
//                    // put back the saved content
                    ctx.drawImage(memCanvas, 0, 0);
                    var m = getMouse(e, canvas);
                    points.push({
                        x: m.x,
                        y: m.y
                    });
                    drawPoints(ctx, points);
                } else {//to show where start point of doodle
                    var m = getMouse(e, canvas);
                    points.push({
                        x: m.x,
                        y: m.y
                    });
                    ctx.clearRect(0, 0, 1000, 2400);
                    // put back the saved content
                    ctx.drawImage(memCanvas, 0, 0);
                    drawPoints(ctx, points);
                    points = [];
                }
            }

            function mouseUp(e) {
                if (started) {
                    started = false;
                    // When the pen is done, save the resulting context
                    // to the in-memory canvas
                    memCtx.clearRect(0, 0, 1000, 2400);
                    memCtx.drawImage(canvas, 0, 0);
                    ctx.drawImage(memCanvas, 0, 0);
                    points = [];
                }
            }

            // clear both canvases!
            function clear123() {
                ctx.clearRect(0, 0, 1000, 2400);
                memCtx.clearRect(0, 0, 1000, 2400);
                cleanUpArray();
            }

            var small_x = 0, small_y = 0, big_x = 0, big_y = 0;

            function drawPoints(ctx, points) {
                ctx_stuff();
                // draw a basic circle instead
                if (points.length < 6) {
                    var b = points[0];
                    if (v) {
                        ctx.beginPath(), ctx.arc(b.x, b.y, ctx.lineWidth / 2, 0, Math.PI * 2, !0), ctx.closePath(), ctx.fillStyle = "rgba(246,246,131,0)", ctx.fill();
//                        ctx.clearRect(b.x - (lWidthE / 2), b.y - (lWidthE / 2), (lWidthE), (lWidthE));

                    } else {
                        ctx.beginPath(), ctx.arc(b.x, b.y, ctx.lineWidth / 2, 0, Math.PI * 2, !0), ctx.closePath(), ctx.fillStyle = "rgba(0,0,0,1)", ctx.fill();
                    }
                    return;
                }

                ctx.beginPath(), ctx.moveTo(points[0].x, points[0].y);
                // draw a bunch of quadratics, using the average of two points as the control point
                for (var i = 1; i < points.length - 2; i++) {
                    var c = (points[i].x + points[i + 1].x) / 2,
                            d = (points[i].y + points[i + 1].y) / 2;
//                    if (v) {
//                        ctx.clearRect(points[i].x - (lWidthE / 2), points[i].y - (lWidthE / 2), lWidthE, lWidthE);
//                    }
//                    else {
                        ctx.quadraticCurveTo(points[i].x, points[i].y, c, d);
//                    }
                }
//                if (!v) {
                    ctx.quadraticCurveTo(points[i].x, points[i].y, points[i + 1].x, points[i + 1].y), ctx.stroke();
//                }
            }

            // Creates an object with x and y defined,
            // set to the mouse position relative to the state's canvas
            // If you wanna be super-correct this can be tricky,
            // we have to worry about padding and borders
            // takes an event and a reference to the canvas
            function getMouse(e, canvas) {
                var element = canvas, offsetX = 0, offsetY = 0, mx, my;

                // Compute the total offset. It's possible to cache this if you want
                if (element.offsetParent !== undefined) {
                    do {
                        offsetX += element.offsetLeft;
                        offsetY += element.offsetTop;
                    } while ((element == element.offsetParent));
                }

                mx = e.pageX - offsetX;
                my = e.pageY - offsetY;

                ex = mx;
                ey = my;

                var tr;
                if (v) {
                    tr = lWidthE + 250;
                } else {
                    tr = lWidthM + 250;
                }
                if (mx < small_x || small_x === 0) {
                    small_x = mx - tr;
                    if (small_x < 0) {
                        small_x = 0;
                    }
                }
                if (mx > big_x || big_x === 0) {
                    big_x = mx + tr;
                    if (big_x > 1000) {
                        big_x = 1000;
                    }
                }
                if (my < small_y || small_y === 0) {
                    small_y = my - tr;
                    if (small_y < 0) {
                        small_y = 0;
                    }
                }
                if (my > big_y || big_y === 0) {
                    big_y = my + tr;
                    if (big_y > 2400) {
                        big_y = 2400;
                    }
                }

                // We return a simple javascript object with x and y defined
                return {x: mx, y: my};
            }

            var v = false;

            function erase() {
                if (v) {
                    v = false;
                }
                else {
                    v = true;
                }
            }
        </script>
    </head>
    <body onload="init();">
        <div class="canvasBackground"></div>
        <div class="canvasBackground"></div>
    <canvas id='canvas' width='1000' height='2400'></canvas>
    <div id="main">
        <p>
            <label for="amountM">Marker size:</label>
            <input type="text" id="amountM" style="border: 0; color: #f6931f; font-weight: bold;"/>
        </p>
        <div title="Slide the bar to change size of marker" id="slider-range-minM"></div>
        <p>
            <label for="amountE">Eraser size:</label>
            <input type="text" id="amountE" style="border: 0; color: #f6931f; font-weight: bold;"/>
        </p>
        <div title="Slide the bar to change size of eraser" id="slider-range-minE"></div>
        <br/>
        <button title="Clear the canvas area." onclick='clear123();'>Clear</button>
        <input type="button" id="btnErase" title="Click to change between eraser and marker." onclick='erase();' value="Eraser/Marker"/>
        <img class="icon" src="icons/undo-icon.png" alt="Undo." title="Undo" onclick="javascript:undo();">
        <img class="icon" src="icons/redo-icon.png" alt="Redo." title="Redo" onclick="javascript:redo();">
    </div>
</body>
</html>
4

1 に答える 1

10

これは、globalCompositeOperation=”destination-out” を使用して消しゴムを作成する図です。

この合成は、消しゴムが上に描画する以前のピクセルを「消去」します。

ヒント: スケッチした線の「切り取り」を残さないように、消しゴムを円として描くと役立ちます。

これは、スケッチされた線と消去の両方を示す mousemove 関数です。

スケッチの処理 (ストロークの記録) が異なるように見えますが、これは宛先出力合成を消しゴムとして使用する方法を示しています。

    function handleMouseMove(e){
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);

      // Put your mousemove stuff here
      if(isMouseDown){
          ctx.beginPath();
          if(mode=="pen"){
              ctx.globalCompositeOperation="source-over";
              ctx.moveTo(lastX,lastY);
              ctx.lineTo(mouseX,mouseY);
              ctx.stroke();     
          }else{
              ctx.globalCompositeOperation="destination-out";
              ctx.arc(lastX,lastY,5,0,Math.PI*2,false);
              ctx.fill();
          }
          lastX=mouseX;
          lastY=mouseY;
      }
    }

ここにコードとフィドルがあります: http://jsfiddle.net/m1erickson/uSMxU/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<!--[if lt IE 9]><script type="text/javascript" src="../excanvas.js"></script><![endif]-->

<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>

<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    var lastX;
    var lastY;
    var strokeColor="red";
    var strokeWidth=2;
    var mouseX;
    var mouseY;
    var canvasOffset=$("#canvas").offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;
    var isMouseDown=false;


    function handleMouseDown(e){
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);

      // Put your mousedown stuff here
      lastX=mouseX;
      lastY=mouseY;
      isMouseDown=true;
    }

    function handleMouseUp(e){
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);

      // Put your mouseup stuff here
      isMouseDown=false;
    }

    function handleMouseOut(e){
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);

      // Put your mouseOut stuff here
      isMouseDown=false;
    }

    function handleMouseMove(e){
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);

      // Put your mousemove stuff here
      if(isMouseDown){
          ctx.beginPath();
          if(mode=="pen"){
              ctx.globalCompositeOperation="source-over";
              ctx.moveTo(lastX,lastY);
              ctx.lineTo(mouseX,mouseY);
              ctx.stroke();     
          }else{
              ctx.globalCompositeOperation="destination-out";
              ctx.arc(lastX,lastY,5,0,Math.PI*2,false);
              ctx.fill();
          }
          lastX=mouseX;
          lastY=mouseY;
      }
    }

    $("#canvas").mousedown(function(e){handleMouseDown(e);});
    $("#canvas").mousemove(function(e){handleMouseMove(e);});
    $("#canvas").mouseup(function(e){handleMouseUp(e);});
    $("#canvas").mouseout(function(e){handleMouseOut(e);});

    var mode="pen";
    $("#pen").click(function(){ mode="pen"; });
    $("#eraser").click(function(){ mode="eraser"; });

}); // end $(function(){});
</script>

</head>

<body>
    <canvas id="canvas" width=300 height=300></canvas></br>
    <button id="pen">Pen</button>
    <button id="eraser">Eraser</button>
</body>
</html>
于 2013-04-29T04:48:56.780 に答える