Vue Select Elements
Select elements with mouse over
by WILLIAM CORREA
HTML
<div id="app">
<div
ref="canvas"
id="canvas"
@mousedown="onMouseDown"
@mousemove="onMouseMove"
@mouseup="onMouseUp"
>
<div
ref="selector"
id="selector"
:style="style"
hidden
></div>
<div
v-for="button in buttons"
class="container"
:ref="button.ref"
:class="{'selected': button.selected}"
>
<button>{{ button.label }}</button>
</div>
</div>
<pre>{{ selected }}</pre>
</div>
CSS
#canvas {
padding: 20px;
display: flex;
flex-wrap: wrap;
user-select: none;
justify-content: space-between;
align-items: center;
height: 200px;
overflow: auto;
border: 1px solid #ddd;
}
.container {
margin: 5px;
flex: 1;
}
.container > * {
display: block;
width: 100%;
height: 100%;
}
.container.selected > * {
box-shadow: 0 0 5px 1px rgba(0, 0, 0, .7);
}
#selector {
border-radius: 2px;
border: 1px dotted #000;
position: fixed;
background: rgba(100, 100, 100, .25);
}
JavaScript
new Vue({
el: '#app',
data: () => ({
selector: {
top: 0,
left: 0,
width: 0,
height: 0,
},
style: {
left: '',
top: '',
width: '',
height: '',
},
tolerance: {
top: 10,
left: 10,
height: 10,
width: 10
},
buttons: Array.from({
length: 100
}).map((item, index) => ({
label: `Button ${index}`,
ref: `ref-${index}`,
selected: false
}))
}),
computed: {
selected () {
return this.buttons.filter(button => button.selected).map(button => button.ref)
}
},
methods: {
onMouseDown($event) {
this.$refs.selector.hidden = 0
this.selector.top = $event.clientX
this.selector.left = $event.clientY
this.draw()
},
onMouseMove($event) {
this.selector.width = $event.clientX
this.selector.height = $event.clientY
this.draw()
},
onMouseUp($event) {
const rectangle = element => {
return {
top: element.offsetTop,
left: element.offsetLeft,
width: element.offsetWidth,
height: element.offsetHeight
}
}
const area = rectangle(this.$refs.selector)
this.$refs.selector.hidden = 1
this.buttons.forEach(button => {
button.selected = this.areaHasContainer(area, rectangle(this.$refs[button.ref][0]))
})
},
draw() {
const a = Math.min(this.selector.top, this.selector.width);
const b = Math.max(this.selector.top, this.selector.width);
const c = Math.min(this.selector.left, this.selector.height);
const d = Math.max(this.selector.left, this.selector.height);
this.style.left = a + 'px';
this.style.top = c + 'px';
this.style.width = b - a + 'px';
this.style.height = d - c + 'px';
},
areaHasContainer(area, container) {
const top = this.$refs.canvas.scrollTop
...