0.2.0 #71
@ -22,6 +22,7 @@ kotlin{
|
||||
dependencies{
|
||||
implementation(project(":visionforge-gdml"))
|
||||
implementation(project(":visionforge-plotly"))
|
||||
implementation(projects.visionforge.visionforgeMarkdown)
|
||||
implementation(project(":visionforge-threejs"))
|
||||
implementation(project(":ui:ring"))
|
||||
}
|
@ -12,7 +12,9 @@ import space.kscience.plotly.models.Trace
|
||||
import space.kscience.plotly.scatter
|
||||
import space.kscience.visionforge.Application
|
||||
import space.kscience.visionforge.VisionClient
|
||||
import space.kscience.visionforge.markup.VisionOfMarkup
|
||||
import space.kscience.visionforge.plotly.PlotlyPlugin
|
||||
import space.kscience.visionforge.react.flexRow
|
||||
import space.kscience.visionforge.ring.ThreeCanvasWithControls
|
||||
import space.kscience.visionforge.ring.ThreeWithControlsPlugin
|
||||
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) }
|
||||
}
|
||||
|
||||
|
||||
private class JsPlaygroundApp : Application {
|
||||
|
||||
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 bouncingSphereTrace = Trace()
|
||||
val bouncingSphereMarkup = VisionOfMarkup()
|
||||
|
||||
render(element) {
|
||||
styledDiv {
|
||||
@ -57,53 +59,68 @@ private class JsPlaygroundApp : Application {
|
||||
Tab("gravity") {
|
||||
styledDiv {
|
||||
css {
|
||||
height = 50.vh
|
||||
height = 100.vh - 50.pt
|
||||
}
|
||||
child(ThreeCanvasWithControls) {
|
||||
attrs {
|
||||
context = playgroundContext
|
||||
solid {
|
||||
sphere(5.0, "ball") {
|
||||
detail = 16
|
||||
color("red")
|
||||
val h = 100.0
|
||||
y = h
|
||||
launch {
|
||||
val g = 10.0
|
||||
val dt = 0.1
|
||||
var time = 0.0
|
||||
var velocity = 0.0
|
||||
while (isActive) {
|
||||
delay(20)
|
||||
time += dt
|
||||
velocity -= g * dt
|
||||
y = y.toDouble() + velocity * dt
|
||||
bouncingSphereTrace.appendXYLatest(time, y)
|
||||
if (y.toDouble() <= 2.5) {
|
||||
//conservation of energy
|
||||
velocity = sqrt(2 * g * h)
|
||||
styledDiv {
|
||||
css {
|
||||
height = 50.vh
|
||||
}
|
||||
child(ThreeCanvasWithControls) {
|
||||
attrs {
|
||||
context = playgroundContext
|
||||
solid {
|
||||
sphere(5.0, "ball") {
|
||||
detail = 16
|
||||
color("red")
|
||||
val h = 100.0
|
||||
y = h
|
||||
launch {
|
||||
val g = 10.0
|
||||
val dt = 0.1
|
||||
var time = 0.0
|
||||
var velocity = 0.0
|
||||
while (isActive) {
|
||||
delay(20)
|
||||
time += dt
|
||||
velocity -= g * dt
|
||||
val energy = g * y.toDouble() + velocity * velocity / 2
|
||||
y = y.toDouble() + velocity * dt
|
||||
bouncingSphereTrace.appendXYLatest(time, y)
|
||||
if (y.toDouble() <= 2.5) {
|
||||
//conservation of energy
|
||||
velocity = sqrt(2 * g * h)
|
||||
}
|
||||
|
||||
bouncingSphereMarkup.content = """
|
||||
## Bouncing sphere parameters
|
||||
|
||||
**velocity** = $velocity
|
||||
|
||||
**energy** = $energy
|
||||
""".trimIndent()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
box(200, 5, 200, name = "floor") {
|
||||
y = -2.5
|
||||
box(200, 5, 200, name = "floor") {
|
||||
y = -2.5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
styledDiv {
|
||||
css {
|
||||
height = 40.vh
|
||||
}
|
||||
|
||||
Plotly {
|
||||
attrs {
|
||||
context = playgroundContext
|
||||
plot = space.kscience.plotly.Plotly.plot {
|
||||
traces(bouncingSphereTrace)
|
||||
flexRow {
|
||||
css{
|
||||
alignContent = Align.stretch
|
||||
alignItems = Align.stretch
|
||||
height = 50.vh - 50.pt
|
||||
}
|
||||
plotly {
|
||||
traces(bouncingSphereTrace)
|
||||
}
|
||||
Markup {
|
||||
attrs {
|
||||
markup = bouncingSphereMarkup
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -121,7 +138,7 @@ private class JsPlaygroundApp : Application {
|
||||
Tab("spheres") {
|
||||
styledDiv {
|
||||
css {
|
||||
height = 90.vh
|
||||
height = 100.vh - 50.pt
|
||||
}
|
||||
child(ThreeCanvasWithControls) {
|
||||
val random = Random(112233)
|
||||
@ -147,7 +164,6 @@ private class JsPlaygroundApp : Application {
|
||||
Tab("plotly") {
|
||||
Plotly {
|
||||
attrs {
|
||||
context = playgroundContext
|
||||
plot = space.kscience.plotly.Plotly.plot {
|
||||
scatter {
|
||||
x(1, 2, 3)
|
||||
|
56
demo/js-playground/src/main/kotlin/markupComponent.kt
Normal file
56
demo/js-playground/src/main/kotlin/markupComponent.kt
Normal 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
|
||||
}
|
||||
}
|
@ -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.HTMLElement
|
||||
import react.RProps
|
||||
import react.functionalComponent
|
||||
import react.useEffect
|
||||
import react.useRef
|
||||
import space.kscience.dataforge.context.Context
|
||||
import react.*
|
||||
import space.kscience.plotly.Plot
|
||||
import space.kscience.plotly.PlotlyConfig
|
||||
import space.kscience.plotly.plot
|
||||
import styled.css
|
||||
import styled.styledDiv
|
||||
|
||||
external interface PlotlyProps: RProps{
|
||||
var context: Context
|
||||
external interface PlotlyProps : RProps {
|
||||
var plot: Plot?
|
||||
}
|
||||
|
||||
|
||||
val Plotly = functionalComponent<PlotlyProps>("Plotly"){props ->
|
||||
val Plotly = functionalComponent<PlotlyProps>("Plotly") { props ->
|
||||
val elementRef = useRef<Element>(null)
|
||||
|
||||
useEffect(props.plot, elementRef) {
|
||||
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 {
|
||||
css {
|
||||
width = 100.pct
|
||||
height = 100.pct
|
||||
border(2.pt, BorderStyle.solid, Color.blue)
|
||||
flex(1.0)
|
||||
}
|
||||
ref = elementRef
|
||||
}
|
||||
}
|
||||
|
||||
fun RBuilder.plotly(plotbuilder: Plot.() -> Unit) = Plotly {
|
||||
attrs {
|
||||
this.plot = Plot().apply(plotbuilder)
|
||||
}
|
||||
}
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
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
|
||||
zipStorePath=wrapper/dists
|
||||
|
@ -18,6 +18,7 @@ pluginManagement {
|
||||
|
||||
rootProject.name = "visionforge"
|
||||
|
||||
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
|
||||
|
||||
include(
|
||||
// ":ui",
|
||||
|
@ -50,7 +50,8 @@ public val ThreeCanvasComponent: FunctionComponent<ThreeCanvasProps> = functiona
|
||||
css {
|
||||
maxWidth = 100.vw
|
||||
maxHeight = 100.vh
|
||||
flex(1.0)
|
||||
width = 100.pct
|
||||
height = 100.pct
|
||||
}
|
||||
ref = elementRef
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ public val ThreeCanvasWithControls: FunctionComponent<ThreeCanvasWithControlsPro
|
||||
flexRow {
|
||||
css {
|
||||
height = 100.pct
|
||||
flex(1.0, 1.0, FlexBasis.auto)
|
||||
width = 100.pct
|
||||
flexWrap = FlexWrap.wrap
|
||||
alignItems = Align.stretch
|
||||
alignContent = Align.stretch
|
||||
@ -120,6 +120,7 @@ public val ThreeCanvasWithControls: FunctionComponent<ThreeCanvasWithControlsPro
|
||||
|
||||
flexColumn {
|
||||
css {
|
||||
height = 100.pct
|
||||
minWidth = 600.px
|
||||
flex(10.0, 1.0, FlexBasis("600px"))
|
||||
position = Position.relative
|
||||
|
@ -32,6 +32,11 @@ public class VisionOfMarkup(
|
||||
}
|
||||
}
|
||||
|
||||
//language = markdown
|
||||
public fun VisionOfMarkup.content(text: () -> String) {
|
||||
content = text()
|
||||
}
|
||||
|
||||
internal val markupSerializersModule = SerializersModule {
|
||||
polymorphic(Vision::class) {
|
||||
subclass(VisionOfMarkup.serializer())
|
||||
|
@ -39,7 +39,6 @@ public class MarkupPlugin : VisionPlugin(), ElementVisionRenderer {
|
||||
div.clear()
|
||||
div.append {
|
||||
markdown(flavour) { vision.content ?: "" }
|
||||
|
||||
}
|
||||
}
|
||||
element.append(div)
|
||||
|
@ -2,7 +2,6 @@ package space.kscience.visionforge.solid.three
|
||||
|
||||
import info.laht.threekt.WebGLRenderer
|
||||
import info.laht.threekt.cameras.PerspectiveCamera
|
||||
import info.laht.threekt.core.BufferGeometry
|
||||
import info.laht.threekt.core.Object3D
|
||||
import info.laht.threekt.core.Raycaster
|
||||
import info.laht.threekt.external.controls.OrbitControls
|
||||
@ -276,7 +275,7 @@ public class ThreeCanvas(
|
||||
if (this is Mesh) {
|
||||
if (highlight) {
|
||||
val edges = LineSegments(
|
||||
EdgesGeometry(geometry as BufferGeometry),
|
||||
EdgesGeometry(geometry),
|
||||
material
|
||||
).apply {
|
||||
name = edgesName
|
||||
|
Loading…
Reference in New Issue
Block a user