Vue

by Vladimir

HTML

<div id="app">
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="500px" height="400px" @mousedown="startDrag" @mouseup="endDrag" @mousemove="mouseMove">
    <rect x=0 y=0 width="500px" height="400px" fill="gray" />
    <g>
      <g v-for="(obj, ind) in objects" @mousedown="selectObject(ind)" :key="ind">
        <rect :stroke="selectedIndex === ind ? 'white' : ''" :x="obj.x" :y="obj.y" :width="obj.width" :height="obj.height" :fill="obj.fill" />
      </g>
    </g>
  </svg>
</div>

Vue

function random(min,max) {
    return Math.floor(Math.random()*(max-min+1)+min);
}
function randColor() { return "#"+((1<<24)*Math.random()|0).toString(16) };

const COUNT_OBJECTS = 1000;

let objects = [...new Array(COUNT_OBJECTS)].map(x => ({ x: random(0, 400), y: random(0, 400), width: random(2, 50), height: random(20, 50), fill: randColor() }));


new Vue({
  el: "#app",
  data: {
    objects: objects,
    selectedIndex: -1
  },
  methods: {
  	selectObject: function(ind) {
    	this.selectedIndex = ind;
    },
    startDrag: function() {
    	this.isDragging = true;
    },
    endDrag: function() {
    	this.isDragging = false;
    },
    moveObject: function(ind, addX, addY) {
    	let obj = this.objects[this.selectedIndex];
      obj.x += addX;
      obj.y += addY;
      Vue.set(this.objects, ind, obj);
    },
    mouseMove: function(e) {
    	if (this.isDragging) {
        let diffX = e.clientX - this.mouseX;
        let diffY = e.clientY - this.mouseY;
        if (this.selectedIndex >= 0) {
          this.moveObject(this.selectedIndex, diffX, diffY);
        }
      }
    	this.mouseX = e.clientX;
      this.mouseY = e.clientY;
    }
  }
})