diff --git a/dataforge-vis-spatial-js/build.gradle.kts b/dataforge-vis-spatial-js/build.gradle.kts index 9c045a7c..4693abbf 100644 --- a/dataforge-vis-spatial-js/build.gradle.kts +++ b/dataforge-vis-spatial-js/build.gradle.kts @@ -25,6 +25,7 @@ configure { configure { dependency("three-full") dependency("style-loader") + dependency("element-resize-event") devDependency("karma") } diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeOutput.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeOutput.kt index 32e0d1b8..e40c306a 100644 --- a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeOutput.kt +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeOutput.kt @@ -6,6 +6,7 @@ import hep.dataforge.meta.* import hep.dataforge.output.Output import hep.dataforge.vis.common.DisplayGroup import hep.dataforge.vis.common.DisplayObject +import hep.dataforge.vis.spatial.demo.require import hep.dataforge.vis.spatial.three.Group import info.laht.threekt.WebGLRenderer import info.laht.threekt.cameras.PerspectiveCamera @@ -18,6 +19,8 @@ import info.laht.threekt.scenes.Scene import org.w3c.dom.Element import kotlin.browser.window +private val elementResizeEvent = require("element-resize-event") + class ThreeOutput(override val context: Context, val meta: Meta = EmptyMeta) : Output { private val aspectRatio by meta.number(1.0).double @@ -41,7 +44,6 @@ class ThreeOutput(override val context: Context, val meta: Meta = EmptyMeta) : O } fun attach(element: Element, computeWidth: Element.() -> Int = { element.clientWidth }) { - val width by meta.number(computeWidth(element)).int val height: Int = (width / aspectRatio).toInt() @@ -60,13 +62,11 @@ class ThreeOutput(override val context: Context, val meta: Meta = EmptyMeta) : O renderer.render(scene, camera) } - window.addEventListener("resize", { + elementResizeEvent(element) { camera.updateProjectionMatrix() - - val width by meta.number(computeWidth(element)).int - - renderer.setSize(width, (width / aspectRatio).toInt()) - }, false) + val newWidth = computeWidth(element) + renderer.setSize(newWidth, (newWidth / aspectRatio).toInt()) + } element.replaceWith(renderer.domElement) animate() diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/demo/ThreeDemoGrid.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/demo/ThreeDemoGrid.kt index c6be504f..fd962164 100644 --- a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/demo/ThreeDemoGrid.kt +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/demo/ThreeDemoGrid.kt @@ -52,8 +52,7 @@ class ThreeDemoGrid(meta: Meta) : AbstractPlugin(meta), OutputManager { div("col-4") { h2 { +(meta["title"].string ?: name.toString()) } hr() - val id = "output-$name" - output.attach(div { this.id = id }) { 300 } + output.attach(div { id = "output-$name" }) } } } diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Extruded.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Extruded.kt index 5f015b23..79c00cb9 100644 --- a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Extruded.kt +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Extruded.kt @@ -6,18 +6,37 @@ import hep.dataforge.vis.common.DisplayLeaf import hep.dataforge.vis.common.DisplayObject import hep.dataforge.vis.common.DisplayObjectList + +typealias Shape2D = List + +data class Layer(val z: Number, val x: Number = 0.0, val y: Number = 0.0, val scale: Number = 1.0) + class Extruded(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, meta) { - val shape get() = shape(properties["shape"] ?: error("Shape not defined")) + val shape + get() = shape(properties["shape"] ?: error("Shape not defined")) + + val layers + get() = properties.getAll("layer").values.map { + layer(it.node ?: error("layer item is not a node")) + } companion object { const val TYPE = "geometry.3d.extruded" - fun shape(item: MetaItem<*>): Shape2D { + private fun shape(item: MetaItem<*>): Shape2D { return item.node?.getAll("xyPoint".toName())?.map { (_, value) -> Point2D(value.node["x"].number ?: 0, value.node["y"].number ?: 0) } ?: emptyList() } + + private fun layer(meta: Meta): Layer { + val x by meta.number(0.0) + val y by meta.number(0.0) + val z by meta.number { error("z is undefined in layer") } + val scale by meta.number(1.0) + return Layer(z, x, y, scale) + } } } diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/GeometryBuilder.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/GeometryBuilder.kt index f0b68705..f3c0fa9a 100644 --- a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/GeometryBuilder.kt +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/GeometryBuilder.kt @@ -8,8 +8,6 @@ import hep.dataforge.vis.common.DisplayObject data class Point2D(val x: Number, val y: Number) -typealias Shape2D = List - data class Point3D(val x: Number, val y: Number, val z: Number) : MetaRepr { override fun toMeta(): Meta = buildMeta { "x" to x