selector wip

This commit is contained in:
barsdeveloper
2021-09-09 18:06:49 +02:00
parent 6b8b52ff37
commit ccaad9b677
6 changed files with 202 additions and 61 deletions

View File

@@ -14,11 +14,26 @@
url('../font/roboto-regular.woff') format('woff');
}
:root {
--ueb-fron-size : 13px;
--ueb-viewport-height : 30rem;
--ueb-viewport-width : 100%;
--ueb-grid-size : 16px;
--ueb-grid-line-width : 2px;
--ueb-grid-line-color : #353535;
--ueb-grid-set : 8;
--ueb-grid-set-line-color : #161616;
--ueb-grid-axis-line-color: black;
--ueb-grid-snap : 16px;
--ueb-node-radius : 7px;
}
u-blueprint {
display : block;
position : relative;
font-family: Roboto, Noto, Oxygen, Ubuntu, 'Open Sans', 'Helvetica Neue', sans-serif;
font-size : var(--ueb-fron-size);
user-select: none;
}
.ueb-viewport-header {
@@ -280,5 +295,44 @@ u-blueprint {
left : min(var(--ueb-select-from-x) * 1px, var(--ueb-select-to-x) * 1px);
width : calc(max(var(--ueb-select-from-x) - var(--ueb-select-to-x), var(--ueb-select-to-x) - var(--ueb-select-from-x)) * 1px);
height : calc(max(var(--ueb-select-from-y) - var(--ueb-select-to-y), var(--ueb-select-to-y) - var(--ueb-select-from-y)) * 1px);
border : 2px dashed gray;
background-image:
/* Top */
repeating-linear-gradient(90deg, transparent, transparent 1px, white 2px, white 7px, transparent 7px, transparent 11px),
repeating-linear-gradient(90deg, black, black 8px, transparent 9px, transparent 11px),
/* Bottom */
repeating-linear-gradient(90deg, transparent, transparent 1px, white 2px, white 7px, transparent 7px, transparent 11px),
repeating-linear-gradient(90deg, black, black 8px, transparent 9px, transparent 11px),
/* Left */
repeating-linear-gradient(180deg, transparent, transparent 1px, white 1px, white 7px, transparent 7px, transparent 11px),
repeating-linear-gradient(180deg, black, black 8px, transparent 9px, transparent 11px),
/* Right */
repeating-linear-gradient(0deg, transparent, transparent 1px, white 2px, white 7px, transparent 7px, transparent 11px),
repeating-linear-gradient(0deg, black, black 8px, transparent 9px, transparent 11px);
background-size:
/* Top */
100% 1px,
100% 3px,
/* Bottom */
100% 1px,
100% 3px,
/* Left */
1px 100%,
3px 100%,
/* Right */
1px 100%,
3px 100%;
background-position:
/* Top */
0 1px,
0 0,
/* Bottom */
0 calc(100% - 1px),
0 100%,
/* Left */
1px 0,
0 0,
/* Right */
calc(100% - 1px) 0,
100% 0;
background-repeat: no-repeat;
}

View File

@@ -49,12 +49,14 @@ export default class UEBlueprint extends HTMLElement {
constructor() {
super()
/** @type {Set<import("./UEBlueprintObject.js").default>}" */
this.nodes = new Set()
this.expandGridSize = 400
this.gridElement = null
this.viewportElement = null
this.overlayElement = null
this.selectorElement = null
this.selectorObserver = null
this.dragObject = null
this.selectObject = null
this.additional = /*[2 * this.expandGridSize, 2 * this.expandGridSize]*/[0, 0]
@@ -102,6 +104,10 @@ export default class UEBlueprint extends HTMLElement {
this.selectObject.unlistenDOMElement()
}
getScroll() {
return [this.viewportElement.scrollLeft, this.viewportElement.scrollTop]
}
setScroll(value, smooth = false) {
this.scroll = value
if (!smooth) {
@@ -151,10 +157,6 @@ export default class UEBlueprint extends HTMLElement {
this.setScroll(finalScroll, smooth)
}
getScroll() {
return [this.viewportElement.scrollLeft, this.viewportElement.scrollTop]
}
scrollCenter() {
const scroll = this.getScroll()
const offset = [
@@ -278,26 +280,56 @@ export default class UEBlueprint extends HTMLElement {
return parseFloat(getComputedStyle(this.gridElement).getPropertyValue('--ueb-grid-scale'))
}
startSelecting(x, y) {
compensateTranslation(position) {
position[0] -= this.translateValue[0]
position[1] -= this.translateValue[1]
return position
}
/**
* Create a selection rectangle starting from the specified position
* @param {number[]} initialPosition - Selection rectangle initial position (relative to the .ueb-grid element)
*/
startSelecting(initialPosition) {
if (this.selectorElement) {
this.finishSelecting()
}
initialPosition = this.compensateTranslation(initialPosition)
this.selectorElement = this.constructor.getElement(this.selectorTemplate())
this.querySelector('[data-nodes]').appendChild(this.selectorElement)
this.selectorElement.style.setProperty('--ueb-select-from-x', x)
this.selectorElement.style.setProperty('--ueb-select-from-y', y)
this.selectorElement.style.setProperty('--ueb-select-from-x', initialPosition[0])
this.selectorElement.style.setProperty('--ueb-select-from-y', initialPosition[1])
this.selectorObserver = new IntersectionObserver(
(entries, observer) => {
entries.map(entry => {
/** @type {import("./UEBlueprintObject.js").default;}" */
let target = entry.target
target.setSelected(entry.isIntersecting)
})
}, {
threshold: [0.01],
root: this.selectorElement
})
this.nodes.forEach(element => this.selectorObserver.observe(element))
}
finishSelecting() {
if (this.selectorElement) {
this.selectorElement.remove()
this.selectorElement = null
this.selectorObserver.disconnect()
this.selectorObserver = null
}
}
doSelecting(x, y) {
this.selectorElement.style.setProperty('--ueb-select-to-x', x)
this.selectorElement.style.setProperty('--ueb-select-to-y', y)
/**
* Move selection rectagle to the specified final position. The initial position was specified by startSelecting()
* @param {number[]} finalPosition - Selection rectangle final position (relative to the .ueb-grid element)
*/
doSelecting(finalPosition) {
finalPosition = this.compensateTranslation(finalPosition)
this.selectorElement.style.setProperty('--ueb-select-to-x', finalPosition[0])
this.selectorElement.style.setProperty('--ueb-select-to-y', finalPosition[1])
}
addNode(...blueprintNodes) {

View File

@@ -4,7 +4,8 @@ export default class UEBlueprintDragScroll extends UEBlueprintDrag {
constructor(scrolledEntity, options) {
super(scrolledEntity, options)
this.minZoom = options?.minZoom ?? -12
let self = this;
let self = this
this.mouseMoveHandler = function (e) {
let mousePosition = self.snapToGrid(e.clientX, e.clientY)
@@ -16,7 +17,8 @@ export default class UEBlueprintDragScroll extends UEBlueprintDrag {
// Reassign the position of mouse
self.mousePosition = mousePosition
};
}
this.mouseWheelHandler = function (e) {
e.preventDefault()
let zoomLevel = self.blueprintNode.getZoom()
@@ -24,10 +26,13 @@ export default class UEBlueprintDragScroll extends UEBlueprintDrag {
let scaleCorrection = 1 / self.blueprintNode.getScale()
const targetOffset = e.target.getBoundingClientRect()
const currentTargetOffset = e.currentTarget.getBoundingClientRect()
let offset = [e.offsetX + targetOffset.x * scaleCorrection - currentTargetOffset.x * scaleCorrection, e.offsetY + targetOffset.y * scaleCorrection - currentTargetOffset.y * scaleCorrection]
let offset = [
e.offsetX + targetOffset.x * scaleCorrection - currentTargetOffset.x * scaleCorrection,
e.offsetY + targetOffset.y * scaleCorrection - currentTargetOffset.y * scaleCorrection
]
self.blueprintNode.setZoom(zoomLevel, offset)
}
this.blueprintNode.getGridDOMElement().addEventListener('wheel', this.mouseWheelHandler, false)
this.blueprintNode.getGridDOMElement().parentElement.addEventListener('wheel', e => e.preventDefault())
}

View File

@@ -1,14 +1,16 @@
export default class UEBlueprintSelect {
constructor(blueprintNode, options) {
/** @type {import("./UEBlueprint.js").default;}" */
this.blueprintNode = blueprintNode;
this.mousePosition = [0, 0];
this.clickButton = options?.clickButton ?? 0
this.exitSelectAnyButton = options?.exitSelectAnyButton ?? true
let self = this;
let self = this
this.mouseDownHandler = function (e) {
switch (e.button) {
case self.clickButton:
self.clicked(e.clientX, e.clientY)
self.clicked([e.offsetX, e.offsetY])
break
default:
if (!self.exitSelectAnyButton) {
@@ -16,30 +18,42 @@ export default class UEBlueprintSelect {
}
break
}
};
this.mouseMoveHandler = function (e) {
self.blueprintNode.doSelecting(e.clientX, e.clientY)
}
this.mouseMoveHandler = function (e) {
e.preventDefault()
let scaleCorrection = 1 / self.blueprintNode.getScale()
const targetOffset = e.target.getBoundingClientRect()
const currentTargetOffset = e.currentTarget.getBoundingClientRect()
let offset = [
e.offsetX + targetOffset.x * scaleCorrection - currentTargetOffset.x * scaleCorrection,
e.offsetY + targetOffset.y * scaleCorrection - currentTargetOffset.y * scaleCorrection
]
self.blueprintNode.doSelecting(offset)
}
this.mouseUpHandler = function (e) {
if (!self.exitSelectAnyButton || e.button == self.clickButton) {
// Remove the handlers of `mousemove` and `mouseup`
document.removeEventListener('mousemove', self.mouseMoveHandler)
self.blueprintNode.getGridDOMElement().removeEventListener('mousemove', self.mouseMoveHandler)
document.removeEventListener('mouseup', self.mouseUpHandler)
}
}
this.blueprintNode.addEventListener('mousedown', this.mouseDownHandler)
this.blueprintNode.addEventListener('contextmenu', e => e.preventDefault())
let gridElement = this.blueprintNode.getGridDOMElement()
gridElement.addEventListener('mousedown', this.mouseDownHandler)
gridElement.addEventListener('contextmenu', e => e.preventDefault())
}
unlistenDOMElement() {
this.blueprintNode.removeEventListener('mousedown', this.mouseDownHandler)
}
clicked(x, y) {
clicked(position) {
// Attach the listeners to `document`
document.addEventListener('mousemove', this.mouseMoveHandler)
this.blueprintNode.getGridDOMElement().addEventListener('mousemove', this.mouseMoveHandler)
document.addEventListener('mouseup', this.mouseUpHandler)
// Start selecting
this.blueprintNode.startSelecting(x, y)
this.blueprintNode.startSelecting(position)
}
}

View File

@@ -6,21 +6,6 @@
<title></title>
<style>
body {
--ueb-fron-size: 13px;
--ueb-viewport-height: 30rem;
--ueb-viewport-width: 100%;
--ueb-grid-size: 16px;
--ueb-grid-line-width: 2px;
--ueb-grid-line-color: #353535;
--ueb-grid-set: 8;
--ueb-grid-set-line-color: #161616;
--ueb-grid-axis-line-color: black;
--ueb-grid-snap: 16px;
--ueb-grid-min-scale: 0.2;
--ueb-node-radius: 7px;
--ueb-grid-snap: 16px;
}
</style>
<link rel="stylesheet" href="css/ueblueprint-node-value-type-color.css">
<link rel="stylesheet" href="css/ueblueprint-style.css">

View File

@@ -70,6 +70,7 @@ class UEBlueprintDragScroll extends UEBlueprintDrag {
super(scrolledEntity, options);
this.minZoom = options?.minZoom ?? -12;
let self = this;
this.mouseMoveHandler = function (e) {
let mousePosition = self.snapToGrid(e.clientX, e.clientY);
@@ -82,6 +83,7 @@ class UEBlueprintDragScroll extends UEBlueprintDrag {
// Reassign the position of mouse
self.mousePosition = mousePosition;
};
this.mouseWheelHandler = function (e) {
e.preventDefault();
let zoomLevel = self.blueprintNode.getZoom();
@@ -89,10 +91,13 @@ class UEBlueprintDragScroll extends UEBlueprintDrag {
let scaleCorrection = 1 / self.blueprintNode.getScale();
const targetOffset = e.target.getBoundingClientRect();
const currentTargetOffset = e.currentTarget.getBoundingClientRect();
let offset = [e.offsetX + targetOffset.x * scaleCorrection - currentTargetOffset.x * scaleCorrection, e.offsetY + targetOffset.y * scaleCorrection - currentTargetOffset.y * scaleCorrection];
let offset = [
e.offsetX + targetOffset.x * scaleCorrection - currentTargetOffset.x * scaleCorrection,
e.offsetY + targetOffset.y * scaleCorrection - currentTargetOffset.y * scaleCorrection
];
self.blueprintNode.setZoom(zoomLevel, offset);
};
this.blueprintNode.getGridDOMElement().addEventListener('wheel', this.mouseWheelHandler, false);
this.blueprintNode.getGridDOMElement().parentElement.addEventListener('wheel', e => e.preventDefault());
}
@@ -101,15 +106,17 @@ class UEBlueprintDragScroll extends UEBlueprintDrag {
class UEBlueprintSelect {
constructor(blueprintNode, options) {
/** @type {import("./UEBlueprint.js").default;}" */
this.blueprintNode = blueprintNode;
this.mousePosition = [0, 0];
this.clickButton = options?.clickButton ?? 0;
this.exitSelectAnyButton = options?.exitSelectAnyButton ?? true;
let self = this;
this.mouseDownHandler = function (e) {
switch (e.button) {
case self.clickButton:
self.clicked(e.clientX, e.clientY);
self.clicked([e.offsetX, e.offsetY]);
break
default:
if (!self.exitSelectAnyButton) {
@@ -118,30 +125,42 @@ class UEBlueprintSelect {
break
}
};
this.mouseMoveHandler = function (e) {
self.blueprintNode.doSelecting(e.clientX, e.clientY);
e.preventDefault();
let scaleCorrection = 1 / self.blueprintNode.getScale();
const targetOffset = e.target.getBoundingClientRect();
const currentTargetOffset = e.currentTarget.getBoundingClientRect();
let offset = [
e.offsetX + targetOffset.x * scaleCorrection - currentTargetOffset.x * scaleCorrection,
e.offsetY + targetOffset.y * scaleCorrection - currentTargetOffset.y * scaleCorrection
];
self.blueprintNode.doSelecting(offset);
};
this.mouseUpHandler = function (e) {
if (!self.exitSelectAnyButton || e.button == self.clickButton) {
// Remove the handlers of `mousemove` and `mouseup`
document.removeEventListener('mousemove', self.mouseMoveHandler);
self.blueprintNode.getGridDOMElement().removeEventListener('mousemove', self.mouseMoveHandler);
document.removeEventListener('mouseup', self.mouseUpHandler);
}
};
this.blueprintNode.addEventListener('mousedown', this.mouseDownHandler);
this.blueprintNode.addEventListener('contextmenu', e => e.preventDefault());
let gridElement = this.blueprintNode.getGridDOMElement();
gridElement.addEventListener('mousedown', this.mouseDownHandler);
gridElement.addEventListener('contextmenu', e => e.preventDefault());
}
unlistenDOMElement() {
this.blueprintNode.removeEventListener('mousedown', this.mouseDownHandler);
}
clicked(x, y) {
clicked(position) {
// Attach the listeners to `document`
document.addEventListener('mousemove', this.mouseMoveHandler);
this.blueprintNode.getGridDOMElement().addEventListener('mousemove', this.mouseMoveHandler);
document.addEventListener('mouseup', this.mouseUpHandler);
// Start selecting
this.blueprintNode.startSelecting(x, y);
this.blueprintNode.startSelecting(position);
}
}
@@ -193,12 +212,14 @@ class UEBlueprint extends HTMLElement {
constructor() {
super();
/** @type {Set<import("./UEBlueprintObject.js").default>}" */
this.nodes = new Set();
this.expandGridSize = 400;
this.gridElement = null;
this.viewportElement = null;
this.overlayElement = null;
this.selectorElement = null;
this.selectorObserver = null;
this.dragObject = null;
this.selectObject = null;
this.additional = /*[2 * this.expandGridSize, 2 * this.expandGridSize]*/[0, 0];
@@ -246,6 +267,10 @@ class UEBlueprint extends HTMLElement {
this.selectObject.unlistenDOMElement();
}
getScroll() {
return [this.viewportElement.scrollLeft, this.viewportElement.scrollTop]
}
setScroll(value, smooth = false) {
this.scroll = value;
if (!smooth) {
@@ -295,10 +320,6 @@ class UEBlueprint extends HTMLElement {
this.setScroll(finalScroll, smooth);
}
getScroll() {
return [this.viewportElement.scrollLeft, this.viewportElement.scrollTop]
}
scrollCenter() {
const scroll = this.getScroll();
const offset = [
@@ -422,26 +443,56 @@ class UEBlueprint extends HTMLElement {
return parseFloat(getComputedStyle(this.gridElement).getPropertyValue('--ueb-grid-scale'))
}
startSelecting(x, y) {
compensateTranslation(position) {
position[0] -= this.translateValue[0];
position[1] -= this.translateValue[1];
return position
}
/**
* Create a selection rectangle starting from the specified position
* @param {number[]} initialPosition - Selection rectangle initial position (relative to the .ueb-grid element)
*/
startSelecting(initialPosition) {
if (this.selectorElement) {
this.finishSelecting();
}
initialPosition = this.compensateTranslation(initialPosition);
this.selectorElement = this.constructor.getElement(this.selectorTemplate());
this.querySelector('[data-nodes]').appendChild(this.selectorElement);
this.selectorElement.style.setProperty('--ueb-select-from-x', x);
this.selectorElement.style.setProperty('--ueb-select-from-y', y);
this.selectorElement.style.setProperty('--ueb-select-from-x', initialPosition[0]);
this.selectorElement.style.setProperty('--ueb-select-from-y', initialPosition[1]);
this.selectorObserver = new IntersectionObserver(
(entries, observer) => {
entries.map(entry => {
/** @type {import("./UEBlueprintObject.js").default;}" */
let target = entry.target;
target.setSelected(entry.isIntersecting);
});
}, {
threshold: [0.01],
root: this.selectorElement
});
this.nodes.forEach(element => this.selectorObserver.observe(element));
}
finishSelecting() {
if (this.selectorElement) {
this.selectorElement.remove();
this.selectorElement = null;
this.selectorObserver.disconnect();
this.selectorObserver = null;
}
}
doSelecting(x, y) {
this.selectorElement.style.setProperty('--ueb-select-to-x', x);
this.selectorElement.style.setProperty('--ueb-select-to-y', y);
/**
* Move selection rectagle to the specified final position. The initial position was specified by startSelecting()
* @param {number[]} finalPosition - Selection rectangle final position (relative to the .ueb-grid element)
*/
doSelecting(finalPosition) {
finalPosition = this.compensateTranslation(finalPosition);
this.selectorElement.style.setProperty('--ueb-select-to-x', finalPosition[0]);
this.selectorElement.style.setProperty('--ueb-select-to-y', finalPosition[1]);
}
addNode(...blueprintNodes) {