Search code examples
javascriptjquerykineticjs

JavaScript stroke fill on click


I'm trying to to make it possible for an image on a canvas to have a box over it with low opacity, to make it be shown that it has been selected. So I need an onclick function, but i'm stuck on what to do. Any advice? I would aslo appreciate if someone could point me in the right direction on how to make the box also pulsate.

                var image1 = new Kinetic.Image({
                    image: imageObj,
                    x: xposition,
                    y: yposition,
                    width: width,
                    height: height,
                    stroke: 'blue',
                    srokeFill: 'red',
                    strokeWidth: 5,
                    draggable: true,
                    dragBoundFunc: function (pos) {
                       if (pos.x < this.minX)
                            this.minX = pos.x;
                        return {
                            x: pos.x,
                            y: this.getAbsolutePosition().y                                 
                        }
                    }


                });

                layer.on('mouseover', function (evt) {
                    var shape = evt.target;
                    document.body.style.cursor = 'pointer';
                    shape.strokeEnabled(true);
                    layer.draw();
                });

                layer.on('mouseout', function (evt) {
                    var shape = evt.target;
                    document.body.style.cursor = 'default';
                    shape.strokeEnabled(false);
                    layer.draw();

                });

Solution

  • When making a clickable region on a canvas you need to.

    - Create a redraw function.
    - Find the mouse point inside of canvas.
    - Do collision detection on the mouse point and region.
    

    update: added multiple clickable regions.

    // x1, y1, x2, y2, clicked
    var boxes = [{
      x1: 10,
      y1: 10,
      x2: 110,
      y2: 110,
      clicked: false
    }, {
      x1: 120,
      y1: 10,
      x2: 220,
      y2: 110,
      clicked: false
    }];
    
    function go() {
      var can = document.getElementById('can');
      var ctx = can.getContext('2d');
      var w = can.width;
      var h = can.height;
    
      makeNoise(ctx);
    
      var imageData = ctx.getImageData(0, 0, w, h);
      var mx = 0;
      var my = 0;
    
      $('#can').mousemove(function(event) {
        var offset = $(this).offset();
        mx = event.pageX - offset.left;
        my = event.pageY - offset.top;
        redraw();
      });
    
      $('#can').click(function(event) {
        var offset = $(this).offset();
        mx = event.pageX - offset.left;
        my = event.pageY - offset.top;
    
        for (var i = 0, len = boxes.length; i < len; i++) {
          var b = boxes[i];
          if (hit(b.x1, b.y1, b.x2, b.y2)) {
            b.clicked = !b.clicked;
          }
        }
    
        redraw();
      });
    
      function redraw() {
        // Draw the original image
        ctx.putImageData(imageData, 0, 0);
        // Draw the clickable region
    
        for (var i = 0, len = boxes.length; i < len; i++) {
          drawBox(boxes[i]);
        }
        // Draw the mouse. Probably only needed when testing
        // mouse location.
        drawMouse();
      }
    
      redraw();
    
      // Collision dection of a square against mouse point.
      // square points x1,y1 must be less than x2,y2
      function hit(x1, y1, x2, y2) {
        if (mx < x1 || my < y1 || mx > x2 || my > y2) return false;
        return true;
      }
    
      function drawMouse() {
        ctx.moveTo(mx, my);
        ctx.fillStyle = "yellow";
        ctx.beginPath();
        ctx.arc(mx, my, 5, 0, Math.PI * 360);
        ctx.fill();
      }
    
      function drawBox(b) {
    
        if (b.clicked) {
          // Mouse clicked.
          ctx.fillStyle = "rgba(255,0,255,.5)"
        } else if (hit(b.x1, b.y1, b.x2, b.y2)) {
          // Mouse Over
          ctx.fillStyle = "rgba(255,255,255,.5)"
        } else {
          // Mouse Out
          ctx.fillStyle = "red";
        }
    
        ctx.fillRect(b.x1, b.y1, b.x2 - b.x1, b.y2 - b.y1);
    
      }
    }
    
    // Fill a canvas context with noise.
    function makeNoise(ctx) {
      var can = ctx.canvas;
      var imageData = ctx.getImageData(0, 0, can.width, can.height);
      var d = imageData.data;
      for (var i = 0, len = d.length; i < len; i += 4) {
        d[i] = d[i + 1] = d[i + 2] = (Math.random() * 8) << 4;
        d[i + 3] = 255;
      }
      ctx.putImageData(imageData, 0, 0);
    }
    
    go();
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <canvas id="can" width="400" height="300"></canvas>