mirror of
https://github.com/barsdeveloper/ueblueprint.git
synced 2026-02-04 08:17:41 +08:00
Link implementation wip
This commit is contained in:
2
dist/css/ueblueprint-style.css
vendored
2
dist/css/ueblueprint-style.css
vendored
File diff suppressed because one or more lines are too long
2
dist/css/ueblueprint-style.css.map
vendored
2
dist/css/ueblueprint-style.css.map
vendored
@@ -1 +1 @@
|
||||
{"version":3,"sourceRoot":"","sources":["../../scss/ueblueprint-style.css"],"names":[],"mappings":"AAAA,WACI,qBACA,iBACA,IACI,kGAIR,WACI,qBACA,mBACA,IACI,sGAIR,MACI,sBACA,6BACA,2BACA,sBACA,2BACA,+BACA,kBACA,mCACA,kCACA,sBACA,uBAGJ,cACI,cACA,kBACA,8EACA,+BACA,iBAGJ,qBACI,aACA,kBACA,MACA,QACA,OACA,aACA,8BACA,UAGJ,mBACI,gBAGJ,mBACI,kBACA,kCACA,gCACA,gBACA,kBAGJ,oDACI,gBAGJ,UACI,kFACA,kBACA,eACA,gBACA,kEACA,mEACA,yBACA,iBAEI,s3BA0BJ,gBAEI,sZAQJ,sFACA,gEACA,oDACA,qBACA,gBAGJ,oCACI,gBAGJ,qBAGI,eACA,6CAGJ,iBAEI,mBAGJ,iBAEI,kBAGJ,iBAEI,mBAGJ,iBAEI,iBACA,uDAGJ,iBAEI,mBACA,uDAGJ,iBACI,sBACA,uDAGJ,iBACI,iBACA,uDAGJ,iBACI,sBACA,uDAGJ,iBACI,sBACA,uDAGJ,kBAEI,iBACA,uDAGJ,kBAEI,sBACA,uDAGJ,kBAEI,sBACA,uDAGJ,kBACI,kBACA,QACA,SACA,wGAGJ,SACI,cACA,kBACA,sGACA,qCACA,4DACA,sBAGJ,iFACI,YAGJ,iBACI,YACA,YACA,+CAGJ,cACI,UAGJ,+BACI,iBACI,kNAIJ,oDACA,0CACA,sDACA,0BACA,oBAGJ,kBACI,kBACA,YACA,iCACA,qCACA,8BACA,gBAGJ,iBACI,kBACA,6DACA,gEACA,8EACA,aACA,gBACA,mBAGJ,eACI,iFACA,qBACA,mBAGJ,eACI,aACA,cACA,YACA,gBACA,mBAGJ,iBACI,kBACA,iBAGJ,kBACI,kBAGJ,QACI,cACA,gBAGJ,qCACI,eAGJ,0DACI,4CAGJ,8GACI,iBAGJ,qBACI,qBACA,kBACA,YACA,aACA,wBACA,wBAGJ,6BACI,WACA,cACA,kBACA,MACA,QACA,SACA,OACA,6CACA,kBAGJ,6BACI,uCAGJ,4BACI,WACA,cACA,kBACA,qBACA,sBACA,QACA,SACA,kCACA,qCACA,mDAGJ,cACI,cACA,kBACA,kBACA,MACA,OACA,QACA,SACA,iBAEI,wlDAmDJ,gBAEI,gQAWJ,oBAEI,wJAOJ,4BAGJ,eACI,mBAGJ,kCACI,mBACA,iEACA,kEACA,yHACA","file":"ueblueprint-style.css"}
|
||||
{"version":3,"sourceRoot":"","sources":["../../scss/ueblueprint-style.css"],"names":[],"mappings":"AAAA,WACI,qBACA,iBACA,IACI,kGAIR,WACI,qBACA,mBACA,IACI,sGAIR,MACI,sBACA,6BACA,2BACA,sBACA,2BACA,+BACA,kBACA,mCACA,kCACA,sBACA,uBAGJ,cACI,cACA,kBACA,8EACA,+BACA,iBAGJ,qBACI,aACA,kBACA,MACA,QACA,OACA,aACA,8BACA,UAGJ,mBACI,gBAGJ,mBACI,kBACA,kCACA,gCACA,gBACA,kBAGJ,oDACI,gBAGJ,UACI,kFACA,kBACA,eACA,gBACA,kEACA,mEACA,yBACA,iBAEI,s3BA0BJ,gBAEI,sZAQJ,sFACA,gEACA,oDACA,qBACA,gBAGJ,oCACI,gBAGJ,qBAGI,eACA,6CAGJ,iBAEI,mBAGJ,iBAEI,kBAGJ,iBAEI,mBAGJ,iBAEI,iBACA,uDAGJ,iBAEI,mBACA,uDAGJ,iBACI,sBACA,uDAGJ,iBACI,iBACA,uDAGJ,iBACI,sBACA,uDAGJ,iBACI,sBACA,uDAGJ,kBAEI,iBACA,uDAGJ,kBAEI,sBACA,uDAGJ,kBAEI,sBACA,uDAGJ,kBACI,kBACA,QACA,SACA,wGAGJ,SACI,cACA,kBACA,sGACA,qCACA,4DACA,sBAGJ,iFACI,YAGJ,iBACI,YACA,YACA,+CAGJ,cACI,UAGJ,+BACI,iBACI,kNAIJ,oDACA,0CACA,sDACA,0BACA,oBAGJ,kBACI,kBACA,YACA,iCACA,qCACA,8BACA,gBAGJ,iBACI,kBACA,6DACA,gEACA,8EACA,aACA,gBACA,mBAGJ,eACI,iFACA,qBACA,mBAGJ,eACI,aACA,cACA,YACA,gBACA,mBAGJ,iBACI,kBACA,iBAGJ,kBACI,kBAGJ,QACI,cACA,gBAGJ,qCACI,eAGJ,+FACI,4CACA,iBAGJ,qBACI,qBACA,kBACA,YACA,aACA,wBACA,wBAGJ,6BACI,WACA,cACA,kBACA,MACA,QACA,SACA,OACA,6CACA,kBAGJ,6BACI,uCAGJ,4BACI,WACA,cACA,kBACA,qBACA,sBACA,QACA,SACA,kCACA,qCACA,mDAGJ,2CAEI,mBACA,mDACA,oDACA,6FACA,8FAGJ,aACI,cACA,kBACA,kBACA,MACA,OACA,QACA,SACA,iBAEI,wlDAmDJ,gBAEI,gQAWJ,oBAEI,wJAOJ,4BAGJ,eACI,mBAGJ,SACI,cACA,kBACA","file":"ueblueprint-style.css"}
|
||||
515
dist/ueblueprint.js
vendored
515
dist/ueblueprint.js
vendored
@@ -318,11 +318,11 @@ class GraphElement extends HTMLElement {
|
||||
*/
|
||||
constructor(entity, template) {
|
||||
super();
|
||||
/** @type {Blueprint}" */
|
||||
/** @type {Blueprint} */
|
||||
this.blueprint = null;
|
||||
/** @type {Entity}" */
|
||||
/** @type {Entity} */
|
||||
this.entity = entity;
|
||||
/** @type {Template}" */
|
||||
/** @type {Template} */
|
||||
this.template = template;
|
||||
/** @type {Context[]} */
|
||||
this.inputObjects = [];
|
||||
@@ -357,7 +357,7 @@ const tagReplacement = {
|
||||
'"': '"'
|
||||
};
|
||||
|
||||
function sanitizeText$1(value) {
|
||||
function sanitizeText(value) {
|
||||
if (value.constructor === String) {
|
||||
return value.replace(/[&<>'"]/g, tag => tagReplacement[tag])
|
||||
}
|
||||
@@ -399,7 +399,6 @@ class SelectorTemplate extends Template {
|
||||
*/
|
||||
apply(selector) {
|
||||
super.apply(selector);
|
||||
selector.classList.add("ueb-selector");
|
||||
this.applyFinishSelecting(selector);
|
||||
}
|
||||
|
||||
@@ -409,11 +408,11 @@ class SelectorTemplate extends Template {
|
||||
*/
|
||||
applyStartSelecting(selector, initialPosition) {
|
||||
// Set initial position
|
||||
selector.style.setProperty("--ueb-select-from-x", sanitizeText$1(initialPosition[0]));
|
||||
selector.style.setProperty("--ueb-select-from-y", sanitizeText$1(initialPosition[1]));
|
||||
selector.style.setProperty("--ueb-from-x", sanitizeText(initialPosition[0]));
|
||||
selector.style.setProperty("--ueb-from-y", sanitizeText(initialPosition[1]));
|
||||
// Final position coincide with the initial position, at the beginning of selection
|
||||
selector.style.setProperty("--ueb-select-to-x", sanitizeText$1(initialPosition[0]));
|
||||
selector.style.setProperty("--ueb-select-to-y", sanitizeText$1(initialPosition[1]));
|
||||
selector.style.setProperty("--ueb-to-x", sanitizeText(initialPosition[0]));
|
||||
selector.style.setProperty("--ueb-to-y", sanitizeText(initialPosition[1]));
|
||||
selector.dataset.selecting = "true";
|
||||
}
|
||||
|
||||
@@ -422,8 +421,8 @@ class SelectorTemplate extends Template {
|
||||
* @param {GraphSelector} selector Selector element
|
||||
*/
|
||||
applyDoSelecting(selector, finalPosition) {
|
||||
selector.style.setProperty("--ueb-select-to-x", sanitizeText$1(finalPosition[0]));
|
||||
selector.style.setProperty("--ueb-select-to-y", sanitizeText$1(finalPosition[1]));
|
||||
selector.style.setProperty("--ueb-to-x", sanitizeText(finalPosition[0]));
|
||||
selector.style.setProperty("--ueb-to-y", sanitizeText(finalPosition[1]));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -472,6 +471,9 @@ class GraphSelector extends GraphElement {
|
||||
|
||||
customElements.define("ueb-selector", GraphSelector);
|
||||
|
||||
/**
|
||||
* This solves the sole purpose of providing compression capability for html inside template literals strings. Check rollup.config.js function minifyHTML()
|
||||
*/
|
||||
const html = String.raw;
|
||||
|
||||
/** @typedef {import("../Blueprint").default} Blueprint */
|
||||
@@ -500,10 +502,10 @@ class BlueprintTemplate extends Template {
|
||||
<div class="ueb-viewport-body">
|
||||
<div class="ueb-grid"
|
||||
style="
|
||||
--ueb-additional-x:${sanitizeText$1(element.additional[0])};
|
||||
--ueb-additional-y:${sanitizeText$1(element.additional[1])};
|
||||
--ueb-translate-x:${sanitizeText$1(element.translateValue[0])};
|
||||
--ueb-translate-y:${sanitizeText$1(element.translateValue[1])};
|
||||
--ueb-additional-x:${sanitizeText(element.additional[0])};
|
||||
--ueb-additional-y:${sanitizeText(element.additional[1])};
|
||||
--ueb-translate-x:${sanitizeText(element.translateValue[0])};
|
||||
--ueb-translate-y:${sanitizeText(element.translateValue[1])};
|
||||
">
|
||||
<div class="ueb-grid-content" data-nodes></div>
|
||||
</div>
|
||||
@@ -546,8 +548,8 @@ class BlueprintTemplate extends Template {
|
||||
* @param {Blueprint} blueprint The blueprint element
|
||||
*/
|
||||
applyZoom(blueprint, newZoom) {
|
||||
blueprint.classList.remove("ueb-zoom-" + sanitizeText$1(blueprint.zoom));
|
||||
blueprint.classList.add("ueb-zoom-" + sanitizeText$1(newZoom));
|
||||
blueprint.classList.remove("ueb-zoom-" + sanitizeText(blueprint.zoom));
|
||||
blueprint.classList.add("ueb-zoom-" + sanitizeText(newZoom));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -555,8 +557,8 @@ class BlueprintTemplate extends Template {
|
||||
* @param {Blueprint} blueprint The blueprint element
|
||||
*/
|
||||
applyExpand(blueprint) {
|
||||
blueprint.gridElement.style.setProperty("--ueb-additional-x", sanitizeText$1(blueprint.additional[0]));
|
||||
blueprint.gridElement.style.setProperty("--ueb-additional-y", sanitizeText$1(blueprint.additional[1]));
|
||||
blueprint.gridElement.style.setProperty("--ueb-additional-x", sanitizeText(blueprint.additional[0]));
|
||||
blueprint.gridElement.style.setProperty("--ueb-additional-y", sanitizeText(blueprint.additional[1]));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -564,8 +566,8 @@ class BlueprintTemplate extends Template {
|
||||
* @param {Blueprint} blueprint The blueprint element
|
||||
*/
|
||||
applyTranlate(blueprint) {
|
||||
blueprint.gridElement.style.setProperty("--ueb-translate-x", sanitizeText$1(blueprint.translateValue[0]));
|
||||
blueprint.gridElement.style.setProperty("--ueb-translate-y", sanitizeText$1(blueprint.translateValue[1]));
|
||||
blueprint.gridElement.style.setProperty("--ueb-translate-x", sanitizeText(blueprint.translateValue[0]));
|
||||
blueprint.gridElement.style.setProperty("--ueb-translate-y", sanitizeText(blueprint.translateValue[1]));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -753,6 +755,16 @@ class Utility {
|
||||
return getComputedStyle(element).getPropertyValue("--ueb-scale")
|
||||
}
|
||||
|
||||
static convertLocation(viewportLocation, movementElement) {
|
||||
const scaleCorrection = 1 / Utility.getScale(movementElement);
|
||||
const targetOffset = movementElement.getBoundingClientRect();
|
||||
let location = [
|
||||
Math.round((viewportLocation[0] - targetOffset.x) * scaleCorrection),
|
||||
Math.round((viewportLocation[1] - targetOffset.y) * scaleCorrection)
|
||||
];
|
||||
return location
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a value in an object
|
||||
* @param {String[]} keys The chained keys to access from object in order to set the value
|
||||
@@ -1462,6 +1474,176 @@ class Copy extends Context {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {import("../graph/GraphLink").default} GraphLink
|
||||
*/
|
||||
class LinkTemplate extends Template {
|
||||
|
||||
/**
|
||||
* Computes the html content of the target element.
|
||||
* @param {GraphLink} link Link connecting two graph nodes
|
||||
* @returns The result html
|
||||
*/
|
||||
render(link) {
|
||||
return html`
|
||||
<svg viewBox="0 0 100 100">
|
||||
<line x1="0" y1="80" x2="100" y2="20" stroke="black" />
|
||||
</svg>
|
||||
`
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the style to the element.
|
||||
* @param {GraphLink} link Element of the graph
|
||||
*/
|
||||
apply(link) {
|
||||
super.apply(link);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the style relative to the source pin location.
|
||||
* @param {GraphLink} link Link element
|
||||
*/
|
||||
applySourceLocation(link, initialPosition) {
|
||||
// Set initial position
|
||||
link.style.setProperty("--ueb-from-x", sanitizeText(initialPosition[0]));
|
||||
link.style.setProperty("--ueb-from-y", sanitizeText(initialPosition[1]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the style relative to the destination pin location.
|
||||
* @param {GraphLink} link Link element
|
||||
*/
|
||||
applyDestinationLocation(link, finalPosition) {
|
||||
link.style.setProperty("--ueb-to-x", sanitizeText(finalPosition[0]));
|
||||
link.style.setProperty("--ueb-to-y", sanitizeText(finalPosition[1]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {import("./GraphPin").default} GraphPin
|
||||
*/
|
||||
class GraphLink extends GraphElement {
|
||||
|
||||
/** @type {GraphPin} */
|
||||
#source
|
||||
/** @type {GraphPin} */
|
||||
#destination
|
||||
#nodeDeleteHandler = _ => this.blueprint.removeGraphElement(this)
|
||||
#nodeDragSourceHandler = _ => this.setSourceLocation(this.#source.getLinkLocation())
|
||||
#nodeDragDestinatonHandler = _ => this.setDestinationLocation(this.#destination.getLinkLocation())
|
||||
|
||||
/**
|
||||
* @param {?GraphPin} source
|
||||
* @param {?GraphPin} destination
|
||||
*/
|
||||
constructor(source, destination) {
|
||||
super({}, new LinkTemplate());
|
||||
/** @type {import("../template/LinkTemplate").default} */
|
||||
this.template;
|
||||
this.setSourcePin(source);
|
||||
this.setDestinationPin(destination);
|
||||
}
|
||||
|
||||
setSourceLocation(location) {
|
||||
if (location == null) {
|
||||
location = this.#source.template.getLinkLocation(this.#source);
|
||||
}
|
||||
this.template.applySourceLocation(this, location);
|
||||
}
|
||||
|
||||
setDestinationLocation(location) {
|
||||
if (location == null) {
|
||||
location = this.#destination.template.getLinkLocation(this.#destination);
|
||||
}
|
||||
this.template.applyDestinationLocation(this, location);
|
||||
}
|
||||
|
||||
|
||||
getSourcePin() {
|
||||
return this.#source
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {GraphPin} graphPin
|
||||
*/
|
||||
setSourcePin(graphPin) {
|
||||
this.#source?.removeEventListener("ueb-node-delete", this.#nodeDeleteHandler);
|
||||
this.#source?.removeEventListener("ueb-node-drag", this.#nodeDragSourceHandler);
|
||||
this.#source = graphPin;
|
||||
this.#source?.addEventListener("ueb-node-delete", this.#nodeDeleteHandler);
|
||||
this.#source?.addEventListener("ueb-node-drag", this.#nodeDragSourceHandler);
|
||||
this.setSourceLocation();
|
||||
this.originatesFromInput = this.#destination == null;
|
||||
}
|
||||
|
||||
getDestinationPin() {
|
||||
return this.#destination
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {GraphPin} graphPin
|
||||
*/
|
||||
setDestinationPin(graphPin) {
|
||||
this.#destination?.removeEventListener("ueb-node-delete", this.#nodeDeleteHandler);
|
||||
this.#destination?.removeEventListener("ueb-node-drag", this.#nodeDragDestinatonHandler);
|
||||
this.#destination = graphPin;
|
||||
this.#destination?.addEventListener("ueb-node-delete", this.#nodeDeleteHandler);
|
||||
this.#destination?.addEventListener("ueb-node-drag", this.#nodeDragDestinatonHandler);
|
||||
this.originatesFromInput = false;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("ueb-link", GraphLink);
|
||||
|
||||
/**
|
||||
* @typedef {import("../graph/GraphPin").default} GraphPin
|
||||
*/
|
||||
class PinTemplate extends Template {
|
||||
|
||||
/**
|
||||
* Computes the html content of the pin.
|
||||
* @param {GraphPin} pin Pin entity
|
||||
* @returns The result html
|
||||
*/
|
||||
render(pin) {
|
||||
if (pin.isInput()) {
|
||||
return html`
|
||||
<span class="ueb-node-value-icon ${pin.isConnected() ? 'ueb-node-value-fill' : ''}"></span>
|
||||
${sanitizeText(pin.getPinDisplayName())}
|
||||
`
|
||||
} else {
|
||||
return html`
|
||||
${sanitizeText(pin.getPinDisplayName())}
|
||||
<span class="ueb-node-value-icon ${pin.isConnected() ? 'ueb-node-value-fill' : ''}"></span>
|
||||
`
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the style to the element.
|
||||
* @param {GraphPin} pin Element of the graph
|
||||
*/
|
||||
apply(pin) {
|
||||
super.apply(pin);
|
||||
pin.classList.add("ueb-node-" + pin.isInput() ? "input" : "output", "ueb-node-value-" + sanitizeText(pin.getType()));
|
||||
pin.clickableElement = pin;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {GraphPin} pin
|
||||
* @returns
|
||||
*/
|
||||
getLinkLocation(pin) {
|
||||
const rect = pin.querySelector(".ueb-node-value-icon").getBoundingClientRect();
|
||||
return Utility.convertLocation(
|
||||
[(rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2],
|
||||
pin.blueprint.gridElement)
|
||||
}
|
||||
}
|
||||
|
||||
class Pointing extends Context {
|
||||
|
||||
constructor(target, blueprint, options) {
|
||||
@@ -1474,14 +1656,8 @@ class Pointing extends Context {
|
||||
* @param {MouseEvent} mouseEvent
|
||||
* @returns
|
||||
*/
|
||||
getLocation(mouseEvent) {
|
||||
const scaleCorrection = 1 / Utility.getScale(this.target);
|
||||
const targetOffset = this.movementSpace.getBoundingClientRect();
|
||||
let location = [
|
||||
Math.round((mouseEvent.clientX - targetOffset.x) * scaleCorrection),
|
||||
Math.round((mouseEvent.clientY - targetOffset.y) * scaleCorrection)
|
||||
];
|
||||
return location
|
||||
locationFromEvent(mouseEvent) {
|
||||
return Utility.convertLocation([mouseEvent.clientX, mouseEvent.clientY], this.movementSpace)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1514,7 +1690,7 @@ class MouseClickDrag extends Pointing {
|
||||
// Attach the listeners
|
||||
movementListenedElement.addEventListener("mousemove", self.mouseStartedMovingHandler);
|
||||
document.addEventListener("mouseup", self.mouseUpHandler);
|
||||
self.clickedPosition = self.getLocation(e);
|
||||
self.clickedPosition = self.locationFromEvent(e);
|
||||
self.clicked(self.clickedPosition);
|
||||
return true
|
||||
}
|
||||
@@ -1544,7 +1720,7 @@ class MouseClickDrag extends Pointing {
|
||||
this.mouseMoveHandler = e => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const location = self.getLocation(e);
|
||||
const location = self.locationFromEvent(e);
|
||||
const movement = [e.movementX, e.movementY];
|
||||
self.dragTo(location, movement);
|
||||
};
|
||||
@@ -1591,183 +1767,60 @@ class MouseClickDrag extends Pointing {
|
||||
}
|
||||
}
|
||||
|
||||
class MouseScrollGraph extends MouseClickDrag {
|
||||
|
||||
startDrag() {
|
||||
this.blueprint.template.applyStartDragScrolling(this.blueprint);
|
||||
}
|
||||
|
||||
dragTo(location, movement) {
|
||||
this.blueprint.scrollDelta([-movement[0], -movement[1]]);
|
||||
}
|
||||
|
||||
endDrag() {
|
||||
this.blueprint.template.applyEndDragScrolling(this.blueprint);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {import("../graph/GraphLink").default} GraphLink
|
||||
*/
|
||||
class LinkTemplate extends Template {
|
||||
|
||||
/**
|
||||
* Computes the html content of the target element.
|
||||
* @param {GraphLink} link Link connecting two graph nodes
|
||||
* @returns The result html
|
||||
*/
|
||||
render(link) {
|
||||
return html`
|
||||
<svg viewBox="0 0 100 100">
|
||||
<line x1="0" y1="80" x2="100" y2="20" stroke="black" />
|
||||
</svg>
|
||||
`
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the style to the element.
|
||||
* @param {GraphLink} link Element of the graph
|
||||
*/
|
||||
apply(link) {
|
||||
super.apply(link);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the style relative to the source pin location.
|
||||
* @param {GraphLink} link Link element
|
||||
*/
|
||||
applySourceLocation(link, initialPosition) {
|
||||
// Set initial position
|
||||
link.style.setProperty("--ueb-link-from-x", sanitizeText(initialPosition[0]));
|
||||
link.style.setProperty("--ueb-link-from-y", sanitizeText(initialPosition[1]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the style relative to the destination pin location.
|
||||
* @param {GraphLink} link Link element
|
||||
*/
|
||||
applyDestinationLocation(link, finalPosition) {
|
||||
link.style.setProperty("--ueb-link-to-x", sanitizeText(finalPosition[0]));
|
||||
link.style.setProperty("--ueb-link-to-y", sanitizeText(finalPosition[1]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {import("./GraphPin").default} GraphPin
|
||||
*/
|
||||
class GraphLink extends GraphElement {
|
||||
|
||||
/** @type {GraphPin} */
|
||||
#source
|
||||
/** @type {GraphPin} */
|
||||
#destination
|
||||
#nodeDeleteHandler = _ => this.blueprint.removeGraphElement(this)
|
||||
#nodeDragSourceHandler = _ => this.setSourceLocation(this.#source.getLinkLocation())
|
||||
#nodeDragDestinatonHandler = _ => this.setDestinationLocation(this.#destination.getLinkLocation())
|
||||
|
||||
/**
|
||||
* @param {?GraphPin} source
|
||||
* @param {?GraphPin} destination
|
||||
*/
|
||||
constructor(source, destination) {
|
||||
super(this, new LinkTemplate());
|
||||
/** @type {import("../template/LinkTemplate").default} */
|
||||
this.template;
|
||||
this.setSource(source);
|
||||
this.setDestination(destination);
|
||||
}
|
||||
|
||||
setSourceLocation(location) {
|
||||
this.template.applySourceLocation(this.#source.getLinkLocation());
|
||||
}
|
||||
|
||||
setDestinationLocation(location) {
|
||||
this.template.applyDestinationLocation(this.#destination.getLinkLocation());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {GraphPin} graphPin
|
||||
*/
|
||||
setSourcePin(graphPin) {
|
||||
this.#source?.removeEventListener("ueb-node-delete", this.#nodeDeleteHandler);
|
||||
this.#source?.removeEventListener("ueb-node-drag", this.#nodeDragSourceHandler);
|
||||
this.#source = graphPin;
|
||||
this.#source?.addEventListener("ueb-node-delete", this.#nodeDeleteHandler);
|
||||
this.#source?.addEventListener("ueb-node-drag", this.#nodeDragSourceHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {GraphPin} graphPin
|
||||
*/
|
||||
setDestinationPin(graphPin) {
|
||||
this.#destination?.removeEventListener("ueb-node-delete", this.#nodeDeleteHandler);
|
||||
this.#destination?.removeEventListener("ueb-node-drag", this.#nodeDragDestinatonHandler);
|
||||
this.#destination = graphPin;
|
||||
this.#destination?.addEventListener("ueb-node-delete", this.#nodeDeleteHandler);
|
||||
this.#destination?.addEventListener("ueb-node-drag", this.#nodeDragDestinatonHandler);
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("ueb-link", GraphLink);
|
||||
|
||||
/**
|
||||
* @typedef {import("../graph/GraphPin").default} GraphPin
|
||||
*/
|
||||
class PinTemplate extends Template {
|
||||
|
||||
/**
|
||||
* Computes the html content of the pin.
|
||||
* @param {GraphPin} pin Pin entity
|
||||
* @returns The result html
|
||||
*/
|
||||
render(pin) {
|
||||
if (pin.isInput()) {
|
||||
return html`
|
||||
<span class="ueb-node-value-icon ${pin.isConnected() ? 'ueb-node-value-fill' : ''}"></span>
|
||||
${sanitizeText$1(pin.getPinDisplayName())}
|
||||
`
|
||||
} else {
|
||||
return html`
|
||||
${sanitizeText$1(pin.getPinDisplayName())}
|
||||
<span class="ueb-node-value-icon ${pin.isConnected() ? 'ueb-node-value-fill' : ''}"></span>
|
||||
`
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the style to the element.
|
||||
* @param {GraphPin} pin Element of the graph
|
||||
*/
|
||||
apply(pin) {
|
||||
super.apply(pin);
|
||||
pin.classList.add("ueb-node-" + pin.isInput() ? "input" : "output", "ueb-node-value-" + sanitizeText$1(pin.getType()));
|
||||
pin.clickableElement = pin.querySelector(".ueb-node-value-icon");
|
||||
}
|
||||
}
|
||||
|
||||
class MouseCreateLink extends MouseClickDrag {
|
||||
|
||||
/** @type {(e: MouseEvent) => void} */
|
||||
#mouseenterHandler
|
||||
|
||||
/** @type {(e: MouseEvent) => void} */
|
||||
#mouseleaveHandler
|
||||
|
||||
constructor(target, blueprint, options) {
|
||||
super(target, blueprint, options);
|
||||
/** @type {import("../../graph/GraphPin").default} */
|
||||
this.target;
|
||||
/** @type {import("../../graph/GraphLink").default} */
|
||||
this.link;
|
||||
/** @type {import("../../entity/PinEntity").default} */
|
||||
this.enteredPin;
|
||||
|
||||
let self = this;
|
||||
this.#mouseenterHandler = e => {
|
||||
if (!self.enteredPin) {
|
||||
self.enteredPin = e.target;
|
||||
}
|
||||
};
|
||||
this.#mouseleaveHandler = e => {
|
||||
if (self.enteredPin == e.target) {
|
||||
self.enteredPin = null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
startDrag() {
|
||||
this.target.dragLink();
|
||||
|
||||
this.link = new GraphLink(this.target, null);
|
||||
this.blueprint.nodesContainerElement.insertBefore(this.link, this.blueprint.selectorElement.nextElementSibling);
|
||||
this.blueprint.querySelectorAll("ueb-pin." + this.target.isInput() ? "output" : "input")
|
||||
.forEach(pin => {
|
||||
pin.addEventListener("mouseenter", this.#mouseenterHandler);
|
||||
pin.addEventListener("mouseleave", this.#mouseleaveHandler);
|
||||
});
|
||||
}
|
||||
|
||||
dragTo(location, movement) {
|
||||
//this.selectorElement.doSelecting(location)
|
||||
this.link.setDestinationLocation(location);
|
||||
}
|
||||
|
||||
endDrag() {
|
||||
if (this.started) ;
|
||||
this.blueprint.querySelectorAll("ueb-pin." + this.target.isInput() ? "output" : "input")
|
||||
.forEach(pin => {
|
||||
pin.removeEventListener("mouseenter", this.#mouseenterHandler);
|
||||
pin.removeEventListener("mouseleave", this.#mouseleaveHandler);
|
||||
});
|
||||
if (this.enteredPin) {
|
||||
this.link.setDestinationPin(this.link);
|
||||
}
|
||||
this.link = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1777,6 +1830,8 @@ class GraphPin extends GraphElement {
|
||||
super(entity, new PinTemplate());
|
||||
/** @type {import("../entity/PinEntity").default} */
|
||||
this.entity;
|
||||
/** @type {PinTemplate} */
|
||||
this.template;
|
||||
/** @type {HTMLElement} */
|
||||
this.clickableElement = null;
|
||||
}
|
||||
@@ -1784,7 +1839,8 @@ class GraphPin extends GraphElement {
|
||||
createInputObjects() {
|
||||
return [
|
||||
new MouseCreateLink(this.clickableElement, this.blueprint, {
|
||||
moveEverywhere: true
|
||||
moveEverywhere: true,
|
||||
looseTarget: true
|
||||
}),
|
||||
]
|
||||
}
|
||||
@@ -1817,15 +1873,6 @@ class GraphPin extends GraphElement {
|
||||
return this.entity.getType()
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns {GraphLink} The link created
|
||||
*/
|
||||
dragLink() {
|
||||
let link = new GraphLink(this);
|
||||
return link
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns The exact location where the link originates from or arrives at.
|
||||
* @returns {Number[]} The location array
|
||||
@@ -1847,8 +1894,8 @@ class SelectableDraggableTemplate extends Template {
|
||||
* @param {SelectableDraggable} element Element of the graph
|
||||
*/
|
||||
applyLocation(element) {
|
||||
element.style.setProperty("--ueb-position-x", sanitizeText$1(element.location[0]));
|
||||
element.style.setProperty("--ueb-position-y", sanitizeText$1(element.location[1]));
|
||||
element.style.setProperty("--ueb-position-x", sanitizeText(element.location[0]));
|
||||
element.style.setProperty("--ueb-position-y", sanitizeText(element.location[1]));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1904,7 +1951,7 @@ class NodeTemplate extends SelectableDraggableTemplate {
|
||||
<div class="ueb-node-header">
|
||||
<span class="ueb-node-name">
|
||||
<span class="ueb-node-symbol"></span>
|
||||
<span class="ueb-node-text">${sanitizeText$1(node.entity.getNodeDisplayName())}</span>
|
||||
<span class="ueb-node-text">${sanitizeText(node.entity.getNodeDisplayName())}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="ueb-node-body">
|
||||
@@ -1925,8 +1972,8 @@ class NodeTemplate extends SelectableDraggableTemplate {
|
||||
if (node.selected) {
|
||||
node.classList.add("ueb-selected");
|
||||
}
|
||||
node.style.setProperty("--ueb-position-x", sanitizeText$1(node.location[0]));
|
||||
node.style.setProperty("--ueb-position-y", sanitizeText$1(node.location[1]));
|
||||
node.style.setProperty("--ueb-position-x", sanitizeText(node.location[0]));
|
||||
node.style.setProperty("--ueb-position-y", sanitizeText(node.location[1]));
|
||||
/** @type {HTMLElement} */
|
||||
let inputContainer = node.querySelector(".ueb-node-inputs");
|
||||
/** @type {HTMLElement} */
|
||||
@@ -2211,6 +2258,39 @@ class KeyvoardCanc extends KeyboardShortcut {
|
||||
}
|
||||
}
|
||||
|
||||
class KeyboardSelectAll extends KeyboardShortcut {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {HTMLElement} target
|
||||
* @param {import("../../Blueprint").default} blueprint
|
||||
* @param {Object} options
|
||||
*/
|
||||
constructor(target, blueprint, options = {}) {
|
||||
options = KeyboardShortcut.keyOptionsParse(options, Configuration.selectAllKeyboardKey);
|
||||
super(target, blueprint, options);
|
||||
}
|
||||
|
||||
fire() {
|
||||
this.blueprint.selectAll();
|
||||
}
|
||||
}
|
||||
|
||||
class MouseScrollGraph extends MouseClickDrag {
|
||||
|
||||
startDrag() {
|
||||
this.blueprint.template.applyStartDragScrolling(this.blueprint);
|
||||
}
|
||||
|
||||
dragTo(location, movement) {
|
||||
this.blueprint.scrollDelta([-movement[0], -movement[1]]);
|
||||
}
|
||||
|
||||
endDrag() {
|
||||
this.blueprint.template.applyEndDragScrolling(this.blueprint);
|
||||
}
|
||||
}
|
||||
|
||||
class MouseTracking extends Pointing {
|
||||
|
||||
constructor(target, blueprint, options = {}) {
|
||||
@@ -2219,7 +2299,7 @@ class MouseTracking extends Pointing {
|
||||
|
||||
let self = this;
|
||||
this.mousemoveHandler = e => {
|
||||
self.blueprint.entity.mousePosition = self.getLocation(e);
|
||||
self.blueprint.entity.mousePosition = self.locationFromEvent(e);
|
||||
return true
|
||||
};
|
||||
}
|
||||
@@ -2356,7 +2436,7 @@ class MouseWheel extends Pointing {
|
||||
|
||||
this.mouseWheelHandler = e => {
|
||||
e.preventDefault();
|
||||
const location = self.getLocation(e);
|
||||
const location = self.locationFromEvent(e);
|
||||
self.wheel(Math.sign(e.deltaY), location);
|
||||
return true
|
||||
};
|
||||
@@ -2391,24 +2471,6 @@ class Zoom extends MouseWheel {
|
||||
}
|
||||
}
|
||||
|
||||
class KeyboardSelectAll extends KeyboardShortcut {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {HTMLElement} target
|
||||
* @param {import("../../Blueprint").default} blueprint
|
||||
* @param {Object} options
|
||||
*/
|
||||
constructor(target, blueprint, options = {}) {
|
||||
options = KeyboardShortcut.keyOptionsParse(options, Configuration.selectAllKeyboardKey);
|
||||
super(target, blueprint, options);
|
||||
}
|
||||
|
||||
fire() {
|
||||
this.blueprint.selectAll();
|
||||
}
|
||||
}
|
||||
|
||||
class Blueprint extends GraphElement {
|
||||
|
||||
constructor() {
|
||||
@@ -2488,7 +2550,6 @@ class Blueprint extends GraphElement {
|
||||
|
||||
createInputObjects() {
|
||||
return [
|
||||
|
||||
new Copy(this.getGridDOMElement(), this),
|
||||
new Paste(this.getGridDOMElement(), this),
|
||||
new KeyvoardCanc(this.getGridDOMElement(), this),
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import BlueprintTemplate from "./template/BlueprintTemplate"
|
||||
import Configuration from "./Configuration"
|
||||
import Copy from "./input/common/Copy"
|
||||
import MouseScrollGraph from "./input/mouse/MouseScrollGraph"
|
||||
import GraphElement from "./graph/GraphElement"
|
||||
import GraphLink from "./graph/GraphLink"
|
||||
import GraphNode from "./graph/GraphNode"
|
||||
import GraphSelector from "./graph/GraphSelector"
|
||||
import KeyboardCanc from "./input/keybaord/KeyboardCanc"
|
||||
import KeyboardSelectAll from "./input/keybaord/KeyboardSelectAll"
|
||||
import MouseScrollGraph from "./input/mouse/MouseScrollGraph"
|
||||
import MouseTracking from "./input/mouse/MouseTracking"
|
||||
import Paste from "./input/common/Paste"
|
||||
import Select from "./input/mouse/Select"
|
||||
import Unfocus from "./input/mouse/Unfocus"
|
||||
import Utility from "./Utility"
|
||||
import Zoom from "./input/mouse/Zoom"
|
||||
import KeyboardSelectAll from "./input/keybaord/KeyboardSelectAll"
|
||||
|
||||
export default class Blueprint extends GraphElement {
|
||||
|
||||
@@ -94,7 +94,6 @@ export default class Blueprint extends GraphElement {
|
||||
|
||||
createInputObjects() {
|
||||
return [
|
||||
|
||||
new Copy(this.getGridDOMElement(), this),
|
||||
new Paste(this.getGridDOMElement(), this),
|
||||
new KeyboardCanc(this.getGridDOMElement(), this),
|
||||
|
||||
@@ -10,6 +10,16 @@ export default class Utility {
|
||||
return getComputedStyle(element).getPropertyValue("--ueb-scale")
|
||||
}
|
||||
|
||||
static convertLocation(viewportLocation, movementElement) {
|
||||
const scaleCorrection = 1 / Utility.getScale(movementElement)
|
||||
const targetOffset = movementElement.getBoundingClientRect()
|
||||
let location = [
|
||||
Math.round((viewportLocation[0] - targetOffset.x) * scaleCorrection),
|
||||
Math.round((viewportLocation[1] - targetOffset.y) * scaleCorrection)
|
||||
]
|
||||
return location
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a value in an object
|
||||
* @param {String[]} keys The chained keys to access from object in order to set the value
|
||||
|
||||
@@ -14,11 +14,11 @@ export default class GraphElement extends HTMLElement {
|
||||
*/
|
||||
constructor(entity, template) {
|
||||
super()
|
||||
/** @type {Blueprint}" */
|
||||
/** @type {Blueprint} */
|
||||
this.blueprint = null
|
||||
/** @type {Entity}" */
|
||||
/** @type {Entity} */
|
||||
this.entity = entity
|
||||
/** @type {Template}" */
|
||||
/** @type {Template} */
|
||||
this.template = template
|
||||
/** @type {Context[]} */
|
||||
this.inputObjects = []
|
||||
|
||||
@@ -3,7 +3,7 @@ import LinkTemplate from "../template/LinkTemplate"
|
||||
|
||||
|
||||
/**
|
||||
* @type {import("./GraphPin").default} GraphPin
|
||||
* @typedef {import("./GraphPin").default} GraphPin
|
||||
*/
|
||||
export default class GraphLink extends GraphElement {
|
||||
|
||||
@@ -20,19 +20,30 @@ export default class GraphLink extends GraphElement {
|
||||
* @param {?GraphPin} destination
|
||||
*/
|
||||
constructor(source, destination) {
|
||||
super(this, new LinkTemplate())
|
||||
super({}, new LinkTemplate())
|
||||
/** @type {import("../template/LinkTemplate").default} */
|
||||
this.template
|
||||
this.setSource(source)
|
||||
this.setDestination(destination)
|
||||
this.setSourcePin(source)
|
||||
this.setDestinationPin(destination)
|
||||
}
|
||||
|
||||
setSourceLocation(location) {
|
||||
this.template.applySourceLocation(this.#source.getLinkLocation())
|
||||
if (location == null) {
|
||||
location = this.#source.template.getLinkLocation(this.#source)
|
||||
}
|
||||
this.template.applySourceLocation(this, location)
|
||||
}
|
||||
|
||||
setDestinationLocation(location) {
|
||||
this.template.applyDestinationLocation(this.#destination.getLinkLocation())
|
||||
if (location == null) {
|
||||
location = this.#destination.template.getLinkLocation(this.#destination)
|
||||
}
|
||||
this.template.applyDestinationLocation(this, location)
|
||||
}
|
||||
|
||||
|
||||
getSourcePin() {
|
||||
return this.#source
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,6 +55,12 @@ export default class GraphLink extends GraphElement {
|
||||
this.#source = graphPin
|
||||
this.#source?.addEventListener("ueb-node-delete", this.#nodeDeleteHandler)
|
||||
this.#source?.addEventListener("ueb-node-drag", this.#nodeDragSourceHandler)
|
||||
this.setSourceLocation()
|
||||
this.originatesFromInput = this.#destination == null
|
||||
}
|
||||
|
||||
getDestinationPin() {
|
||||
return this.#destination
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,6 +73,7 @@ export default class GraphLink extends GraphElement {
|
||||
this.#destination = graphPin
|
||||
this.#destination?.addEventListener("ueb-node-delete", this.#nodeDeleteHandler)
|
||||
this.#destination?.addEventListener("ueb-node-drag", this.#nodeDragDestinatonHandler)
|
||||
this.originatesFromInput = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import NodeTemplate from "../template/NodeTemplate"
|
||||
import ObjectEntity from "../entity/ObjectEntity"
|
||||
import PinEntity from "../entity/PinEntity"
|
||||
import SelectableDraggable from "./SelectableDraggable"
|
||||
import SerializerFactory from "../serialization/SerializerFactory"
|
||||
import PinEntity from "../entity/PinEntity"
|
||||
|
||||
export default class GraphNode extends SelectableDraggable {
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import GraphElement from "./GraphElement"
|
||||
import PinTemplate from "../template/PinTemplate"
|
||||
import MouseCreateLink from "../input/mouse/MouseCreateLink"
|
||||
import GraphLink from "./GraphLink"
|
||||
|
||||
export default class GraphPin extends GraphElement {
|
||||
|
||||
@@ -9,6 +8,8 @@ export default class GraphPin extends GraphElement {
|
||||
super(entity, new PinTemplate())
|
||||
/** @type {import("../entity/PinEntity").default} */
|
||||
this.entity
|
||||
/** @type {PinTemplate} */
|
||||
this.template
|
||||
/** @type {HTMLElement} */
|
||||
this.clickableElement = null
|
||||
}
|
||||
@@ -16,7 +17,8 @@ export default class GraphPin extends GraphElement {
|
||||
createInputObjects() {
|
||||
return [
|
||||
new MouseCreateLink(this.clickableElement, this.blueprint, {
|
||||
moveEverywhere: true
|
||||
moveEverywhere: true,
|
||||
looseTarget: true
|
||||
}),
|
||||
]
|
||||
}
|
||||
@@ -49,15 +51,6 @@ export default class GraphPin extends GraphElement {
|
||||
return this.entity.getType()
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns {GraphLink} The link created
|
||||
*/
|
||||
dragLink() {
|
||||
let link = new GraphLink(this)
|
||||
return link
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns The exact location where the link originates from or arrives at.
|
||||
* @returns {Number[]} The location array
|
||||
|
||||
@@ -29,7 +29,7 @@ export default class MouseClickDrag extends Pointing {
|
||||
// Attach the listeners
|
||||
movementListenedElement.addEventListener("mousemove", self.mouseStartedMovingHandler)
|
||||
document.addEventListener("mouseup", self.mouseUpHandler)
|
||||
self.clickedPosition = self.getLocation(e)
|
||||
self.clickedPosition = self.locationFromEvent(e)
|
||||
self.clicked(self.clickedPosition)
|
||||
return true
|
||||
}
|
||||
@@ -59,7 +59,7 @@ export default class MouseClickDrag extends Pointing {
|
||||
this.mouseMoveHandler = e => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
const location = self.getLocation(e)
|
||||
const location = self.locationFromEvent(e)
|
||||
const movement = [e.movementX, e.movementY]
|
||||
self.dragTo(location, movement)
|
||||
}
|
||||
|
||||
@@ -1,29 +1,61 @@
|
||||
import GraphLink from "../../graph/GraphLink"
|
||||
import MouseClickDrag from "./MouseClickDrag"
|
||||
|
||||
export default class MouseCreateLink extends MouseClickDrag {
|
||||
|
||||
/** @type {(e: MouseEvent) => void} */
|
||||
#mouseenterHandler
|
||||
|
||||
/** @type {(e: MouseEvent) => void} */
|
||||
#mouseleaveHandler
|
||||
|
||||
constructor(target, blueprint, options) {
|
||||
super(target, blueprint, options)
|
||||
/** @type {import("../../graph/GraphPin").default} */
|
||||
this.target
|
||||
/** @type {import("../../graph/GraphLink").default} */
|
||||
this.link
|
||||
/** @type {import("../../entity/PinEntity").default} */
|
||||
this.enteredPin
|
||||
|
||||
let self = this
|
||||
this.#mouseenterHandler = e => {
|
||||
if (!self.enteredPin) {
|
||||
self.enteredPin = e.target
|
||||
}
|
||||
}
|
||||
this.#mouseleaveHandler = e => {
|
||||
if (self.enteredPin == e.target) {
|
||||
self.enteredPin = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
startDrag() {
|
||||
let link = this.target.dragLink()
|
||||
|
||||
this.link = new GraphLink(this.target, null)
|
||||
this.blueprint.nodesContainerElement.insertBefore(this.link, this.blueprint.selectorElement.nextElementSibling)
|
||||
this.blueprint.querySelectorAll("ueb-pin." + this.target.isInput() ? "output" : "input")
|
||||
.forEach(pin => {
|
||||
pin.addEventListener("mouseenter", this.#mouseenterHandler)
|
||||
pin.addEventListener("mouseleave", this.#mouseleaveHandler)
|
||||
})
|
||||
}
|
||||
|
||||
dragTo(location, movement) {
|
||||
//this.selectorElement.doSelecting(location)
|
||||
this.link.setDestinationLocation(location)
|
||||
}
|
||||
|
||||
endDrag() {
|
||||
if (this.started) {
|
||||
//this.selectorElement.finishSelecting()
|
||||
this.blueprint.querySelectorAll("ueb-pin." + this.target.isInput() ? "output" : "input")
|
||||
.forEach(pin => {
|
||||
pin.removeEventListener("mouseenter", this.#mouseenterHandler)
|
||||
pin.removeEventListener("mouseleave", this.#mouseleaveHandler)
|
||||
})
|
||||
if (this.enteredPin) {
|
||||
this.link.setDestinationPin(this.link)
|
||||
} else {
|
||||
// this.blueprint.unselectAll()
|
||||
// this.link.remove()
|
||||
}
|
||||
this.link = null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ export default class MouseTracking extends Pointing {
|
||||
|
||||
let self = this
|
||||
this.mousemoveHandler = e => {
|
||||
self.blueprint.entity.mousePosition = self.getLocation(e)
|
||||
self.blueprint.entity.mousePosition = self.locationFromEvent(e)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ export default class MouseWheel extends Pointing {
|
||||
|
||||
this.mouseWheelHandler = e => {
|
||||
e.preventDefault()
|
||||
const location = self.getLocation(e)
|
||||
const location = self.locationFromEvent(e)
|
||||
self.wheel(Math.sign(e.deltaY), location)
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -13,13 +13,7 @@ export default class Pointing extends Context {
|
||||
* @param {MouseEvent} mouseEvent
|
||||
* @returns
|
||||
*/
|
||||
getLocation(mouseEvent) {
|
||||
const scaleCorrection = 1 / Utility.getScale(this.target)
|
||||
const targetOffset = this.movementSpace.getBoundingClientRect()
|
||||
let location = [
|
||||
Math.round((mouseEvent.clientX - targetOffset.x) * scaleCorrection),
|
||||
Math.round((mouseEvent.clientY - targetOffset.y) * scaleCorrection)
|
||||
]
|
||||
return location
|
||||
locationFromEvent(mouseEvent) {
|
||||
return Utility.convertLocation([mouseEvent.clientX, mouseEvent.clientY], this.movementSpace)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import html from "./html"
|
||||
import sanitizeText from "./sanitizeText"
|
||||
import Template from "./Template"
|
||||
|
||||
/**
|
||||
@@ -25,7 +26,6 @@ export default class LinkTemplate extends Template {
|
||||
*/
|
||||
apply(link) {
|
||||
super.apply(link)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -34,8 +34,8 @@ export default class LinkTemplate extends Template {
|
||||
*/
|
||||
applySourceLocation(link, initialPosition) {
|
||||
// Set initial position
|
||||
link.style.setProperty("--ueb-link-from-x", sanitizeText(initialPosition[0]))
|
||||
link.style.setProperty("--ueb-link-from-y", sanitizeText(initialPosition[1]))
|
||||
link.style.setProperty("--ueb-from-x", sanitizeText(initialPosition[0]))
|
||||
link.style.setProperty("--ueb-from-y", sanitizeText(initialPosition[1]))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -43,7 +43,7 @@ export default class LinkTemplate extends Template {
|
||||
* @param {GraphLink} link Link element
|
||||
*/
|
||||
applyDestinationLocation(link, finalPosition) {
|
||||
link.style.setProperty("--ueb-link-to-x", sanitizeText(finalPosition[0]))
|
||||
link.style.setProperty("--ueb-link-to-y", sanitizeText(finalPosition[1]))
|
||||
link.style.setProperty("--ueb-to-x", sanitizeText(finalPosition[0]))
|
||||
link.style.setProperty("--ueb-to-y", sanitizeText(finalPosition[1]))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import Utility from "../Utility"
|
||||
import html from "./html"
|
||||
import sanitizeText from "./sanitizeText"
|
||||
import Template from "./Template"
|
||||
@@ -33,6 +34,18 @@ export default class PinTemplate extends Template {
|
||||
apply(pin) {
|
||||
super.apply(pin)
|
||||
pin.classList.add("ueb-node-" + pin.isInput() ? "input" : "output", "ueb-node-value-" + sanitizeText(pin.getType()))
|
||||
pin.clickableElement = pin.querySelector(".ueb-node-value-icon")
|
||||
pin.clickableElement = pin
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {GraphPin} pin
|
||||
* @returns
|
||||
*/
|
||||
getLinkLocation(pin) {
|
||||
const rect = pin.querySelector(".ueb-node-value-icon").getBoundingClientRect()
|
||||
return Utility.convertLocation(
|
||||
[(rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2],
|
||||
pin.blueprint.gridElement)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ export default class SelectorTemplate extends Template {
|
||||
*/
|
||||
apply(selector) {
|
||||
super.apply(selector)
|
||||
selector.classList.add("ueb-selector")
|
||||
this.applyFinishSelecting(selector)
|
||||
}
|
||||
|
||||
@@ -22,11 +21,11 @@ export default class SelectorTemplate extends Template {
|
||||
*/
|
||||
applyStartSelecting(selector, initialPosition) {
|
||||
// Set initial position
|
||||
selector.style.setProperty("--ueb-select-from-x", sanitizeText(initialPosition[0]))
|
||||
selector.style.setProperty("--ueb-select-from-y", sanitizeText(initialPosition[1]))
|
||||
selector.style.setProperty("--ueb-from-x", sanitizeText(initialPosition[0]))
|
||||
selector.style.setProperty("--ueb-from-y", sanitizeText(initialPosition[1]))
|
||||
// Final position coincide with the initial position, at the beginning of selection
|
||||
selector.style.setProperty("--ueb-select-to-x", sanitizeText(initialPosition[0]))
|
||||
selector.style.setProperty("--ueb-select-to-y", sanitizeText(initialPosition[1]))
|
||||
selector.style.setProperty("--ueb-to-x", sanitizeText(initialPosition[0]))
|
||||
selector.style.setProperty("--ueb-to-y", sanitizeText(initialPosition[1]))
|
||||
selector.dataset.selecting = "true"
|
||||
}
|
||||
|
||||
@@ -35,8 +34,8 @@ export default class SelectorTemplate extends Template {
|
||||
* @param {GraphSelector} selector Selector element
|
||||
*/
|
||||
applyDoSelecting(selector, finalPosition) {
|
||||
selector.style.setProperty("--ueb-select-to-x", sanitizeText(finalPosition[0]))
|
||||
selector.style.setProperty("--ueb-select-to-y", sanitizeText(finalPosition[1]))
|
||||
selector.style.setProperty("--ueb-to-x", sanitizeText(finalPosition[0]))
|
||||
selector.style.setProperty("--ueb-to-y", sanitizeText(finalPosition[1]))
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
/**
|
||||
* This solves the sole purpose of providing compression capability for html inside template literals strings. Check rollup.config.js function minifyHTML()
|
||||
*/
|
||||
const html = String.raw
|
||||
export default html
|
||||
|
||||
@@ -1,77 +1,77 @@
|
||||
@font-face {
|
||||
font-family: "Roboto";
|
||||
font-style : light;
|
||||
src :
|
||||
font-family : "Roboto";
|
||||
font-style : light;
|
||||
src :
|
||||
url("../font/roboto-light.woff2") format("woff2"),
|
||||
url("../font/roboto-light.woff") format("woff");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Roboto";
|
||||
font-style : regular;
|
||||
src :
|
||||
font-family : "Roboto";
|
||||
font-style : regular;
|
||||
src :
|
||||
url("../font/roboto-regular.woff2") format("woff2"),
|
||||
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 : 8px;
|
||||
--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 : 8px;
|
||||
}
|
||||
|
||||
ueb-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;
|
||||
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 {
|
||||
display : flex;
|
||||
position : absolute;
|
||||
top : 0;
|
||||
right : 0;
|
||||
left : 0;
|
||||
height : 1.5em;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
z-index : 1;
|
||||
display : flex;
|
||||
position : absolute;
|
||||
top : 0;
|
||||
right : 0;
|
||||
left : 0;
|
||||
height : 1.5em;
|
||||
background : rgba(0, 0, 0, 0.5);
|
||||
z-index : 1;
|
||||
}
|
||||
|
||||
.ueb-viewport-zoom {
|
||||
color: #4d4d4db7;
|
||||
color : #4d4d4db7;
|
||||
}
|
||||
|
||||
.ueb-viewport-body {
|
||||
position : relative;
|
||||
height : var(--ueb-viewport-height);
|
||||
width : var(--ueb-viewport-width);
|
||||
overflow : hidden;
|
||||
scrollbar-width: 0;
|
||||
position : relative;
|
||||
height : var(--ueb-viewport-height);
|
||||
width : var(--ueb-viewport-width);
|
||||
overflow : hidden;
|
||||
scrollbar-width : 0;
|
||||
}
|
||||
|
||||
ueb-blueprint[data-focused="true"] .ueb-viewport-body {
|
||||
overflow: scroll;
|
||||
overflow : scroll;
|
||||
}
|
||||
|
||||
.ueb-grid {
|
||||
--ueb-grid-line-actual-width: calc(var(--ueb-grid-line-width) / var(--ueb-scale));
|
||||
position : absolute;
|
||||
min-width : 100%;
|
||||
min-height : 100%;
|
||||
width : calc((100% + var(--ueb-additional-x) * 1px) / var(--ueb-scale));
|
||||
height : calc((100% + var(--ueb-additional-y) * 1px) / var(--ueb-scale));
|
||||
background-color : #262626;
|
||||
background-image :
|
||||
--ueb-grid-line-actual-width : calc(var(--ueb-grid-line-width) / var(--ueb-scale));
|
||||
position : absolute;
|
||||
min-width : 100%;
|
||||
min-height : 100%;
|
||||
width : calc((100% + var(--ueb-additional-x) * 1px) / var(--ueb-scale));
|
||||
height : calc((100% + var(--ueb-additional-y) * 1px) / var(--ueb-scale));
|
||||
background-color : #262626;
|
||||
background-image :
|
||||
/* Axis lines */
|
||||
linear-gradient(var(--ueb-grid-axis-line-color),
|
||||
var(--ueb-grid-axis-line-color)),
|
||||
@@ -109,117 +109,117 @@ ueb-blueprint[data-focused="true"] .ueb-viewport-body {
|
||||
/* Light grid */
|
||||
var(--ueb-grid-actual-size) var(--ueb-grid-actual-size),
|
||||
var(--ueb-grid-actual-size) var(--ueb-grid-actual-size);
|
||||
background-position: calc(var(--ueb-translate-x) * 1px) calc(var(--ueb-translate-y) * 1px);
|
||||
background-repeat : repeat-x, repeat-y, repeat, repeat, repeat, repeat;
|
||||
transform : scale(var(--ueb-scale), var(--ueb-scale));
|
||||
transform-origin : 0 0;
|
||||
overflow : hidden;
|
||||
background-position : calc(var(--ueb-translate-x) * 1px) calc(var(--ueb-translate-y) * 1px);
|
||||
background-repeat : repeat-x, repeat-y, repeat, repeat, repeat, repeat;
|
||||
transform : scale(var(--ueb-scale), var(--ueb-scale));
|
||||
transform-origin : 0 0;
|
||||
overflow : hidden;
|
||||
}
|
||||
|
||||
.ueb-grid[data-drag-scrolling="true"] {
|
||||
cursor: grabbing;
|
||||
cursor : grabbing;
|
||||
}
|
||||
|
||||
.ueb-zoom--.ueb,
|
||||
.ueb {
|
||||
/* 16/16 */
|
||||
--ueb-scale : 1;
|
||||
--ueb-grid-actual-size: var(--ueb-grid-size);
|
||||
--ueb-scale : 1;
|
||||
--ueb-grid-actual-size : var(--ueb-grid-size);
|
||||
}
|
||||
|
||||
.ueb-zoom--1.ueb {
|
||||
/* 14/16 */
|
||||
--ueb-scale: 0.875;
|
||||
--ueb-scale : 0.875;
|
||||
}
|
||||
|
||||
.ueb-zoom--2.ueb {
|
||||
/* 12/16 */
|
||||
--ueb-scale: 0.75;
|
||||
--ueb-scale : 0.75;
|
||||
}
|
||||
|
||||
.ueb-zoom--3.ueb {
|
||||
/* 10.8/16 */
|
||||
--ueb-scale: 0.675;
|
||||
--ueb-scale : 0.675;
|
||||
}
|
||||
|
||||
.ueb-zoom--4.ueb {
|
||||
/* 8/16 */
|
||||
--ueb-scale : 0.5;
|
||||
--ueb-grid-actual-size: calc(var(--ueb-grid-size) * 2);
|
||||
--ueb-scale : 0.5;
|
||||
--ueb-grid-actual-size : calc(var(--ueb-grid-size) * 2);
|
||||
}
|
||||
|
||||
.ueb-zoom--5.ueb {
|
||||
/* 6/16 */
|
||||
--ueb-scale : 0.375;
|
||||
--ueb-grid-actual-size: calc(var(--ueb-grid-size) * 2);
|
||||
--ueb-scale : 0.375;
|
||||
--ueb-grid-actual-size : calc(var(--ueb-grid-size) * 2);
|
||||
}
|
||||
|
||||
.ueb-zoom--6.ueb {
|
||||
--ueb-scale : 0.333333;
|
||||
--ueb-grid-actual-size: calc(var(--ueb-grid-size) * 3);
|
||||
--ueb-scale : 0.333333;
|
||||
--ueb-grid-actual-size : calc(var(--ueb-grid-size) * 3);
|
||||
}
|
||||
|
||||
.ueb-zoom--7.ueb {
|
||||
--ueb-scale : 0.3;
|
||||
--ueb-grid-actual-size: calc(var(--ueb-grid-size) * 3);
|
||||
--ueb-scale : 0.3;
|
||||
--ueb-grid-actual-size : calc(var(--ueb-grid-size) * 3);
|
||||
}
|
||||
|
||||
.ueb-zoom--8.ueb {
|
||||
--ueb-scale : 0.266666;
|
||||
--ueb-grid-actual-size: calc(var(--ueb-grid-size) * 3);
|
||||
--ueb-scale : 0.266666;
|
||||
--ueb-grid-actual-size : calc(var(--ueb-grid-size) * 3);
|
||||
}
|
||||
|
||||
.ueb-zoom--9.ueb {
|
||||
--ueb-scale : 0.233333;
|
||||
--ueb-grid-actual-size: calc(var(--ueb-grid-size) * 3);
|
||||
--ueb-scale : 0.233333;
|
||||
--ueb-grid-actual-size : calc(var(--ueb-grid-size) * 3);
|
||||
}
|
||||
|
||||
.ueb-zoom--10.ueb {
|
||||
/* 12/16 */
|
||||
--ueb-scale : 0.2;
|
||||
--ueb-grid-actual-size: calc(var(--ueb-grid-size) * 3);
|
||||
--ueb-scale : 0.2;
|
||||
--ueb-grid-actual-size : calc(var(--ueb-grid-size) * 3);
|
||||
}
|
||||
|
||||
.ueb-zoom--11.ueb {
|
||||
/* 12/16 */
|
||||
--ueb-scale : 0.166666;
|
||||
--ueb-grid-actual-size: calc(var(--ueb-grid-size) * 6);
|
||||
--ueb-scale : 0.166666;
|
||||
--ueb-grid-actual-size : calc(var(--ueb-grid-size) * 6);
|
||||
}
|
||||
|
||||
.ueb-zoom--12.ueb {
|
||||
/* 12/16 */
|
||||
--ueb-scale : 0.133333;
|
||||
--ueb-grid-actual-size: calc(var(--ueb-grid-size) * 6);
|
||||
--ueb-scale : 0.133333;
|
||||
--ueb-grid-actual-size : calc(var(--ueb-grid-size) * 6);
|
||||
}
|
||||
|
||||
.ueb-grid-content {
|
||||
position : relative;
|
||||
width : 0;
|
||||
height : 0;
|
||||
transform: translateX(calc(var(--ueb-translate-x) * 1px)) translateY(calc(var(--ueb-translate-y) * 1px));
|
||||
position : relative;
|
||||
width : 0;
|
||||
height : 0;
|
||||
transform : translateX(calc(var(--ueb-translate-x) * 1px)) translateY(calc(var(--ueb-translate-y) * 1px));
|
||||
}
|
||||
|
||||
ueb-node {
|
||||
display : block;
|
||||
position : absolute;
|
||||
transform : translateX(calc(var(--ueb-position-x) * 1px)) translateY(calc(var(--ueb-position-y) * 1px));
|
||||
border-radius: var(--ueb-node-radius);
|
||||
box-shadow : 0 0 1px 0 black, 1px 4px 6px 0 rgba(0, 0, 0, 0.3);
|
||||
will-change : transform;
|
||||
display : block;
|
||||
position : absolute;
|
||||
transform : translateX(calc(var(--ueb-position-x) * 1px)) translateY(calc(var(--ueb-position-y) * 1px));
|
||||
border-radius : var(--ueb-node-radius);
|
||||
box-shadow : 0 0 1px 0 black, 1px 4px 6px 0 rgba(0, 0, 0, 0.3);
|
||||
will-change : transform;
|
||||
}
|
||||
|
||||
.ueb-grid[data-drag-scrolling="false"] ueb-selector[data-selecting="false"]~ueb-node {
|
||||
cursor: move;
|
||||
cursor : move;
|
||||
}
|
||||
|
||||
.ueb-node-border {
|
||||
margin : -3px;
|
||||
padding : 3px;
|
||||
border-radius: calc(var(--ueb-node-radius) * 1.4);
|
||||
margin : -3px;
|
||||
padding : 3px;
|
||||
border-radius : calc(var(--ueb-node-radius) * 1.4);
|
||||
}
|
||||
|
||||
.ueb-selected {
|
||||
z-index: 1;
|
||||
z-index : 1;
|
||||
}
|
||||
|
||||
.ueb-selected>.ueb-node-border {
|
||||
@@ -228,118 +228,124 @@ ueb-node {
|
||||
linear-gradient(to bottom, #f1b000 0%, #cc6700 100%),
|
||||
linear-gradient(to right, #cc6700 0%, #cc6700 100%),
|
||||
linear-gradient(to bottom, #f1b000 0%, #cc6700 100%);
|
||||
background-size : 100% 7px, 7px 100%, 100% 7px, 7px 100%;
|
||||
background-position: top, right, bottom, left;
|
||||
background-repeat : repeat-x, repeat-y, repeat-x, repeat-y;
|
||||
outline : 3px solid #cc6700;
|
||||
outline-offset : -6px;
|
||||
background-size : 100% 7px, 7px 100%, 100% 7px, 7px 100%;
|
||||
background-position : top, right, bottom, left;
|
||||
background-repeat : repeat-x, repeat-y, repeat-x, repeat-y;
|
||||
outline : 3px solid #cc6700;
|
||||
outline-offset : -6px;
|
||||
}
|
||||
|
||||
.ueb-node-content {
|
||||
position : relative;
|
||||
padding : 1px;
|
||||
box-shadow : inset 0 0 2px 0 black;
|
||||
border-radius: var(--ueb-node-radius);
|
||||
background : rgba(0, 0, 0, 0.7);
|
||||
overflow : hidden;
|
||||
position : relative;
|
||||
padding : 1px;
|
||||
box-shadow : inset 0 0 2px 0 black;
|
||||
border-radius : var(--ueb-node-radius);
|
||||
background : rgba(0, 0, 0, 0.7);
|
||||
overflow : hidden;
|
||||
}
|
||||
|
||||
.ueb-node-header {
|
||||
padding : 0.2em 0.7em;
|
||||
box-shadow : inset 0 1px 2px 0 #313631, inset 0 2px 0 0 #92c381;
|
||||
border-radius: var(--ueb-node-radius) var(--ueb-node-radius) 0 0;
|
||||
background : linear-gradient(170deg, #5f815a 0%, #5f815a 50%, transparent 100%);
|
||||
color : #c0c0c0;
|
||||
font-weight : 600;
|
||||
white-space : nowrap;
|
||||
padding : 0.2em 0.7em;
|
||||
box-shadow : inset 0 1px 2px 0 #313631, inset 0 2px 0 0 #92c381;
|
||||
border-radius : var(--ueb-node-radius) var(--ueb-node-radius) 0 0;
|
||||
background : linear-gradient(170deg, #5f815a 0%, #5f815a 50%, transparent 100%);
|
||||
color : #c0c0c0;
|
||||
font-weight : 600;
|
||||
white-space : nowrap;
|
||||
}
|
||||
|
||||
.ueb-node-name {
|
||||
background: radial-gradient(closest-side, rgba(0, 0, 0, 0.5) 0%, transparent 90%);
|
||||
margin : -0.1em -1.6em;
|
||||
padding : 0.1em 1.6em;
|
||||
background : radial-gradient(closest-side, rgba(0, 0, 0, 0.5) 0%, transparent 90%);
|
||||
margin : -0.1em -1.6em;
|
||||
padding : 0.1em 1.6em;
|
||||
}
|
||||
|
||||
.ueb-node-body {
|
||||
display : flex;
|
||||
padding : 6px 0;
|
||||
color : white;
|
||||
font-weight: 100;
|
||||
white-space: nowrap;
|
||||
display : flex;
|
||||
padding : 6px 0;
|
||||
color : white;
|
||||
font-weight : 100;
|
||||
white-space : nowrap;
|
||||
}
|
||||
|
||||
.ueb-node-inputs {
|
||||
margin-right: auto;
|
||||
padding-left: 8px;
|
||||
margin-right : auto;
|
||||
padding-left : 8px;
|
||||
}
|
||||
|
||||
.ueb-node-outputs {
|
||||
padding-right: 8px;
|
||||
padding-right : 8px;
|
||||
}
|
||||
|
||||
ueb-pin {
|
||||
display: block;
|
||||
padding: 1px 2px;
|
||||
display : block;
|
||||
padding : 1px 2px;
|
||||
}
|
||||
|
||||
.ueb-grid[data-drag-scrolling="false"] {
|
||||
cursor: default;
|
||||
cursor : default;
|
||||
}
|
||||
|
||||
ueb-selector[data-selecting="false"]~ueb-node ueb-pin:hover {
|
||||
background: var(--ueb-node-value-background);
|
||||
}
|
||||
|
||||
.ueb-grid[data-drag-scrolling="false"] ueb-selector[data-selecting="false"]~ueb-node ueb-pin .ueb-node-value-icon {
|
||||
cursor: crosshair;
|
||||
.ueb-grid[data-drag-scrolling="false"] ueb-selector[data-selecting="false"]~ueb-node ueb-pin:hover {
|
||||
background : var(--ueb-node-value-background);
|
||||
cursor : crosshair;
|
||||
}
|
||||
|
||||
.ueb-node-value-icon {
|
||||
display : inline-block;
|
||||
position : relative;
|
||||
width : 0.85em;
|
||||
height : 0.85em;
|
||||
vertical-align: baseline;
|
||||
margin : 0 0.4em -1px 0.1em;
|
||||
display : inline-block;
|
||||
position : relative;
|
||||
width : 0.85em;
|
||||
height : 0.85em;
|
||||
vertical-align : baseline;
|
||||
margin : 0 0.4em -1px 0.1em;
|
||||
}
|
||||
|
||||
.ueb-node-value-icon::before {
|
||||
content : "";
|
||||
display : block;
|
||||
position : absolute;
|
||||
top : 0;
|
||||
right : 0;
|
||||
bottom : 0;
|
||||
left : 0;
|
||||
border : 2px solid var(--ueb-node-value-color);
|
||||
border-radius: 50%;
|
||||
content : "";
|
||||
display : block;
|
||||
position : absolute;
|
||||
top : 0;
|
||||
right : 0;
|
||||
bottom : 0;
|
||||
left : 0;
|
||||
border : 2px solid var(--ueb-node-value-color);
|
||||
border-radius : 50%;
|
||||
}
|
||||
|
||||
.ueb-node-value-fill::before {
|
||||
background: var(--ueb-node-value-color);
|
||||
background : var(--ueb-node-value-color);
|
||||
}
|
||||
|
||||
.ueb-node-value-icon::after {
|
||||
content : "";
|
||||
display : block;
|
||||
position : absolute;
|
||||
top : calc(50% - 0.3em);
|
||||
left : calc(100% + 1px);
|
||||
width : 0;
|
||||
height : 0;
|
||||
border-top : 0.3em solid transparent;
|
||||
border-bottom: 0.3em solid transparent;
|
||||
border-left : 0.3em solid var(--ueb-node-value-color);
|
||||
content : "";
|
||||
display : block;
|
||||
position : absolute;
|
||||
top : calc(50% - 0.3em);
|
||||
left : calc(100% + 1px);
|
||||
width : 0;
|
||||
height : 0;
|
||||
border-top : 0.3em solid transparent;
|
||||
border-bottom : 0.3em solid transparent;
|
||||
border-left : 0.3em solid var(--ueb-node-value-color);
|
||||
}
|
||||
|
||||
.ueb-selector {
|
||||
display : block;
|
||||
position : absolute;
|
||||
visibility: hidden;
|
||||
top : 0;
|
||||
left : 0;
|
||||
width : 0;
|
||||
height : 0;
|
||||
ueb-selector[data-selecting="true"],
|
||||
ueb-link {
|
||||
visibility : visible;
|
||||
top : min(var(--ueb-from-y) * 1px, var(--ueb-to-y) * 1px);
|
||||
left : min(var(--ueb-from-x) * 1px, var(--ueb-to-x) * 1px);
|
||||
width : calc(max(var(--ueb-from-x) - var(--ueb-to-x), var(--ueb-to-x) - var(--ueb-from-x)) * 1px);
|
||||
height : calc(max(var(--ueb-from-y) - var(--ueb-to-y), var(--ueb-to-y) - var(--ueb-from-y)) * 1px);
|
||||
}
|
||||
|
||||
ueb-selector {
|
||||
display : block;
|
||||
position : absolute;
|
||||
visibility : hidden;
|
||||
top : 0;
|
||||
left : 0;
|
||||
width : 0;
|
||||
height : 0;
|
||||
background-image:
|
||||
/* Top */
|
||||
repeating-linear-gradient(90deg,
|
||||
@@ -415,17 +421,15 @@ ueb-selector[data-selecting="false"]~ueb-node ueb-pin:hover {
|
||||
calc(1px / var(--ueb-scale)) 0, 0 0,
|
||||
/* Right */
|
||||
calc(100% - 1px / var(--ueb-scale)) 0, 100% 0;
|
||||
background-repeat: no-repeat;
|
||||
background-repeat : no-repeat;
|
||||
}
|
||||
|
||||
ueb-selector>* {
|
||||
visibility: visible;
|
||||
visibility : visible;
|
||||
}
|
||||
|
||||
ueb-selector[data-selecting="true"] {
|
||||
visibility: visible;
|
||||
top : min(var(--ueb-select-from-y) * 1px, var(--ueb-select-to-y) * 1px);
|
||||
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);
|
||||
ueb-link {
|
||||
display : block;
|
||||
position : absolute;
|
||||
border : 2px solid red;
|
||||
}
|
||||
Reference in New Issue
Block a user