Khyana
Khyana

Reputation: 195

Display and Draw in html5 canvas

I've been trying to display shapes (coordinates are generated in js) and can draw freely in my canvas.

If I tried joining to use the same canvas to be displayed, big mess happens:

here's my code:

function display() {
 var canvas = document.getElementById('displaycake_sketch');
 context = canvas.getContext('2d');
 context.clearRect(0, 0, canvas.width, canvas.height);

    if(document.getElementById('color1').checked){
      context.strokeStyle="#FF0000";
    } else if(document.getElementById('color2').checked){
      context.strokeStyle="#0000FF";
    }
    if (document.getElementById('shape1').checked) {
           
           context.arc(95,50,40,0,2*Math.PI);
           
           context.stroke();
                }

    if (document.getElementById('shape2').checked) {
            
            context.rect(50, 27, 50, 100);
            
            context.stroke();
                }
   }


    $(function () {
        $('#displaycake_sketch').sketch();
        $(".tools a").eq(0).attr("style", "color:#fba557");
        $(".tools a").click(function () {
            $(".tools a").removeAttr("style");
            $(this).attr("style", "color:#000");
        });
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<script src="http://intridea.github.io/sketch.js/lib/sketch.js"></script>

   
<canvas id="displaycake_sketch"></canvas>
<div> <input type="radio" id="shape1" name="shape_design" value="CIRCLE" onchange="display()"/> O 
<input type="radio" id="shape2" name="shape_design" value="RECTANGLE" onchange="display()"/> [] </div>

<div> <input type="radio" id="color1" name="color_design" value="RED" onchange="display()"/> RED  
<input type="radio" id="color2" name="color_design" value="BLUE" onchange="display()"/> BLUE </div>

<div class="tools"> 
<a href="#displaycake_sketch" class="btn btn-primary" data-tool="marker"> Marker</a> 
<a href="#displaycake_sketch" class="btn btn-primary" data-tool="eraser"> Eraser</a>

</div>

As you can see, whenever I tried to draw, the shapes disappears. and when I choose again some in my options, the lines will be disappear.. My eraser is working only for the marker.

And when I tried using different canvas, you can't draw freely but only the shapes can be displayed (I used position:absolute; to stay the same place)

Hope somebody can help, thank you so much!!

Upvotes: 2

Views: 391

Answers (1)

nfarahani
nfarahani

Reputation: 26

Look at:

https://intridea.github.io/sketch.js/lib/sketch.js

It's not a random 3-5 seconds, but some event is firing as a result of your interaction with the canvas element:

  this.canvas.bind('click mousedown mouseup mousemove mouseleave mouseout touchstart touchmove touchend touchcancel', this.onEvent);

You'll need to hijack the redraw method and chain your own code to it, for example, one quick and dirty option is to:

$(function() {
  var drawObject = $('#displaycake_sketch').sketch();
  var oldRedraw = drawObject.data('sketch').redraw;
  drawObject.data('sketch').redraw = function () {
    oldRedraw.call(this);
    display();
  }
  $(".tools a").eq(0).attr("style", "color:#fba557");
  $(".tools a").click(function() {
    $(".tools a").removeAttr("style");
    $(this).attr("style", "color:#000");
  });
});

You also want to do a context.beginPath(); when doing your display function, so that the doodled path ends and a new shape starts. (And not clear the canvas so the doodled path stays).

Final code is:

  function display() {
    var canvas = document.getElementById('displaycake_sketch');
    context = canvas.getContext('2d');
    //context.clearRect(0, 0, canvas.width, canvas.height);
    context.beginPath();

    if (document.getElementById('color1').checked) {
      context.strokeStyle = "#FF0000";
    } else if (document.getElementById('color2').checked) {
      context.strokeStyle = "#0000FF";
    }
    if (document.getElementById('shape1').checked) {

      context.arc(95, 50, 40, 0, 2 * Math.PI);

      context.stroke();
    }

    if (document.getElementById('shape2').checked) {

      context.rect(50, 27, 50, 100);

      context.stroke();
    }
  }


  $(function() {
    var drawObject = $('#displaycake_sketch').sketch();
    var oldRedraw = drawObject.data('sketch').redraw;
    window.redraw = drawObject.data('sketch').redraw = function() {
      oldRedraw.call(this);
      display();
    }
    window.redraw = function () {
      drawObject.data('sketch').redraw();
    }
    $(".tools a").eq(0).attr("style", "color:#fba557");
    $(".tools a").click(function() {
      $(".tools a").removeAttr("style");
      $(this).attr("style", "color:#000");
    });
  });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<script src="http://intridea.github.io/sketch.js/lib/sketch.js"></script>

   
<canvas id="displaycake_sketch"></canvas>
<div> <input type="radio" id="shape1" name="shape_design" value="CIRCLE" onchange="redraw()"/> O 
<input type="radio" id="shape2" name="shape_design" value="RECTANGLE" onchange="redraw()"/> [] </div>

<div> <input type="radio" id="color1" name="color_design" value="RED" onchange="display()"/> RED  
<input type="radio" id="color2" name="color_design" value="BLUE" onchange="display()"/> BLUE </div>

<div class="tools"> 
<a href="#displaycake_sketch" class="btn btn-primary" data-tool="marker"> Marker</a> 
<a href="#displaycake_sketch" class="btn btn-primary" data-tool="eraser"> Eraser</a>

</div>

UPDATE to show circle or square when clicking radio buttons The existing "display" function doesn't clear the canvas (or redraw the sketched path). To ensure a redraw, where the old radio selection is erased and only the new radio selection is drawn, we need to call the sketch-redraw function then our "display" fn. A quick and dirty way is to wrap the sketch fn, which has sketch and display both being called, into a global function the onclick radio button event can call. Code updated above.

Regarding close path, this is a good overview: Do I have to have the content.beginPath() and content.closePath()?

Upvotes: 1

Related Questions