Utku Demir
Utku Demir

Reputation: 423

How to draw a rectangle manually in html without canvas?

What I mean is understood better in this photo

In the given photo, I used canvas for drawings; however, I would like to do it by an another way because I want to created rectangles be draggable and give ids to created rectangles. For example, If I used div instead of canvas, I could not manually draw the rectangles like in the photo. Maybe, there is a way but I don't know it. When I searched this subject, most of the people use paper.js, etc. but it is just useful in resize or drag&drop; therefore, I did not want to use these.

function lettersOnly(input) {
  var regex = /[^a-z]/gi;
  input.value = input.value.replace(regex, "");
}

jQuery(document).ready(function($) {

  //Canvas
  var canvas = document.getElementById('canvas');
  var ctx = canvas.getContext('2d');

  //Variables
  var canvasOffset = $("#canvas").offset();
  var canvasx = canvasOffset.left;
  var canvasy = canvasOffset.top;
  var last_mousex = 0;
  var last_mousey = 0;
  var mousex = 0;
  var mousey = 0;
  var mousedown = false;
  var shapes = [];
  var width;
  var height;
  // make var col a global variable
  var col = "black";
  var ad = "";

  //Mousedown
  $(canvas).on('mousedown', function(e) {
    last_mousex = parseInt(e.clientX - canvasx);
    last_mousey = parseInt(e.clientY - canvasy);
    mousedown = true;
  });

  //Mouseup
  $(canvas).on('mouseup', function(e) {
    const lastPos = {
      lastMouseX: last_mousex,
      lastMouseY: last_mousey,
      rectWidth: width,
      rectHeight: height,
      // save the color of the rect
      color: col,
      name: ad
    };
    shapes.push(lastPos);
    mousedown = false;
  });

  //Mousemove
  $(canvas).on('mousemove', function(e) {
    mousex = parseInt(e.clientX - canvasx);
    mousey = parseInt(e.clientY - canvasy);

    if (mousedown) {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      width = mousex - last_mousex;
      height = mousey - last_mousey;
      col = $("#color").val();
      ad = $("#name").val();
      if (shapes.length > 0) {
        for (var i in shapes) {
          // for every shape in the shapes array beginPath
          ctx.beginPath();
          //set the color of the stroke
          ctx.strokeStyle = shapes[i].color;
          //draw the rect
          ctx.rect(shapes[i].lastMouseX, shapes[i].lastMouseY, shapes[i].rectWidth, shapes[i].rectHeight);
          ctx.fillText(shapes[i].name, shapes[i].rectWidth - shapes[i].lastMouseX, shapes[i].rectHeight - shapes[i].lastMouseY);
          ctx.stroke();

        }
      }
      //for the new rect beginPath
      ctx.beginPath();
      ctx.rect(last_mousex, last_mousey, width, height);
      ctx.strokeStyle = col;
      ctx.lineWidth = 3;
      ctx.fillText(ad, 100, 100);
      ctx.stroke();

    }
    $('#output').html('Current Coordinate: ' + mousex + ', ' + mousey + '<br/>Last Coordinate: ' + last_mousex + ', ' + last_mousey);

  });
});
.topnav {
  background-color: #333;
  overflow: hidden;
}


/* Style the links inside the navigation bar */

.topnav a {
  float: left;
  color: #f2f2f2;
  text-align: center;
  padding: 14px 16px;
  text-decoration: none;
  font-size: 14px;
}


/* Change the color of links on hover */

.topnav a:hover {
  background-color: #ddd;
  color: black;
}


/* Add a color to the active/current link */

.topnav a.active {
  background-color: #4CAF50;
  color: white;
}

#color {
  border: 1px solid black;
  font-family: 'Times New Roman', Times, serif;
  font-size: 14px;
  margin: auto;
  padding: 0;
  position: absolute;
  top: 0;
  left: 45%;
  right: 0;
  text-align: center;
}

#name {
  border: 1px solid black;
  font-family: 'Times New Roman', Times, serif;
  font-size: 14px;
  margin: auto;
  padding: 0;
  position: absolute;
  top: 0;
  left: 45%;
  right: 0;
  text-align: center;
}

.submit {
  border: 1px solid black;
  margin: auto;
  padding: 0;
  width: 70px;
  height: 30px;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  font-family: 'Times New Roman', Times, serif;
  font-size: 14px;
  text-align: center;
}

#canvas {
  cursor: crosshair;
  background-image: url("kroki2v3.png");
  background-repeat: no-repeat;
  background-size: contain;
  padding: 0;
  margin-left: 210;
  margin-top: 160;
  position: static;
  display: block;
}

#output {
  font-family: 'Times New Roman', Times, serif;
  font-size: 14px;
  top: 19%;
  left: 46%;
  position: absolute;
}
<html>

<head>
  <meta charset="utf-8" />
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>

<body>
  <div>
    <table>
      <tr>
        <td><input type="text" id="color" style="margin-top: 70px" placeholder="Color" onkeyup="lettersOnly(this)" /></td>
        <td><input type="text" id="name" style="margin-top: 100px;" placeholder="Department Name" onkeyup="lettersOnly(this)" /></td>
        <td><input type="submit" class="submit" value="Submit" style="margin-top: 130px;" /></td>
      </tr>
    </table>
  </div>
  <div class="topnav">
    <a class="active" href="">Project</a>
    <a href="https://pavotek.com.tr/iletisim/">Contact</a>
    <a href="https://pavotek.com.tr/biz_kimiz/">About</a>
  </div>

  <div id="container" style="display: none;"><img src="kroki2v3.png" id="img01" alt="" style="display: none;"></div>
  <canvas id="canvas" width="1200" height="520"></canvas>
  <div id="output"></div>

</body>

</html>

Upvotes: 3

Views: 4806

Answers (1)

Souleste
Souleste

Reputation: 1984

Something like this? When you say "draw", this is what I imagined.

You need to find the mouse position in the mousedown function and in the mousemove function, then subtract the mousedown x and y position from the mousemove x and y position to set the width and height.

You also need to set a variable to tell whether or not the mouse is actually down while moving the mouse to ensure a div isn't "drawn" without knowledge.

Once you "mouseup" you can set your draggable / resizable functions to be used.

Here is a fiddle;

$(function() {
  var widget;
  var x;
  var y;
  var finX;
  var finY;
  var ismousedown = false;
  $(document).on({
    mousedown: function(event) {
      if ($(event.target).attr('class') == 'wrapper') {
        x = event.pageX;
        y = event.pageY;
        $('body').append('<div class="widget" style="top:' + y + 'px; left: ' + x + 'px;"></div>');
        widget = $('.widget').last();
        ismousedown = true;
      }
    },
    mousemove: function(event) {
      if (ismousedown == true) {
        finX = event.pageX;
        finY = event.pageY;
        widget.width(finX - x);
        widget.height(finY - y);
        widget.css({
          'width': (finX - x) + '!important',
          'height': (finY - y) + '!important',
          'display': 'block',
          'border': '2px dashed #ccc'
        });
      }
    },
    mouseup: function(event) {
      ismousedown = false;
      widget.css({
        'background': '#222',
        'border': '0',
        'cursor': 'move'
      });
      initDraggable();
    }

  });

  // in case you need to reinitialize later.
  function initDraggable() {
    $('.widget').draggable({});
  }
});
html,
body {
  height: 100% !important;
  position: relative;
}

.wrapper {
  position: relative;
  height: 100% !important;
  width: 100% !important;
}

.widget {
  display: block;
  position: absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<div class="wrapper">

</div>

Upvotes: 6

Related Questions