forked from kscience/visionforge
Refactor react ThreeCanvas to functional component
This commit is contained in:
parent
3edb00b6bf
commit
aaad836567
@ -7,7 +7,6 @@ import hep.dataforge.vision.Vision
|
||||
import hep.dataforge.vision.VisionGroup
|
||||
import hep.dataforge.vision.bootstrap.*
|
||||
import hep.dataforge.vision.gdml.toVision
|
||||
import hep.dataforge.vision.react.component
|
||||
import hep.dataforge.vision.react.objectTree
|
||||
import hep.dataforge.vision.solid.Solid
|
||||
import hep.dataforge.vision.solid.SolidGroup
|
||||
@ -22,11 +21,8 @@ import kscience.gdml.GDML
|
||||
import kscience.gdml.decodeFromString
|
||||
import org.w3c.files.FileReader
|
||||
import org.w3c.files.get
|
||||
import react.RProps
|
||||
import react.*
|
||||
import react.dom.h1
|
||||
import react.getValue
|
||||
import react.setValue
|
||||
import react.useState
|
||||
import styled.css
|
||||
|
||||
external interface GDMLAppProps : RProps {
|
||||
@ -44,7 +40,7 @@ external interface GDMLAppProps : RProps {
|
||||
//}
|
||||
|
||||
@JsExport
|
||||
val GDMLApp = component<GDMLAppProps> { props ->
|
||||
val GDMLApp = functionalComponent<GDMLAppProps>("GDMLApp") { props ->
|
||||
var selected by useState { props.selected }
|
||||
var canvas: ThreeCanvas? by useState { null }
|
||||
var vision: Vision? by useState { props.rootObject }
|
||||
@ -113,16 +109,14 @@ val GDMLApp = component<GDMLAppProps> { props ->
|
||||
+"order-xl-2"
|
||||
}
|
||||
//canvas
|
||||
(vision as? Solid)?.let { visual3D ->
|
||||
child(ThreeCanvasComponent::class) {
|
||||
attrs {
|
||||
this.context = props.context
|
||||
this.obj = visual3D
|
||||
this.selected = selected
|
||||
this.clickCallback = select
|
||||
this.canvasCallback = {
|
||||
canvas = it
|
||||
}
|
||||
child(ThreeCanvasComponent) {
|
||||
attrs {
|
||||
this.context = props.context
|
||||
this.obj = vision as? Solid
|
||||
this.selected = selected
|
||||
this.clickCallback = select
|
||||
this.canvasCallback = {
|
||||
canvas = it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import hep.dataforge.names.length
|
||||
import hep.dataforge.vision.Vision
|
||||
import hep.dataforge.vision.bootstrap.canvasControls
|
||||
import hep.dataforge.vision.bootstrap.card
|
||||
import hep.dataforge.vision.react.component
|
||||
import hep.dataforge.vision.react.configEditor
|
||||
import hep.dataforge.vision.react.objectTree
|
||||
import hep.dataforge.vision.solid.specifications.Camera
|
||||
@ -20,11 +19,10 @@ import io.ktor.client.request.get
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.html.js.onClickFunction
|
||||
import react.RProps
|
||||
import react.*
|
||||
import react.dom.*
|
||||
import react.getValue
|
||||
import react.setValue
|
||||
import react.useState
|
||||
import styled.css
|
||||
import styled.styledDiv
|
||||
import kotlin.math.PI
|
||||
|
||||
external interface MMAppProps : RProps {
|
||||
@ -43,8 +41,8 @@ private val canvasConfig = Canvas3DOptions {
|
||||
}
|
||||
|
||||
@JsExport
|
||||
val MMApp = component<MMAppProps> { props ->
|
||||
var selected by useState { props.selected }
|
||||
val MMApp = functionalComponent<MMAppProps>("Muon monitor") { props ->
|
||||
var selected by useState { props.selected }
|
||||
var canvas: ThreeCanvas? by useState { null }
|
||||
|
||||
val select: (Name?) -> Unit = {
|
||||
@ -59,7 +57,12 @@ val MMApp = component<MMAppProps> { props ->
|
||||
}
|
||||
}
|
||||
div("row") {
|
||||
div("col-lg-3 px-0 overflow-auto") {
|
||||
styledDiv {
|
||||
css {
|
||||
+"col-lg-3"
|
||||
+"px-0"
|
||||
+"overflow-auto"
|
||||
}
|
||||
//tree
|
||||
card("Object tree") {
|
||||
objectTree(root, selected, select)
|
||||
@ -67,7 +70,7 @@ val MMApp = component<MMAppProps> { props ->
|
||||
}
|
||||
div("col-lg-6") {
|
||||
//canvas
|
||||
child(ThreeCanvasComponent::class) {
|
||||
child(ThreeCanvasComponent) {
|
||||
attrs {
|
||||
this.context = props.context
|
||||
this.obj = root
|
||||
|
@ -3,16 +3,25 @@ import hep.dataforge.js.Application
|
||||
import hep.dataforge.js.startApplication
|
||||
import hep.dataforge.vision.bootstrap.visionPropertyEditor
|
||||
import hep.dataforge.vision.react.objectTree
|
||||
import hep.dataforge.vision.solid.Point3D
|
||||
import hep.dataforge.vision.solid.SolidGroup
|
||||
import hep.dataforge.vision.solid.box
|
||||
import hep.dataforge.vision.solid.group
|
||||
import hep.dataforge.vision.solid.*
|
||||
import hep.dataforge.vision.solid.specifications.Canvas3DOptions
|
||||
import hep.dataforge.vision.solid.three.ThreeCanvasComponent
|
||||
import hep.dataforge.vision.solid.three.ThreePlugin
|
||||
import hep.dataforge.vision.solid.three.threeCanvas
|
||||
import kotlinx.browser.document
|
||||
import org.w3c.dom.HTMLElement
|
||||
import react.RBuilder
|
||||
import react.child
|
||||
import react.dom.div
|
||||
import react.dom.render
|
||||
import kotlin.browser.document
|
||||
|
||||
public fun RBuilder.threeCanvas(object3D: Solid, options: Canvas3DOptions.() -> Unit = {}) {
|
||||
child(ThreeCanvasComponent) {
|
||||
attrs {
|
||||
this.obj = object3D
|
||||
this.options = Canvas3DOptions.invoke(options)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class PlayGroundApp : Application {
|
||||
|
||||
|
@ -19,29 +19,29 @@ public external interface ConfigEditorItemProps : RProps {
|
||||
/**
|
||||
* Root config object - always non null
|
||||
*/
|
||||
var root: Config
|
||||
public var root: Config
|
||||
|
||||
/**
|
||||
* Full path to the displayed node in [root]. Could be empty
|
||||
*/
|
||||
var name: Name
|
||||
public var name: Name
|
||||
|
||||
/**
|
||||
* Root default
|
||||
*/
|
||||
var default: Meta?
|
||||
public var default: Meta?
|
||||
|
||||
/**
|
||||
* Root descriptor
|
||||
*/
|
||||
var descriptor: NodeDescriptor?
|
||||
public var descriptor: NodeDescriptor?
|
||||
}
|
||||
|
||||
private val ConfigEditorItem: FunctionalComponent<ConfigEditorItemProps> = component { props ->
|
||||
private val ConfigEditorItem: FunctionalComponent<ConfigEditorItemProps> = functionalComponent("ConfigEditorItem") { props ->
|
||||
configEditorItem(props)
|
||||
}
|
||||
|
||||
private fun RFBuilder.configEditorItem(props: ConfigEditorItemProps) {
|
||||
private fun RBuilder.configEditorItem(props: ConfigEditorItemProps) {
|
||||
var expanded: Boolean by useState { true }
|
||||
var item: MetaItem<Config>? by useState { props.root[props.name] }
|
||||
val descriptorItem: ItemDescriptor? = props.descriptor?.get(props.name)
|
||||
@ -198,7 +198,7 @@ public external interface ConfigEditorProps : RProps {
|
||||
}
|
||||
|
||||
@JsExport
|
||||
public val ConfigEditor: FunctionalComponent<ConfigEditorProps> = component { props ->
|
||||
public val ConfigEditor: FunctionalComponent<ConfigEditorProps> = functionalComponent("ConfigEditor") { props ->
|
||||
child(ConfigEditorItem) {
|
||||
attrs {
|
||||
this.key = ""
|
||||
@ -223,7 +223,7 @@ public fun Element.configEditor(config: Config, descriptor: NodeDescriptor? = nu
|
||||
}
|
||||
}
|
||||
|
||||
fun RBuilder.configEditor(config: Config, descriptor: NodeDescriptor? = null, default: Meta? = null, key: Any? = null) {
|
||||
public fun RBuilder.configEditor(config: Config, descriptor: NodeDescriptor? = null, default: Meta? = null, key: Any? = null) {
|
||||
child(ConfigEditor) {
|
||||
attrs {
|
||||
this.key = key?.toString() ?: ""
|
||||
@ -234,7 +234,7 @@ fun RBuilder.configEditor(config: Config, descriptor: NodeDescriptor? = null, de
|
||||
}
|
||||
}
|
||||
|
||||
fun RBuilder.configEditor(
|
||||
public fun RBuilder.configEditor(
|
||||
obj: Configurable,
|
||||
descriptor: NodeDescriptor? = obj.descriptor,
|
||||
default: Meta? = null,
|
||||
|
@ -21,24 +21,24 @@ public external interface MetaViewerProps : RProps {
|
||||
/**
|
||||
* Root meta
|
||||
*/
|
||||
var root: Meta
|
||||
public var root: Meta
|
||||
|
||||
/**
|
||||
* Full path to the displayed node in [root]. Could be empty
|
||||
*/
|
||||
var name: Name
|
||||
public var name: Name
|
||||
|
||||
/**
|
||||
* Root descriptor
|
||||
*/
|
||||
var descriptor: NodeDescriptor?
|
||||
public var descriptor: NodeDescriptor?
|
||||
}
|
||||
|
||||
private val MetaViewerItem: FunctionalComponent<MetaViewerProps> = component { props ->
|
||||
private val MetaViewerItem: FunctionalComponent<MetaViewerProps> = functionalComponent("MetaViewerItem") { props ->
|
||||
metaViewerItem(props)
|
||||
}
|
||||
|
||||
private fun RFBuilder.metaViewerItem(props: MetaViewerProps) {
|
||||
private fun RBuilder.metaViewerItem(props: MetaViewerProps) {
|
||||
var expanded: Boolean by useState { true }
|
||||
val item = props.root[props.name]
|
||||
val descriptorItem: ItemDescriptor? = props.descriptor?.get(props.name)
|
||||
@ -137,7 +137,7 @@ private fun RFBuilder.metaViewerItem(props: MetaViewerProps) {
|
||||
}
|
||||
|
||||
@JsExport
|
||||
val MetaViewer = component<MetaViewerProps> { props ->
|
||||
public val MetaViewer:FunctionalComponent<MetaViewerProps> = functionalComponent<MetaViewerProps>("MetaViewer") { props ->
|
||||
child(MetaViewerItem) {
|
||||
attrs {
|
||||
this.key = ""
|
||||
@ -148,7 +148,7 @@ val MetaViewer = component<MetaViewerProps> { props ->
|
||||
}
|
||||
}
|
||||
|
||||
fun RBuilder.metaViewer(meta: Meta, descriptor: NodeDescriptor? = null, key: Any? = null) {
|
||||
public fun RBuilder.metaViewer(meta: Meta, descriptor: NodeDescriptor? = null, key: Any? = null) {
|
||||
child(MetaViewer) {
|
||||
attrs {
|
||||
this.key = key?.toString() ?: ""
|
||||
|
@ -19,7 +19,7 @@ public external interface ObjectTreeProps : RProps {
|
||||
public var clickCallback: (Name) -> Unit
|
||||
}
|
||||
|
||||
private fun RFBuilder.objectTree(props: ObjectTreeProps): Unit {
|
||||
private fun RBuilder.objectTree(props: ObjectTreeProps): Unit {
|
||||
var expanded: Boolean by useState { props.selected?.startsWith(props.name) ?: false }
|
||||
|
||||
val onClick: (Event) -> Unit = {
|
||||
@ -103,11 +103,11 @@ private fun RFBuilder.objectTree(props: ObjectTreeProps): Unit {
|
||||
}
|
||||
|
||||
@JsExport
|
||||
val ObjectTree: FunctionalComponent<ObjectTreeProps> = component { props ->
|
||||
public val ObjectTree: FunctionalComponent<ObjectTreeProps> = functionalComponent("ObjectTree") { props ->
|
||||
objectTree(props)
|
||||
}
|
||||
|
||||
fun RBuilder.objectTree(
|
||||
public fun RBuilder.objectTree(
|
||||
vision: Vision,
|
||||
selected: Name? = null,
|
||||
clickCallback: (Name) -> Unit = {}
|
||||
|
@ -4,11 +4,11 @@ import kotlinx.css.*
|
||||
import kotlinx.css.properties.*
|
||||
import styled.StyleSheet
|
||||
|
||||
object TreeStyles : StyleSheet("treeStyles", true) {
|
||||
public object TreeStyles : StyleSheet("treeStyles", true) {
|
||||
/**
|
||||
* Remove default bullets
|
||||
*/
|
||||
val tree by css {
|
||||
public val tree by css {
|
||||
paddingLeft = 8.px
|
||||
marginLeft = 0.px
|
||||
listStyleType = ListStyleType.none
|
||||
@ -17,7 +17,7 @@ object TreeStyles : StyleSheet("treeStyles", true) {
|
||||
/**
|
||||
* Style the caret/arrow
|
||||
*/
|
||||
val treeCaret by css {
|
||||
public val treeCaret by css {
|
||||
cursor = Cursor.pointer
|
||||
userSelect = UserSelect.none
|
||||
/* Create the caret/arrow with a unicode, and style it */
|
||||
|
@ -6,11 +6,12 @@ import kotlinx.css.display
|
||||
import kotlinx.css.flexDirection
|
||||
import kotlinx.html.DIV
|
||||
import react.RBuilder
|
||||
import react.ReactElement
|
||||
import styled.StyledDOMBuilder
|
||||
import styled.css
|
||||
import styled.styledDiv
|
||||
|
||||
inline fun RBuilder.flexColumn(block: StyledDOMBuilder<DIV>.() -> Unit) =
|
||||
public inline fun RBuilder.flexColumn(block: StyledDOMBuilder<DIV>.() -> Unit): ReactElement =
|
||||
styledDiv {
|
||||
css {
|
||||
display = Display.flex
|
||||
@ -19,7 +20,7 @@ inline fun RBuilder.flexColumn(block: StyledDOMBuilder<DIV>.() -> Unit) =
|
||||
block()
|
||||
}
|
||||
|
||||
inline fun RBuilder.flexRow(block: StyledDOMBuilder<DIV>.() -> Unit) =
|
||||
public inline fun RBuilder.flexRow(block: StyledDOMBuilder<DIV>.() -> Unit): ReactElement =
|
||||
styledDiv {
|
||||
css {
|
||||
display = Display.flex
|
||||
|
@ -1,24 +0,0 @@
|
||||
package hep.dataforge.vision.react
|
||||
|
||||
import react.*
|
||||
|
||||
public class RFBuilder : RBuilder()
|
||||
|
||||
/**
|
||||
* Get functional component from [func]
|
||||
*/
|
||||
public inline fun <P : RProps> component(
|
||||
crossinline func: RFBuilder.(props: P) -> Unit,
|
||||
): FunctionalComponent<P> {
|
||||
return { props: P ->
|
||||
val nodes = RFBuilder().apply { func(props) }.childList
|
||||
when (nodes.size) {
|
||||
0 -> null
|
||||
1 -> nodes.first()
|
||||
else -> createElement(Fragment, kotlinext.js.js {}, *nodes.toTypedArray())
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
//public fun <T> RFBuilder.memoize(vararg deps: dynamic, builder: () -> T): T = useMemo(builder, deps)
|
||||
|
@ -13,9 +13,9 @@ import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import mu.KotlinLogging
|
||||
|
||||
expect class Counter() {
|
||||
fun get(): Int
|
||||
fun incrementAndGet(): Int
|
||||
public expect class Counter() {
|
||||
public fun get(): Int
|
||||
public fun incrementAndGet(): Int
|
||||
}
|
||||
|
||||
private fun Point3D?.safePlus(other: Point3D?): Point3D? = if (this == null && other == null) {
|
||||
|
@ -1,8 +1,8 @@
|
||||
package hep.dataforge.vision.gdml
|
||||
|
||||
actual class Counter {
|
||||
public actual class Counter {
|
||||
private var count: Int = 0
|
||||
actual fun get(): Int = count
|
||||
public actual fun get(): Int = count
|
||||
|
||||
actual fun incrementAndGet(): Int = count++
|
||||
public actual fun incrementAndGet(): Int = count++
|
||||
}
|
@ -7,7 +7,7 @@ import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
actual typealias Counter = AtomicInteger
|
||||
public actual typealias Counter = AtomicInteger
|
||||
|
||||
fun GDML.Companion.readFile(file: Path): GDML {
|
||||
val xmlReader = StAXReader(Files.newInputStream(file), "UTF-8")
|
||||
|
@ -29,11 +29,11 @@ import info.laht.threekt.math.Vector2
|
||||
import info.laht.threekt.objects.LineSegments
|
||||
import info.laht.threekt.objects.Mesh
|
||||
import info.laht.threekt.scenes.Scene
|
||||
import kotlinx.browser.window
|
||||
import kotlinx.dom.clear
|
||||
import org.w3c.dom.HTMLElement
|
||||
import org.w3c.dom.Node
|
||||
import org.w3c.dom.events.MouseEvent
|
||||
import kotlin.browser.window
|
||||
import kotlin.dom.clear
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.max
|
||||
import kotlin.math.sin
|
||||
@ -41,11 +41,16 @@ import kotlin.math.sin
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class ThreeCanvas(element: HTMLElement, val three: ThreePlugin, val options: Canvas3DOptions) : Renderer<Solid> {
|
||||
public class ThreeCanvas(
|
||||
element: HTMLElement,
|
||||
public val three: ThreePlugin,
|
||||
public val options: Canvas3DOptions,
|
||||
public val onClick: ((Name?) -> Unit)? = null,
|
||||
) : Renderer<Solid> {
|
||||
|
||||
override val context: Context get() = three.context
|
||||
|
||||
var content: Solid? = null
|
||||
public var content: Solid? = null
|
||||
private set
|
||||
|
||||
private var root: Object3D? = null
|
||||
@ -53,17 +58,15 @@ class ThreeCanvas(element: HTMLElement, val three: ThreePlugin, val options: Can
|
||||
private val raycaster = Raycaster()
|
||||
private val mousePosition: Vector2 = Vector2()
|
||||
|
||||
var onClick: ((Name?) -> Unit)? = null
|
||||
|
||||
val axes = AxesHelper(options.axes.size.toInt()).apply {
|
||||
public val axes: AxesHelper = AxesHelper(options.axes.size.toInt()).apply {
|
||||
visible = options.axes.visible
|
||||
}
|
||||
|
||||
val scene: Scene = Scene().apply {
|
||||
public val scene: Scene = Scene().apply {
|
||||
add(axes)
|
||||
}
|
||||
|
||||
val camera = buildCamera(options.camera)
|
||||
public val camera: PerspectiveCamera = buildCamera(options.camera)
|
||||
|
||||
private var picked: Object3D? = null
|
||||
|
||||
@ -166,7 +169,7 @@ class ThreeCanvas(element: HTMLElement, val three: ThreePlugin, val options: Can
|
||||
}
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
public fun clear() {
|
||||
scene.children.find { it.name == "@root" }?.let {
|
||||
scene.remove(it)
|
||||
}
|
||||
@ -192,7 +195,7 @@ class ThreeCanvas(element: HTMLElement, val three: ThreePlugin, val options: Can
|
||||
private fun Object3D.toggleHighlight(
|
||||
highlight: Boolean,
|
||||
edgesName: String,
|
||||
material: LineBasicMaterial = SELECTED_MATERIAL
|
||||
material: LineBasicMaterial = SELECTED_MATERIAL,
|
||||
) {
|
||||
if (userData[DO_NOT_HIGHLIGHT_TAG] == true) {
|
||||
return
|
||||
@ -220,7 +223,7 @@ class ThreeCanvas(element: HTMLElement, val three: ThreePlugin, val options: Can
|
||||
/**
|
||||
* Toggle highlight for element with given name
|
||||
*/
|
||||
fun select(name: Name?) {
|
||||
public fun select(name: Name?) {
|
||||
if (name == null) {
|
||||
selected?.toggleHighlight(false, SELECT_NAME, SELECTED_MATERIAL)
|
||||
selected = null
|
||||
@ -234,15 +237,21 @@ class ThreeCanvas(element: HTMLElement, val three: ThreePlugin, val options: Can
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val DO_NOT_HIGHLIGHT_TAG = "doNotHighlight"
|
||||
public companion object {
|
||||
public const val DO_NOT_HIGHLIGHT_TAG = "doNotHighlight"
|
||||
private const val HIGHLIGHT_NAME = "@highlight"
|
||||
private const val SELECT_NAME = "@select"
|
||||
}
|
||||
}
|
||||
|
||||
fun ThreePlugin.output(element: HTMLElement, spec: Canvas3DOptions = Canvas3DOptions.empty()): ThreeCanvas =
|
||||
ThreeCanvas(element, this, spec)
|
||||
public fun ThreePlugin.output(
|
||||
element: HTMLElement,
|
||||
spec: Canvas3DOptions = Canvas3DOptions.empty(),
|
||||
onClick: ((Name?) -> Unit)? = null,
|
||||
): ThreeCanvas = ThreeCanvas(element, this, spec, onClick)
|
||||
|
||||
fun ThreePlugin.render(element: HTMLElement, obj: Solid, spec: Canvas3DOptions = Canvas3DOptions.empty()): Unit =
|
||||
output(element, spec).render(obj)
|
||||
public fun ThreePlugin.render(
|
||||
element: HTMLElement, obj: Solid,
|
||||
spec: Canvas3DOptions = Canvas3DOptions.empty(),
|
||||
onClick: ((Name?) -> Unit)? = null,
|
||||
): Unit = output(element, spec, onClick).render(obj)
|
@ -6,67 +6,88 @@ import hep.dataforge.vision.solid.Solid
|
||||
import hep.dataforge.vision.solid.specifications.Canvas3DOptions
|
||||
import org.w3c.dom.Element
|
||||
import org.w3c.dom.HTMLElement
|
||||
import react.RBuilder
|
||||
import react.RComponent
|
||||
import react.RProps
|
||||
import react.RState
|
||||
import react.*
|
||||
import react.dom.div
|
||||
import react.dom.findDOMNode
|
||||
|
||||
public external interface ThreeCanvasProps : RProps {
|
||||
var context: Context
|
||||
var obj: Solid
|
||||
var options: Canvas3DOptions?
|
||||
var selected: Name?
|
||||
var clickCallback: (Name?) -> Unit
|
||||
var canvasCallback: ((ThreeCanvas?) -> Unit)?
|
||||
public var context: Context
|
||||
public var obj: Solid?
|
||||
public var options: Canvas3DOptions?
|
||||
public var selected: Name?
|
||||
public var clickCallback: (Name?) -> Unit
|
||||
public var canvasCallback: ((ThreeCanvas?) -> Unit)?
|
||||
}
|
||||
|
||||
public external interface ThreeCanvasState : RState {
|
||||
var element: Element?
|
||||
public var element: Element?
|
||||
// var canvas: ThreeCanvas?
|
||||
}
|
||||
|
||||
@JsExport
|
||||
public class ThreeCanvasComponent : RComponent<ThreeCanvasProps, ThreeCanvasState>() {
|
||||
public val ThreeCanvasComponent: FunctionalComponent<ThreeCanvasProps> = functionalComponent(
|
||||
"ThreeCanvasComponent"
|
||||
) { props ->
|
||||
val elementRef = useRef<Element?>(null)
|
||||
var canvas by useState<ThreeCanvas?>(null)
|
||||
|
||||
private var canvas: ThreeCanvas? = null
|
||||
|
||||
override fun componentDidMount() {
|
||||
if(canvas == null) {
|
||||
val element = state.element as? HTMLElement ?: error("Canvas element not found")
|
||||
useEffect(listOf(props.context, props.obj, props.options, elementRef)) {
|
||||
if (canvas == null) {
|
||||
val element = elementRef.current as? HTMLElement ?: error("Canvas element not found")
|
||||
val three: ThreePlugin = props.context.plugins.fetch(ThreePlugin)
|
||||
canvas = three.output(element, props.options ?: Canvas3DOptions.empty()).apply {
|
||||
onClick = props.clickCallback
|
||||
}
|
||||
props.canvasCallback?.invoke(canvas)
|
||||
}
|
||||
canvas?.render(props.obj)
|
||||
}
|
||||
|
||||
override fun componentDidUpdate(prevProps: ThreeCanvasProps, prevState: ThreeCanvasState, snapshot: Any) {
|
||||
if (prevProps.obj != props.obj) {
|
||||
componentDidMount()
|
||||
}
|
||||
if (prevProps.selected != props.selected) {
|
||||
canvas?.select(props.selected)
|
||||
val newCanvas = three.output(element, props.options ?: Canvas3DOptions.empty(), props.clickCallback)
|
||||
props.canvasCallback?.invoke(newCanvas)
|
||||
canvas = newCanvas
|
||||
}
|
||||
}
|
||||
|
||||
override fun RBuilder.render() {
|
||||
div {
|
||||
ref {
|
||||
state.element = findDOMNode(it)
|
||||
useEffect(listOf(canvas, props.obj)) {
|
||||
props.obj?.let { obj ->
|
||||
if (canvas?.content != obj) {
|
||||
canvas?.render(obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(listOf(canvas, props.selected)) {
|
||||
canvas?.select(props.selected)
|
||||
}
|
||||
|
||||
div {
|
||||
ref = elementRef
|
||||
}
|
||||
}
|
||||
|
||||
public fun RBuilder.threeCanvas(object3D: Solid, options: Canvas3DOptions.() -> Unit = {}) {
|
||||
child(ThreeCanvasComponent::class) {
|
||||
attrs {
|
||||
this.obj = object3D
|
||||
this.options = Canvas3DOptions.invoke(options)
|
||||
}
|
||||
}
|
||||
}
|
||||
//public class ThreeCanvasComponent : RComponent<ThreeCanvasProps, ThreeCanvasState>() {
|
||||
//
|
||||
// private var canvas: ThreeCanvas? = null
|
||||
//
|
||||
// override fun componentDidMount() {
|
||||
// props.obj?.let { obj ->
|
||||
// if (canvas == null) {
|
||||
// val element = state.element as? HTMLElement ?: error("Canvas element not found")
|
||||
// val three: ThreePlugin = props.context.plugins.fetch(ThreePlugin)
|
||||
// canvas = three.output(element, props.options ?: Canvas3DOptions.empty()).apply {
|
||||
// onClick = props.clickCallback
|
||||
// }
|
||||
// props.canvasCallback?.invoke(canvas)
|
||||
// }
|
||||
// canvas?.render(obj)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// override fun componentDidUpdate(prevProps: ThreeCanvasProps, prevState: ThreeCanvasState, snapshot: Any) {
|
||||
// if (prevProps.obj != props.obj) {
|
||||
// componentDidMount()
|
||||
// }
|
||||
// if (prevProps.selected != props.selected) {
|
||||
// canvas?.select(props.selected)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// override fun RBuilder.render() {
|
||||
// div {
|
||||
// ref {
|
||||
// state.element = findDOMNode(it)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
Loading…
Reference in New Issue
Block a user