Adjust demo

This commit is contained in:
Alexander Nozik 2021-08-17 21:57:09 +03:00
parent cbc67cb16b
commit bb61b97c1d
11 changed files with 146 additions and 57 deletions

View File

@ -22,6 +22,7 @@ kotlin{
dependencies{ dependencies{
implementation(project(":visionforge-gdml")) implementation(project(":visionforge-gdml"))
implementation(project(":visionforge-plotly")) implementation(project(":visionforge-plotly"))
implementation(projects.visionforge.visionforgeMarkdown)
implementation(project(":visionforge-threejs")) implementation(project(":visionforge-threejs"))
implementation(project(":ui:ring")) implementation(project(":ui:ring"))
} }

View File

@ -12,7 +12,9 @@ import space.kscience.plotly.models.Trace
import space.kscience.plotly.scatter import space.kscience.plotly.scatter
import space.kscience.visionforge.Application import space.kscience.visionforge.Application
import space.kscience.visionforge.VisionClient import space.kscience.visionforge.VisionClient
import space.kscience.visionforge.markup.VisionOfMarkup
import space.kscience.visionforge.plotly.PlotlyPlugin import space.kscience.visionforge.plotly.PlotlyPlugin
import space.kscience.visionforge.react.flexRow
import space.kscience.visionforge.ring.ThreeCanvasWithControls import space.kscience.visionforge.ring.ThreeCanvasWithControls
import space.kscience.visionforge.ring.ThreeWithControlsPlugin import space.kscience.visionforge.ring.ThreeWithControlsPlugin
import space.kscience.visionforge.ring.solid import space.kscience.visionforge.ring.solid
@ -30,7 +32,6 @@ fun Trace.appendXYLatest(x: Number, y: Number, history: Int = 400, xErr: Number?
yErr?.let { error_y.array = (error_y.array + yErr).takeLast(history) } yErr?.let { error_y.array = (error_y.array + yErr).takeLast(history) }
} }
private class JsPlaygroundApp : Application { private class JsPlaygroundApp : Application {
override fun start(state: Map<String, Any>) { override fun start(state: Map<String, Any>) {
@ -44,6 +45,7 @@ private class JsPlaygroundApp : Application {
val element = document.getElementById("playground") ?: error("Element with id 'playground' not found on page") val element = document.getElementById("playground") ?: error("Element with id 'playground' not found on page")
val bouncingSphereTrace = Trace() val bouncingSphereTrace = Trace()
val bouncingSphereMarkup = VisionOfMarkup()
render(element) { render(element) {
styledDiv { styledDiv {
@ -55,6 +57,10 @@ private class JsPlaygroundApp : Application {
} }
SmartTabs("gravity") { SmartTabs("gravity") {
Tab("gravity") { Tab("gravity") {
styledDiv {
css {
height = 100.vh - 50.pt
}
styledDiv { styledDiv {
css { css {
height = 50.vh height = 50.vh
@ -77,12 +83,21 @@ private class JsPlaygroundApp : Application {
delay(20) delay(20)
time += dt time += dt
velocity -= g * dt velocity -= g * dt
val energy = g * y.toDouble() + velocity * velocity / 2
y = y.toDouble() + velocity * dt y = y.toDouble() + velocity * dt
bouncingSphereTrace.appendXYLatest(time, y) bouncingSphereTrace.appendXYLatest(time, y)
if (y.toDouble() <= 2.5) { if (y.toDouble() <= 2.5) {
//conservation of energy //conservation of energy
velocity = sqrt(2 * g * h) velocity = sqrt(2 * g * h)
} }
bouncingSphereMarkup.content = """
## Bouncing sphere parameters
**velocity** = $velocity
**energy** = $energy
""".trimIndent()
} }
} }
} }
@ -94,17 +109,19 @@ private class JsPlaygroundApp : Application {
} }
} }
} }
styledDiv { flexRow {
css { css{
height = 40.vh alignContent = Align.stretch
alignItems = Align.stretch
height = 50.vh - 50.pt
} }
plotly {
Plotly {
attrs {
context = playgroundContext
plot = space.kscience.plotly.Plotly.plot {
traces(bouncingSphereTrace) traces(bouncingSphereTrace)
} }
Markup {
attrs {
markup = bouncingSphereMarkup
}
} }
} }
} }
@ -121,7 +138,7 @@ private class JsPlaygroundApp : Application {
Tab("spheres") { Tab("spheres") {
styledDiv { styledDiv {
css { css {
height = 90.vh height = 100.vh - 50.pt
} }
child(ThreeCanvasWithControls) { child(ThreeCanvasWithControls) {
val random = Random(112233) val random = Random(112233)
@ -147,7 +164,6 @@ private class JsPlaygroundApp : Application {
Tab("plotly") { Tab("plotly") {
Plotly { Plotly {
attrs { attrs {
context = playgroundContext
plot = space.kscience.plotly.Plotly.plot { plot = space.kscience.plotly.Plotly.plot {
scatter { scatter {
x(1, 2, 3) x(1, 2, 3)

View File

@ -0,0 +1,56 @@
import kotlinx.css.*
import kotlinx.css.properties.border
import kotlinx.dom.clear
import kotlinx.html.dom.append
import org.intellij.markdown.flavours.commonmark.CommonMarkFlavourDescriptor
import org.intellij.markdown.flavours.gfm.GFMFlavourDescriptor
import org.w3c.dom.Element
import org.w3c.dom.HTMLElement
import react.RProps
import react.functionalComponent
import react.useEffect
import react.useRef
import space.kscience.visionforge.markup.VisionOfMarkup
import space.kscience.visionforge.markup.markdown
import space.kscience.visionforge.useProperty
import styled.css
import styled.styledDiv
external interface MarkupProps : RProps {
var markup: VisionOfMarkup?
}
val Markup = functionalComponent<MarkupProps>("Markup") { props ->
val elementRef = useRef<Element>(null)
useEffect(props.markup, elementRef) {
val element = elementRef.current as? HTMLElement ?: error("Markup element not found")
props.markup?.let { vision ->
val flavour = when (vision.format) {
VisionOfMarkup.COMMONMARK_FORMAT -> CommonMarkFlavourDescriptor()
VisionOfMarkup.GFM_FORMAT -> GFMFlavourDescriptor()
//TODO add new formats via plugins
else -> error("Format ${vision.format} not recognized")
}
vision.useProperty(VisionOfMarkup::content) { content ->
element.clear()
element.append {
markdown(flavour) { content ?: "" }
}
}
}
}
styledDiv {
css {
width = 100.pct
height = 100.pct
border(2.pt, BorderStyle.solid, Color.blue)
padding(8.pt)
backgroundColor = Color.white
flex(1.0)
zIndex = 10000
}
ref = elementRef
}
}

View File

@ -1,34 +1,44 @@
import kotlinx.css.flex import kotlinx.css.*
import kotlinx.css.properties.border
import org.w3c.dom.Element import org.w3c.dom.Element
import org.w3c.dom.HTMLElement import org.w3c.dom.HTMLElement
import react.RProps import react.*
import react.functionalComponent
import react.useEffect
import react.useRef
import space.kscience.dataforge.context.Context
import space.kscience.plotly.Plot import space.kscience.plotly.Plot
import space.kscience.plotly.PlotlyConfig
import space.kscience.plotly.plot import space.kscience.plotly.plot
import styled.css import styled.css
import styled.styledDiv import styled.styledDiv
external interface PlotlyProps: RProps{ external interface PlotlyProps : RProps {
var context: Context
var plot: Plot? var plot: Plot?
} }
val Plotly = functionalComponent<PlotlyProps>("Plotly"){props -> val Plotly = functionalComponent<PlotlyProps>("Plotly") { props ->
val elementRef = useRef<Element>(null) val elementRef = useRef<Element>(null)
useEffect(props.plot, elementRef) { useEffect(props.plot, elementRef) {
val element = elementRef.current as? HTMLElement ?: error("Plotly element not found") val element = elementRef.current as? HTMLElement ?: error("Plotly element not found")
props.plot?.let { element.plot(it)} props.plot?.let {
element.plot(it, PlotlyConfig {
responsive = true
})
}
} }
styledDiv { styledDiv {
css { css {
width = 100.pct
height = 100.pct
border(2.pt, BorderStyle.solid, Color.blue)
flex(1.0) flex(1.0)
} }
ref = elementRef ref = elementRef
} }
} }
fun RBuilder.plotly(plotbuilder: Plot.() -> Unit) = Plotly {
attrs {
this.plot = Plot().apply(plotbuilder)
}
}

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -18,6 +18,7 @@ pluginManagement {
rootProject.name = "visionforge" rootProject.name = "visionforge"
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
include( include(
// ":ui", // ":ui",

View File

@ -50,7 +50,8 @@ public val ThreeCanvasComponent: FunctionComponent<ThreeCanvasProps> = functiona
css { css {
maxWidth = 100.vw maxWidth = 100.vw
maxHeight = 100.vh maxHeight = 100.vh
flex(1.0) width = 100.pct
height = 100.pct
} }
ref = elementRef ref = elementRef
} }

View File

@ -112,7 +112,7 @@ public val ThreeCanvasWithControls: FunctionComponent<ThreeCanvasWithControlsPro
flexRow { flexRow {
css { css {
height = 100.pct height = 100.pct
flex(1.0, 1.0, FlexBasis.auto) width = 100.pct
flexWrap = FlexWrap.wrap flexWrap = FlexWrap.wrap
alignItems = Align.stretch alignItems = Align.stretch
alignContent = Align.stretch alignContent = Align.stretch
@ -120,6 +120,7 @@ public val ThreeCanvasWithControls: FunctionComponent<ThreeCanvasWithControlsPro
flexColumn { flexColumn {
css { css {
height = 100.pct
minWidth = 600.px minWidth = 600.px
flex(10.0, 1.0, FlexBasis("600px")) flex(10.0, 1.0, FlexBasis("600px"))
position = Position.relative position = Position.relative

View File

@ -32,6 +32,11 @@ public class VisionOfMarkup(
} }
} }
//language = markdown
public fun VisionOfMarkup.content(text: () -> String) {
content = text()
}
internal val markupSerializersModule = SerializersModule { internal val markupSerializersModule = SerializersModule {
polymorphic(Vision::class) { polymorphic(Vision::class) {
subclass(VisionOfMarkup.serializer()) subclass(VisionOfMarkup.serializer())

View File

@ -39,7 +39,6 @@ public class MarkupPlugin : VisionPlugin(), ElementVisionRenderer {
div.clear() div.clear()
div.append { div.append {
markdown(flavour) { vision.content ?: "" } markdown(flavour) { vision.content ?: "" }
} }
} }
element.append(div) element.append(div)

View File

@ -2,7 +2,6 @@ package space.kscience.visionforge.solid.three
import info.laht.threekt.WebGLRenderer import info.laht.threekt.WebGLRenderer
import info.laht.threekt.cameras.PerspectiveCamera import info.laht.threekt.cameras.PerspectiveCamera
import info.laht.threekt.core.BufferGeometry
import info.laht.threekt.core.Object3D import info.laht.threekt.core.Object3D
import info.laht.threekt.core.Raycaster import info.laht.threekt.core.Raycaster
import info.laht.threekt.external.controls.OrbitControls import info.laht.threekt.external.controls.OrbitControls
@ -276,7 +275,7 @@ public class ThreeCanvas(
if (this is Mesh) { if (this is Mesh) {
if (highlight) { if (highlight) {
val edges = LineSegments( val edges = LineSegments(
EdgesGeometry(geometry as BufferGeometry), EdgesGeometry(geometry),
material material
).apply { ).apply {
name = edgesName name = edgesName