0.2.0 #71

Merged
altavir merged 139 commits from dev into master 2022-01-24 09:44:18 +03:00
11 changed files with 146 additions and 57 deletions
Showing only changes of commit bb61b97c1d - Show all commits

View File

@ -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"))
}

View File

@ -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)

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.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)
}
}

View File

@ -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

View File

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

View File

@ -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
}

View File

@ -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

View File

@ -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())

View File

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

View File

@ -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