diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..40b878d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+node_modules/
\ No newline at end of file
diff --git a/css/ueblueprint-style.css b/css/ueblueprint-style.css
index 4484390..6f938d3 100644
--- a/css/ueblueprint-style.css
+++ b/css/ueblueprint-style.css
@@ -14,14 +14,15 @@
url('../font/roboto-regular.woff') format('woff');
}
-.ueb {
+u-blueprint {
+ display : block;
position : relative;
font-family: Roboto, Noto, Oxygen, Ubuntu, 'Open Sans', 'Helvetica Neue', sans-serif;
font-size : var(--ueb-fron-size);
}
.ueb-viewport-header {
- display : flexbox;
+ display : flex;
position : absolute;
top : 0;
right : 0;
@@ -32,7 +33,6 @@
}
.ueb-viewport-zoom {
- float: right;
color: #4d4d4db7;
}
@@ -175,6 +175,7 @@
}
.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);
diff --git a/js/UEBlueprint.js b/js/UEBlueprint.js
index 6ed429c..e8549bd 100644
--- a/js/UEBlueprint.js
+++ b/js/UEBlueprint.js
@@ -1,25 +1,35 @@
-import UEBlueprintDOMModel from "./UEBlueprintDOMModel.js"
import UEBlueprintDragScroll from "./UEBlueprintDragScroll.js"
-export default class UEBlueprint extends UEBlueprintDOMModel {
+export default class UEBlueprint extends HTMLElement {
- static domTemplate(obj) {
+ header() {
return `
-
-
-
-
-
-
- ${obj.nodes.forEach(node => node.getDOMElement()) ?? ''}
+
-
-
-
-`
+ `
+ }
+
+ overlay() {
+ return `
+
+ `
+ }
+
+ viewport() {
+ return `
+
+ `
+ }
+
+ insertChildren() {
+ this.querySelector('[data-nodes]').append(...this.nodes)
}
static clamp(val, min, max) {
@@ -28,49 +38,60 @@ export default class UEBlueprint extends UEBlueprintDOMModel {
constructor() {
super()
+ this.nodes = new Set()
this.expandGridSize = 400
- this.gridDOMElement = null
+ this.gridElement = null
+ this.viewportElement = null
+ this.overlayElement = null
this.dragObject = null
this.additional = /*[2 * this.expandGridSize, 2 * this.expandGridSize]*/[0, 0]
this.translateValue = /*[this.expandGridSize, this.expandGridSize]*/[0, 0]
this.zoom = 0
- this.nodes = []
+ this.headerElement = null
}
- createDOMElement() {
- super.createDOMElement()
- this.gridDOMElement = this.domElement.querySelector('.ueb-grid')
- let contentElement = this.domElement.querySelector('.ueb-grid-content')
- if (!this.gridDOMElement || !contentElement) {
- console.error('Some expencted DOM elements not be found, please check domTemplate().')
- }
- // Populate the grid content with the node elements
- this.nodes.forEach(node => {
- contentElement.appendChild(node.getDOMElement())
- })
+ connectedCallback() {
+ this.classList.add('ueb', `ueb-zoom-${this.zoom}`)
+ let aDiv = document.createElement('div');
+ // Add header
+ aDiv.innerHTML = this.header()
+ this.headerElement = aDiv.firstElementChild
+ this.appendChild(this.headerElement)
+
+ // Add overlay
+ aDiv.innerHTML = this.overlay()
+ this.overlayElement = aDiv.firstElementChild
+ this.appendChild(this.overlayElement)
+
+ // Add viewport
+ aDiv.innerHTML = this.viewport()
+ this.viewportElement = aDiv.firstElementChild
+ this.appendChild(this.viewportElement)
+
+ this.gridElement = this.viewportElement.querySelector('.ueb-grid')
+ this.insertChildren()
+
this.dragObject = new UEBlueprintDragScroll(this, {
'clickButton': 2,
'stepSize': 1
})
}
- removeDOMElement() {
- if (this.domElement) {
- this.dragObject.unlistenDOMElement()
- }
- return super.removeDOMElement()
+ getGridDOMElement() {
+ return this.gridElement
}
- getGridDOMElement() {
- return this.gridDOMElement
+ disconnectedCallback() {
+ super.disconnectedCallback()
+ this.dragObject.unlistenDOMElement()
}
setScroll(value, smooth = false) {
this.scroll = value
if (!smooth) {
- this.gridDOMElement.parentElement.scroll(value[0], value[1])
+ this.viewportElement.scroll(value[0], value[1])
} else {
- this.gridDOMElement.parentElement.scroll({
+ this.viewportElement.scroll({
left: value[0],
top: value[1],
behavior: 'smooth'
@@ -115,8 +136,7 @@ export default class UEBlueprint extends UEBlueprintDOMModel {
}
getScroll() {
- let parentElement = this.gridDOMElement.parentElement
- return [parentElement.scrollLeft, parentElement.scrollTop]
+ return [this.viewportElement.scrollLeft, this.viewportElement.scrollTop]
}
scrollCenter() {
@@ -138,10 +158,9 @@ export default class UEBlueprint extends UEBlueprintDOMModel {
}
getViewportSize() {
- let parentElement = this.gridDOMElement.parentElement
return [
- parentElement.clientWidth,
- parentElement.clientHeight
+ this.viewportElement.clientWidth,
+ this.viewportElement.clientHeight
]
}
@@ -150,10 +169,9 @@ export default class UEBlueprint extends UEBlueprintDOMModel {
* @return {array} The horizonal and vertical maximum scroll limits
*/
getScrollMax() {
- let parentElement = this.gridDOMElement.parentElement
return [
- parentElement.scrollWidth - parentElement.clientWidth,
- parentElement.scrollHeight - parentElement.clientHeight
+ this.viewportElement.scrollWidth - this.viewportElement.clientWidth,
+ this.viewportElement.scrollHeight - this.viewportElement.clientHeight
]
}
@@ -166,9 +184,9 @@ export default class UEBlueprint extends UEBlueprintDOMModel {
x = Math.round(Math.abs(x))
y = Math.round(Math.abs(y))
this.additional = [this.additional[0] + x, this.additional[1] + y]
- if (this.gridDOMElement) {
- this.gridDOMElement.style.setProperty('--ueb-additional-x', this.additional[0])
- this.gridDOMElement.style.setProperty('--ueb-additional-y', this.additional[1])
+ if (this.gridElement) {
+ this.gridElement.style.setProperty('--ueb-additional-x', this.additional[0])
+ this.gridElement.style.setProperty('--ueb-additional-y', this.additional[1])
}
}
@@ -181,9 +199,9 @@ export default class UEBlueprint extends UEBlueprintDOMModel {
x = Math.round(x)
y = Math.round(y)
this.translateValue = [this.translateValue[0] + x, this.translateValue[1] + y]
- if (this.gridDOMElement) {
- this.gridDOMElement.style.setProperty('--ueb-translate-x', this.translateValue[0])
- this.gridDOMElement.style.setProperty('--ueb-translate-y', this.translateValue[1])
+ if (this.gridElement) {
+ this.gridElement.style.setProperty('--ueb-translate-x', this.translateValue[0])
+ this.gridElement.style.setProperty('--ueb-translate-y', this.translateValue[1])
}
}
@@ -201,10 +219,10 @@ export default class UEBlueprint extends UEBlueprintDOMModel {
// If the expansion is towards the left or top, then scroll back to give the illusion that the content is in the same position and translate it accordingly
this._translate(scaledX < 0 ? -scaledX : 0, scaledY < 0 ? -scaledY : 0)
if (x < 0) {
- this.gridDOMElement.parentElement.scrollLeft -= x
+ this.viewportElement.scrollLeft -= x
}
if (y < 0) {
- this.gridDOMElement.parentElement.scrollTop -= y
+ this.viewportElement.scrollTop -= y
}
}
@@ -222,8 +240,8 @@ export default class UEBlueprint extends UEBlueprintDOMModel {
return
}
let initialScale = this.getScale()
- this.domElement.classList.add(`ueb-zoom-${zoom}`)
- this.domElement.classList.remove(`ueb-zoom-${this.zoom}`)
+ this.classList.add(`ueb-zoom-${zoom}`)
+ this.classList.remove(`ueb-zoom-${this.zoom}`)
this.zoom = zoom
if (center) {
let relativeScale = this.getScale() / initialScale
@@ -239,10 +257,16 @@ export default class UEBlueprint extends UEBlueprintDOMModel {
}
getScale() {
- return parseFloat(getComputedStyle(this.gridDOMElement).getPropertyValue('--ueb-grid-scale'))
+ return parseFloat(getComputedStyle(this.gridElement).getPropertyValue('--ueb-grid-scale'))
}
- addNode(...blueprintNode) {
- this.nodes.push(...blueprintNode)
+ addNode(...blueprintNodes) {
+ [...blueprintNodes].reduce((s, e) => s.add(e), this.nodes)
+ let nodesDestination = this.querySelector('[data-nodes]')
+ if (nodesDestination) {
+ nodesDestination.append(...blueprintNodes)
+ }
}
}
+
+customElements.define('u-blueprint', UEBlueprint)
diff --git a/js/UEBlueprintDOMModel.js b/js/UEBlueprintDOMModel.js
deleted file mode 100644
index b1e7df9..0000000
--- a/js/UEBlueprintDOMModel.js
+++ /dev/null
@@ -1,35 +0,0 @@
-export default class UEBlueprintDOMModel {
- static dummyDiv = document.createElement('div')
-
- static domTemplate(obj) {
- return ``
- }
-
- constructor() {
- this.domElement = null
- }
-
- createDOMElement() {
- if (this.domElement) {
- this.removeDOMElement()
- }
- this.constructor.dummyDiv.innerHTML = this.constructor.domTemplate(this)
- this.domElement = this.constructor.dummyDiv.removeChild(this.constructor.dummyDiv.firstElementChild)
- }
-
- getDOMElement() {
- if (!this.domElement) {
- this.createDOMElement()
- }
- return this.domElement
- }
-
- removeDOMElement() {
- if (!this.domElement) {
- return false
- }
- this.domElement.parentElement.removeChild(this.domElement)
- this.domElement = null
- return true
- }
-}
diff --git a/js/UEBlueprintDrag.js b/js/UEBlueprintDrag.js
index 0cbcac4..22dd480 100644
--- a/js/UEBlueprintDrag.js
+++ b/js/UEBlueprintDrag.js
@@ -1,6 +1,6 @@
export default class UEBlueprintDrag {
- constructor(draggedNode, options) {
- this.blueprintNode = draggedNode;
+ constructor(blueprintNode, options) {
+ this.blueprintNode = blueprintNode;
this.mousePosition = [0, 0];
this.stepSize = options?.stepSize
this.clickButton = options?.clickButton ?? 0
@@ -38,17 +38,13 @@ export default class UEBlueprintDrag {
document.removeEventListener('mouseup', self.mouseUpHandler)
}
};
- let element = this.blueprintNode.getDOMElement()
+ let element = this.blueprintNode
element.addEventListener('mousedown', this.mouseDownHandler)
element.addEventListener('contextmenu', e => e.preventDefault())
}
unlistenDOMElement() {
- if (this.blueprintNode) {
- this.blueprintNode.getDOMElement().removeEventListener('mousedown', this.mouseDownHandler)
- return true
- }
- return false
+ this.blueprintNode.removeEventListener('mousedown', this.mouseDownHandler)
}
snapToGrid(posX, posY) {
@@ -60,7 +56,7 @@ export default class UEBlueprintDrag {
clicked(x, y) {
if (!this.stepSize) {
- this.stepSize = parseInt(getComputedStyle(this.blueprintNode.getDOMElement()).getPropertyValue('--ueb-grid-snap'))
+ this.stepSize = parseInt(getComputedStyle(this.blueprintNode).getPropertyValue('--ueb-grid-snap'))
}
// Get the current mouse position
this.mousePosition = this.snapToGrid(x, y)
diff --git a/js/UEBlueprintDragScroll.js b/js/UEBlueprintDragScroll.js
index 52ac390..e272f32 100644
--- a/js/UEBlueprintDragScroll.js
+++ b/js/UEBlueprintDragScroll.js
@@ -3,7 +3,6 @@ import UEBlueprintDrag from "./UEBlueprintDrag.js"
export default class UEBlueprintDragScroll extends UEBlueprintDrag {
constructor(scrolledEntity, options) {
super(scrolledEntity, options)
- this.scrolledDOMElement = scrolledEntity.getGridDOMElement()
this.minZoom = options?.minZoom ?? -12
let self = this;
this.mouseMoveHandler = function (e) {
diff --git a/js/UEBlueprintDraggableObject.js b/js/UEBlueprintDraggableObject.js
index 9b2d9a9..be25242 100644
--- a/js/UEBlueprintDraggableObject.js
+++ b/js/UEBlueprintDraggableObject.js
@@ -1,7 +1,6 @@
-import UEBlueprintDOMModel from "./UEBlueprintDOMModel.js"
import UEBlueprintDrag from "./UEBlueprintDrag.js"
-export default class UEBlueprintDraggableObject extends UEBlueprintDOMModel {
+export default class UEBlueprintDraggableObject extends HTMLElement {
constructor() {
super()
@@ -9,24 +8,18 @@ export default class UEBlueprintDraggableObject extends UEBlueprintDOMModel {
this.location = [0, 0]
}
- createDOMElement() {
- super.createDOMElement()
+ connectedCallback() {
this.dragObject = new UEBlueprintDrag(this)
}
- removeDOMElement() {
- if (this.domElement) {
- this.dragObject.unlistenDOMElement()
- }
- return super.removeDOMElement()
+ disconnectedCallback() {
+ this.dragObject.unlistenDOMElement()
}
setLocation(value = [0, 0]) {
this.location = value
- if (this.domElement) {
- this.domElement.style.setProperty('--ueb-position-x', this.location[0])
- this.domElement.style.setProperty('--ueb-position-y', this.location[1])
- }
+ this.style.setProperty('--ueb-position-x', this.location[0])
+ this.style.setProperty('--ueb-position-y', this.location[1])
}
addLocation(value) {
diff --git a/js/UEBlueprintObject.js b/js/UEBlueprintObject.js
index 65819bc..cd16b03 100644
--- a/js/UEBlueprintObject.js
+++ b/js/UEBlueprintObject.js
@@ -16,39 +16,49 @@ export default class UEBlueprintObject extends UEBlueprintDraggableObject {
static classInFlow = false
static classOutFlow = false
static className = 'Empty node'
- static domTemplate(obj) {
+
+ header() {
return `
-
-
-
+ `
+ }
+
+ body() {
+ return `
- ${obj.constructor.classOutputs.forEach((output, index) => `
+ ${this.constructor.classOutputs.forEach((output, index) => `
${output.name}
-
+
`) ?? ''}
-
-
-
+ `
+ }
+
+ render() {
+ return `
+
+
+ ${this.header()}
+ ${this.body()}
+
+
`
}
@@ -67,6 +77,20 @@ export default class UEBlueprintObject extends UEBlueprintDraggableObject {
})
}
+ connectedCallback() {
+ super.connectedCallback()
+ this.classList.add('ueb-node')
+ if (this.selected) {
+ this.classList.add('ueb-selected')
+ }
+ this.style.setProperty('--ueb-position-x', this.location[0])
+ this.style.setProperty('--ueb-position-y', this.location[1])
+
+ let aDiv = document.createElement('div');
+ aDiv.innerHTML = this.render()
+ this.appendChild(aDiv.firstElementChild)
+ }
+
isSelected() {
return this.selected
}
@@ -75,3 +99,5 @@ export default class UEBlueprintObject extends UEBlueprintDraggableObject {
this.selected = value
}
}
+
+customElements.define('u-object', UEBlueprintObject)
diff --git a/js/exporting.js b/js/exporting.js
new file mode 100644
index 0000000..0fd202d
--- /dev/null
+++ b/js/exporting.js
@@ -0,0 +1,4 @@
+import UEBlueprint from "./UEBlueprint"
+import UEBlueprintObject from "./UEBlueprintObject"
+
+export { UEBlueprint, UEBlueprintObject }
\ No newline at end of file
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..48cd031
--- /dev/null
+++ b/package.json
@@ -0,0 +1,26 @@
+{
+ "name": "ueblueprint",
+ "version": "1.0.0",
+ "description": "Unreal Engine's Blueprint visualisation library",
+ "main": "index.js",
+ "scripts": {
+ "build": "rollup --config"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/barsdeveloper/ueblueprint.git"
+ },
+ "keywords": [
+ "unreal",
+ "engine",
+ "blueprint"
+ ],
+ "author": "barsdeveloper",
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/barsdeveloper/ueblueprint/issues"
+ },
+ "homepage": "https://github.com/barsdeveloper/ueblueprint#readme",
+ "dependencies": {},
+ "devDependencies": {}
+}
\ No newline at end of file
diff --git a/rollup.config.js b/rollup.config.js
new file mode 100644
index 0000000..aeb3388
--- /dev/null
+++ b/rollup.config.js
@@ -0,0 +1,7 @@
+export default {
+ input: 'js/exporting.js',
+ output: {
+ file: 'ueblueprint.js',
+ format: 'es',
+ },
+};
\ No newline at end of file
diff --git a/ueblueprint.html b/ueblueprint.html
index 25ff8eb..fd30c8c 100644
--- a/ueblueprint.html
+++ b/ueblueprint.html
@@ -22,20 +22,18 @@
--ueb-grid-snap: 16px;
}
-
+
Hello