Initial commit

This commit is contained in:
barsdeveloper
2021-06-29 16:26:39 +02:00
commit 02e8e6e8af
18 changed files with 811 additions and 0 deletions

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 barsdeveloper
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

2
README.md Normal file
View File

@@ -0,0 +1,2 @@
# ueblueprint
Unreal Engine's Blueprint visualisation library

View File

@@ -0,0 +1,9 @@
.ueb-draggable,
.ueb-node {
/* Indicate the element draggable */
cursor : move;
/* It will be positioned absolutely */
position : absolute;
/* Doesn't allow to select the content inside */
user-select: none;
}

View File

@@ -0,0 +1,35 @@
.ueb {
--ueb-node-value-color: white;
}
.ueb-node-value-boolean {
--ueb-node-value-color: #930000;
}
.ueb-node-value-integer {
--ueb-node-value-color: #1fe0ad;
}
.ueb-node-value-float {
--ueb-node-value-color: #9ffb44;
}
.ueb-node-value-vector {
--ueb-node-value-color: #fcc823;
}
.ueb-node-value-rotator {
--ueb-node-value-color: #9eb1fc;
}
.ueb-node-value-string {
--ueb-node-value-color: #fc00d2;
}
.ueb-node-value-name {
--ueb-node-value-color: #cb81fc;
}
.ueb-node-value-objectreference {
--ueb-node-value-color: #00a8f2;
}

274
css/ueblueprint-style.css Normal file
View File

@@ -0,0 +1,274 @@
@font-face {
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 :
url('../font/roboto-regular.woff2') format('woff2'),
url('../font/roboto-regular.woff') format('woff');
}
.ueb {
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;
position : absolute;
top : 0;
right : 0;
left : 0;
height : 1.5em;
background: rgba(0, 0, 0, 0.5);
z-index : 1;
}
.ueb-viewport-zoom {
float: right;
color: #4d4d4db7;
}
.ueb-viewport-body {
position : relative;
height : var(--ueb-viewport-height);
width : var(--ueb-viewport-width);
overflow : scroll;
scrollbar-width: 0;
}
.ueb-grid {
--ueb-grid-line-actual-width: calc(var(--ueb-grid-line-width) / var(--ueb-grid-scale));
position : absolute;
min-width : 100%;
min-height : 100%;
width : calc(100% + var(--ueb-additional-x) * 1px);
height : calc(100% + var(--ueb-additional-y) * 1px);
background-color : #262626;
background-image :
/* Axis lines */
linear-gradient(var(--ueb-grid-axis-line-color), var(--ueb-grid-axis-line-color)),
linear-gradient(var(--ueb-grid-axis-line-color), var(--ueb-grid-axis-line-color)),
/* Dark bigger grid */
linear-gradient(to right,
var(--ueb-grid-set-line-color),
var(--ueb-grid-set-line-color) var(--ueb-grid-line-actual-width),
transparent var(--ueb-grid-line-actual-width),
transparent),
linear-gradient(to bottom,
var(--ueb-grid-set-line-color),
var(--ueb-grid-set-line-color) var(--ueb-grid-line-actual-width),
transparent var(--ueb-grid-line-actual-width),
transparent),
/* Light grid */
linear-gradient(to right,
var(--ueb-grid-line-color),
var(--ueb-grid-line-color) var(--ueb-grid-line-actual-width),
transparent var(--ueb-grid-line-actual-width),
transparent),
linear-gradient(to bottom,
var(--ueb-grid-line-color),
var(--ueb-grid-line-color)var(--ueb-grid-line-actual-width),
transparent var(--ueb-grid-line-actual-width),
transparent);
background-size:
/* Axis lines */
100% var(--ueb-grid-line-actual-width),
var(--ueb-grid-line-actual-width) 100%,
/* Dark bigger grid */
calc(var(--ueb-grid-set) * var(--ueb-grid-actual-size)) calc(var(--ueb-grid-set) * var(--ueb-grid-actual-size)),
calc(var(--ueb-grid-set) * var(--ueb-grid-actual-size)) calc(var(--ueb-grid-set) * var(--ueb-grid-actual-size)),
/* 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-grid-scale), var(--ueb-grid-scale));
transform-origin : 0 0;
overflow : hidden;
}
.ueb-zoom--.ueb,
.ueb {
/* 16/16 */
--ueb-grid-scale : 1;
--ueb-grid-actual-size: var(--ueb-grid-size);
}
.ueb-zoom--1.ueb {
/* 14/16 */
--ueb-grid-scale: 0.875
}
.ueb-zoom--2.ueb {
/* 12/16 */
--ueb-grid-scale: 0.75
}
.ueb-zoom--3.ueb {
/* 10.8/16 */
--ueb-grid-scale: 0.675
}
.ueb-zoom--4.ueb {
/* 8/16 */
--ueb-grid-scale : 0.5;
--ueb-grid-actual-size: calc(var(--ueb-grid-size) * 2)
}
.ueb-zoom--5.ueb {
/* 6/16 */
--ueb-grid-scale : 0.375;
--ueb-grid-actual-size: calc(var(--ueb-grid-size) * 2);
}
.ueb-zoom--6.ueb {
--ueb-grid-scale : 0.333333;
--ueb-grid-actual-size: calc(var(--ueb-grid-size) * 3);
}
.ueb-zoom--7.ueb {
--ueb-grid-scale : 0.3;
--ueb-grid-actual-size: calc(var(--ueb-grid-size) * 3);
}
.ueb-zoom--8.ueb {
--ueb-grid-scale : 0.266666;
--ueb-grid-actual-size: calc(var(--ueb-grid-size) * 3);
}
.ueb-zoom--9.ueb {
--ueb-grid-scale : 0.233333;
--ueb-grid-actual-size: calc(var(--ueb-grid-size) * 3);
}
.ueb-zoom--10.ueb {
/* 12/16 */
--ueb-grid-scale : 0.2;
--ueb-grid-actual-size: calc(var(--ueb-grid-size) * 3);
}
.ueb-zoom--11.ueb {
/* 12/16 */
--ueb-grid-scale : 0.166666;
--ueb-grid-actual-size: calc(var(--ueb-grid-size) * 6);
}
.ueb-zoom--12.ueb {
/* 12/16 */
--ueb-grid-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))
}
.ueb-node {
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-node-border {
margin : -3px;
padding : 3px;
border-radius: calc(var(--ueb-node-radius) * 1.4);
}
.ueb-selected>.ueb-node-border {
background-image:
linear-gradient(to right, #f1b000 0%, #f1b000 100%),
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;
}
.ueb-node-content {
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;
}
.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;
}
.ueb-node-body {
display : flex;
padding : 0.6em 0.8em;
color : white;
font-weight: 100;
white-space: nowrap;
}
.ueb-node-inputs {
margin-right: 2em;
}
.ueb-node-value-icon {
display : inline-block;
position : relative;
width : 0.85em;
height : 0.85em;
vertical-align: baseline;
margin : 0 0.4em -1px 0.3em;
}
.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%;
}
.ueb-node-value-fill::before {
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);
}

BIN
font/roboto-bold.woff Normal file

Binary file not shown.

BIN
font/roboto-bold.woff2 Normal file

Binary file not shown.

BIN
font/roboto-light.woff Normal file

Binary file not shown.

BIN
font/roboto-light.woff2 Normal file

Binary file not shown.

BIN
font/roboto-regular.woff Normal file

Binary file not shown.

BIN
font/roboto-regular.woff2 Normal file

Binary file not shown.

35
js/UEBlueprintDOMModel.js Normal file
View File

@@ -0,0 +1,35 @@
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
}
}

69
js/UEBlueprintDrag.js Normal file
View File

@@ -0,0 +1,69 @@
export default class UEBlueprintDrag {
constructor(draggedNode, options) {
this.blueprintNode = draggedNode;
this.mousePosition = [0, 0];
this.stepSize = 1
this.clickButton = options?.clickButton ?? 0
this.exitGrabSameButtonOnly = options?.exitGrabSameButtonOnly ?? false
let self = this;
this.mouseDownHandler = function (e) {
switch (e.button) {
case self.clickButton:
self.clicked(e.clientX, e.clientY)
break;
default:
if (!self.exitGrabSameButtonOnly) {
self.mouseUpHandler(e)
}
break;
}
};
this.mouseMoveHandler = function (e) {
let mousePosition = self.snapToGrid(e.clientX, e.clientY)
const d = [mousePosition[0] - self.mousePosition[0], mousePosition[1] - self.mousePosition[1]]
if (d[0] == 0 && d[1] == 0) {
return;
}
self.blueprintNode.addLocation(d)
// Reassign the position of mouse
self.mousePosition = mousePosition
};
this.mouseUpHandler = function (e) {
if (!self.exitGrabSameButtonOnly || e.button == self.clickButton) {
// Remove the handlers of `mousemove` and `mouseup`
document.removeEventListener('mousemove', self.mouseMoveHandler)
document.removeEventListener('mouseup', self.mouseUpHandler)
}
};
let element = this.blueprintNode.getDOMElement()
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
}
snapToGrid(posX, posY) {
return [
this.stepSize * Math.round(posX / this.stepSize),
this.stepSize * Math.round(posY / this.stepSize)
]
}
clicked(x, y) {
// Get the current mouse position
this.mousePosition = this.snapToGrid(x, y)
this.stepSize = parseInt(getComputedStyle(this.blueprintNode.getDOMElement()).getPropertyValue('--ueb-grid-snap'))
// Attach the listeners to `document`
document.addEventListener('mousemove', this.mouseMoveHandler)
document.addEventListener('mouseup', this.mouseUpHandler)
}
}

View File

@@ -0,0 +1,78 @@
import UEBlueprintDrag from "./UEBlueprintDrag.js"
export default class UEBlueprintDragScroll extends UEBlueprintDrag {
constructor(scrolledEntity, options) {
super(scrolledEntity, options)
this.scrolledDOMElement = scrolledEntity.getGridDOMElement()
this.expandGridSize = options?.expandGridSize ?? 200
this.initialExpandGridSize = this.expandGridSize
this.minZoom = options?.minZoom ?? -12
let self = this;
this.mouseMoveHandler = function (e) {
const scrollMaxX = self.scrolledDOMElement.parentElement.scrollWidth - self.scrolledDOMElement.parentElement.clientWidth
const scrollMaxY = self.scrolledDOMElement.parentElement.scrollHeight - self.scrolledDOMElement.parentElement.clientHeight
let expandX = self.scrolledDOMElement.parentElement.scrollLeft < self.expandGridSize * 0.5 ? -1 : 0
+ self.scrolledDOMElement.parentElement.scrollLeft > scrollMaxX - self.expandGridSize * 0.5 ? 1 : 0
let expandY = self.scrolledDOMElement.parentElement.scrollTop < self.expandGridSize * 0.5 ? -1 : 0
+ self.scrolledDOMElement.parentElement.scrollTop > scrollMaxY - self.expandGridSize * 0.5 ? 1 : 0
if (expandX != 0 || expandY != 0) {
/* Managining infinite scrolling: when the scrollbar reaches the end, the grid is expanded and the elements inside translated to give the illusion that they stayed in the same position*/
self.expandAndTranslate(expandX * self.expandGridSize, expandY * self.expandGridSize)
}
let mousePosition = self.snapToGrid(e.clientX, e.clientY)
// How far the mouse has been moved
const dx = mousePosition[0] - self.mousePosition[0]
const dy = mousePosition[1] - self.mousePosition[1]
self.scrolledDOMElement.parentElement.scrollLeft = self.scrolledDOMElement.parentElement.scrollLeft - dx
self.scrolledDOMElement.parentElement.scrollTop = self.scrolledDOMElement.parentElement.scrollTop - dy
// Reassign the position of mouse
self.mousePosition = mousePosition
};
this.mouseWheelHandler = function (e) {
let blueprintRoot = self.elem.parentElement.parentElement
let zoomLevel = 0
let zoomLevelClass = "ueb-zoom-0"
let classes = blueprintRoot.classList.values()
for (let className of classes) {
let v = className.match(/ueb\-zoom\-(\-?\d+)/)
if (v) {
zoomLevelClass = v[0]
zoomLevel = parseInt(v[1])
break
}
}
zoomLevel -= Math.round(e.deltaY / 50)
zoomLevel = self.clamp(zoomLevel, -12, 0)
blueprintRoot.classList.remove(zoomLevelClass)
blueprintRoot.classList.add("ueb-zoom-" + zoomLevel)
let scale = blueprintNode.getScale()
let additionalX = Math.ceil(self.scrolledDOMElement.clientWidth * (1 - 1 / scale))
let additionalY = Math.ceil(self.scrolledDOMElement.clientHeight * (1 - 1 / scale))
self.blueprintNode.expand(additionalX, additionalY)
}
this.blueprintNode.getGridDOMElement().addEventListener('wheel', this.mouseWheelHandler)
this.blueprintNode.getGridDOMElement().addEventListener('wheel', e => e.preventDefault())
this.blueprintNode.getGridDOMElement().parentElement.addEventListener('wheel', e => e.preventDefault())
}
expandAndTranslate(x, y) {
this.blueprintNode.expand(x, y)
this.blueprintNode.translate(-x, -y)
}
scaledExpand(x, y, scale) {
}
clamp(val, min, max) {
return Math.min(Math.max(val, min), max);
}
}

View File

@@ -0,0 +1,40 @@
import UEBlueprintDOMModel from "./UEBlueprintDOMModel.js"
import UEBlueprintDrag from "./UEBlueprintDrag.js"
export default class UEBlueprintDraggableObject extends UEBlueprintDOMModel {
constructor() {
super()
this.dragObject = null
this.location = [0, 0]
}
createDOMElement() {
super.createDOMElement()
this.dragObject = new UEBlueprintDrag(this)
}
removeDOMElement() {
if (this.domElement) {
this.dragObject.unlistenDOMElement()
}
return super.removeDOMElement()
}
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])
}
}
addLocation(value) {
this.setLocation([this.location[0] + value[0], this.location[1] + value[1]])
}
getLocation() {
return this.location
}
}

77
js/UEBlueprintObject.js Normal file
View File

@@ -0,0 +1,77 @@
import UEBlueprintDraggableObject from "./UEBlueprintDraggableObject.js"
export default class UEBlueprintObject extends UEBlueprintDraggableObject {
static classInputs = [/*
{
name: "Input Example",
type: 'integer'
}
*/]
static classOutputs = [/*
{
name: "Return Value",
type: 'string'
}*/
]
static classInFlow = false
static classOutFlow = false
static className = 'Empty node'
static domTemplate(obj) {
return `
<div class="ueb-node ${obj.selected ? 'ueb-selected' : ''}"
style="--ueb-position-x:${obj.location[0]}; --ueb-position-y:${obj.location[1]}">
<div class="ueb-node-border">
<div class="ueb-node-content">
<div class="ueb-node-header">
<span class="ueb-node-name">
<span class="ueb-node-symbol"></span>
<span class="ueb-node-text">${obj.constructor.className}</span>
</span>
</div>
<div class="ueb-node-body">
<div class="ueb-node-inputs">
${obj.constructor.classInputs.forEach((input, index) => `
<div class="ueb-node-input ueb-node-value-${input.type}">
<span class="ueb-node-value-icon ${obj.inputs[index].connected ? 'ueb-node-value-fill' : ''}"></span>
${input.name}
</div>
`) ?? ''}
</div>
<div class="ueb-node-outputs">
${obj.constructor.classOutputs.forEach((output, index) => `
<div class="ueb-node-output ueb-node-value-${output.type}">
${output.name}
<span class="ueb-node-value-icon ${obj.outputs[index].connected ? 'ueb-node-value-fill' : ''}"></span>
</div>
`) ?? ''}
</div>
</div>
</div>
</div>
</div>
`
}
constructor() {
super()
this.selected = false
this.inputs = this.constructor.classInputs.map(value => {
return {
connected: null
}
})
this.outputs = this.constructor.classOutputs.map(value => {
return {
connected: null
}
})
}
isSelected() {
return this.selected
}
setSelected(value = true) {
this.selected = value
}
}

103
js/ueblueprint.js Normal file
View File

@@ -0,0 +1,103 @@
import UEBlueprintDOMModel from "./UEBlueprintDOMModel.js";
import UEBlueprintDragScroll from "./UEBlueprintDragScroll.js";
export default class UEBlueprint extends UEBlueprintDOMModel {
static domTemplate(obj) {
return `
<div class="ueb" style="--ueb-grid-scale:${obj.scale}">
<div class="ueb-viewport-header">
<div class="ueb-viewport-zoom">1:1</div>
</div>
<div class="ueb-viewport-overlay"></div>
<div class="ueb-viewport-body">
<div class="ueb-grid"
style="--ueb-additional-x:${obj.additional[0]}; --ueb-additional-y:${obj.additional[1]}; --ueb-translate-x:${obj.translate[0]}; --ueb-translate-y:${obj.translate[1]}">
<div class="ueb-grid-content">
${obj.nodes.forEach(node => node.getDOMElement()) ?? ''}
</div>
</div>
</div>
</div>
`
}
constructor() {
super()
this.gridDOMElement = null
this.dragObject = null
this.additional = [0, 0]
this.translateValue = [0, 0]
this.scale = 1
this.nodes = []
}
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())
})
this.dragObject = new UEBlueprintDragScroll(this, {
'clickButton': 2
})
}
removeDOMElement() {
if (this.domElement) {
this.dragObject.unlistenDOMElement()
}
return super.removeDOMElement()
}
getGridDOMElement() {
return this.gridDOMElement
}
setScroll(value = [0, 0]) {
this.scroll = value
}
addScroll(value) {
this.setLocation([this.scroll[0] + value[0], this.scroll[1] + value[1]])
}
getScroll() {
return this.scroll
}
expand(x, y) {
x = Math.round(x)
y = Math.round(y)
this.additional = [this.additional[0] + Math.abs(x), this.additional[1] + Math.abs(y)]
if (this.domElement) {
this.domElement.style.setProperty('--ueb-additional-x', this.additional[0])
this.domElement.style.setProperty('--ueb-additional-y', this.additional[1])
this.domElement.parentElement.scrollLeft -= x
this.domElement.parentElement.scrollTop -= y
}
}
translate(x, y) {
x = Math.round(x)
y = Math.round(y)
this.translateValue = [this.translateValue[0] + x, this.translateValue[1] + y]
if (this.domElement) {
this.domElement.style.setProperty('--ueb-translate-x', this.translateValue[0])
this.domElement.style.setProperty('--ueb-translate-y', this.translateValue[1])
}
}
getScale() {
return this.scale
}
addNode(...blueprintNode) {
this.nodes.push(...blueprintNode)
}
}

68
ueblueprint.html Normal file
View File

@@ -0,0 +1,68 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<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-style.css">
<link rel="stylesheet" href="css/ueblueprint-node-value-type-color.css">
</head>
<body>
<div>Hello</div>
<script type="module">
import UEBlueprintObject from "./js/UEBlueprintObject.js"
import UEBlueprint from "./js/UEBlueprint.js"
let node1 = new UEBlueprintObject()
node1.addLocation([100, 100])
let blueprint = new UEBlueprint()
blueprint.addNode(node1)
document.querySelector('body').appendChild(blueprint.getDOMElement())
</script>
<script type="module">
/*
document.addEventListener("DOMContentLoaded", function (event) {
let leftmost = Number.MAX_SAFE_INTEGER;
let topmost = Number.MAX_SAFE_INTEGER;
let draggableElements = document.querySelectorAll('.ueb-node').forEach(function (node) {
new UEBlueprintDrag(node)
leftmost = Math.min(leftmost, node.offsetLeft)
topmost = Math.min(leftmost, node.offsetTop)
})
document.querySelectorAll('.ueb-grid').forEach(function (grid) {
let obj = new UEBlueprintDragScrollGrid(grid, {
'clickButton': 2,
'exitGrabSameButtonOnly': true,
'expandGridSize': 200
})
obj.stepSize = 1
let viewportWidth = grid.parentElement.clientWidth
let viewportHeight = grid.parentElement.clientHeight
grid.style.setProperty('--ueb-translateX', Math.round(viewportWidth / 2))
grid.style.setProperty('--ueb-translateY', Math.round(viewportHeight / 2))
grid.style.setProperty('--ueb-additionalX', 0)
grid.style.setProperty('--ueb-additionalY', 0)
})
});*/
</script>
</body>
</html>