No More Blockly.js? Drag and Drop SVGs Pt. 1

The blockly.js library was a great starting point for the TidyBlocks project, but after working extensively with it there are some major limitiations [mainly the lack of accessbility to the source code and the inablity to use modern bundlers].

Thus begins a new project: creating a drag and drop block library of my own. Eventually, each block will have its own methods (making the blocks easier to work with, because blockly blocks return functions as strings.).

But first, I need to learn a whole lot about dragging and dropping!

You can drag the Purple circle into the green workspace, but once inside it cannot be dragged out.

Step 1: Move a single block inside the SVG area without any part of it going out.

This requires three SVGs: a container, a “workspace” and a "block we can drag into the workspace, but once dragged inside it cannot be dragged out.

  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" onload="makeDraggable(evt)">

    <!-- background bounding box -->
    <rect x="0" y="0" width="100%" height="20" fill="#FEDDB4" />

    <!-- drag area -->
    <rect id="workspace" class="workspace" x="10.5" y="2.2" width="19.5" height="17" fill="#B0DDD6" />

    <!-- class draggable == set cursor to move  -->
    <rect rx="15" ry="15" class="draggable" fill="#8E56A1" x="4" y="4" width="4" height="4" />

  </svg>

As you can see, we have three SVGs, and a function makeDraggable(evt). This function tracks when the user is dragging and dropping by tracking mousedown, mouseover, and mouseup events.

I’ve taken this function from the wonderful tutorial here, where the author very eloquently describes how to track SVG movement, adding one simple piece of logic to the dragEnd event:

  function endDrag(evt) {
    selectedElement = false;

    var r1 = evt.target.getBoundingClientRect();
    var r2 = document.getElementById('workspace').getBoundingClientRect()

    if (r2.left < r1.right )  {
      evt.target.classList.add('confine')
    }
    console.log("Blue Box class list: " + evt.target.classList)

  }

The selectedElement = false portion stops the user from dragging the selected SVG on mouseout and is included in the tutorial. What I’ve added is r1: the position of the SVG element and r2: the position of the workspace. If the workspace and the circle overlap, then we add the class confine to the circle (we use this class in the startDrag function, confining the drag to the specified bounding box.)

And that’s step 1!

You can find the source code here In step 2 I’ll add another circle, and change its color when it overlaps with circle 1.

Avatar
Maya Gans
Data Scientist

Maya’s work as a Master’s student was focused in quantitative biology. She loves coding and is extremely passionate about data science and data visualization.

Related