v0.2.0-dev-22 #47
@ -20,7 +20,7 @@ allprojects {
|
||||
}
|
||||
|
||||
group = "space.kscience"
|
||||
version = "0.2.0-dev-18"
|
||||
version = "0.2.0-dev-19"
|
||||
}
|
||||
|
||||
subprojects {
|
||||
|
@ -1,29 +1,20 @@
|
||||
package space.kscience.visionforge.gdml.demo
|
||||
|
||||
import kotlinx.browser.window
|
||||
import kotlinx.css.height
|
||||
import kotlinx.css.vh
|
||||
import org.w3c.files.FileReader
|
||||
import org.w3c.files.get
|
||||
import react.*
|
||||
import react.dom.h1
|
||||
import ringui.grid.ringCol
|
||||
import ringui.grid.ringGrid
|
||||
import ringui.grid.ringRow
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.dataforge.context.fetch
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.gdml.Gdml
|
||||
import space.kscience.gdml.decodeFromString
|
||||
import space.kscience.visionforge.bootstrap.nameCrumbs
|
||||
import space.kscience.visionforge.gdml.toVision
|
||||
import space.kscience.visionforge.react.ThreeCanvasComponent
|
||||
import space.kscience.visionforge.react.flexColumn
|
||||
import space.kscience.visionforge.ring.ringThreeControls
|
||||
import space.kscience.visionforge.ring.ThreeCanvasWithControls
|
||||
import space.kscience.visionforge.ring.tab
|
||||
import space.kscience.visionforge.solid.Solid
|
||||
import space.kscience.visionforge.solid.Solids
|
||||
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
||||
import styled.css
|
||||
import styled.styledDiv
|
||||
|
||||
external interface GDMLAppProps : RProps {
|
||||
var context: Context
|
||||
@ -33,19 +24,7 @@ external interface GDMLAppProps : RProps {
|
||||
|
||||
@JsExport
|
||||
val GDMLApp = functionalComponent<GDMLAppProps>("GDMLApp") { props ->
|
||||
var selected by useState { props.selected }
|
||||
var vision: Solid? by useState { props.vision }
|
||||
|
||||
val onSelect: (Name?) -> Unit = {
|
||||
selected = it
|
||||
}
|
||||
|
||||
val options = useMemo {
|
||||
Canvas3DOptions.invoke {
|
||||
this.onSelect = onSelect
|
||||
}
|
||||
}
|
||||
|
||||
val visionManager = useMemo(props.context) { props.context.fetch(Solids).visionManager }
|
||||
|
||||
fun loadData(name: String, data: String) {
|
||||
@ -64,43 +43,16 @@ val GDMLApp = functionalComponent<GDMLAppProps>("GDMLApp") { props ->
|
||||
vision = parsedVision as? Solid ?: error("Parsed vision is not a solid")
|
||||
}
|
||||
|
||||
|
||||
ringGrid {
|
||||
ringRow {
|
||||
ringCol {
|
||||
attrs {
|
||||
lg = 9
|
||||
}
|
||||
flexColumn {
|
||||
css {
|
||||
height = 100.vh
|
||||
}
|
||||
h1 { +"GDML/JSON loader demo" }
|
||||
//canvas
|
||||
|
||||
child(ThreeCanvasComponent) {
|
||||
attrs {
|
||||
this.context = props.context
|
||||
this.solid = vision
|
||||
this.selected = selected
|
||||
this.options = options
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
ringCol {
|
||||
attrs {
|
||||
lg = 3
|
||||
}
|
||||
flexColumn {
|
||||
css {
|
||||
height = 100.vh
|
||||
}
|
||||
styledDiv {
|
||||
child(ThreeCanvasWithControls) {
|
||||
attrs {
|
||||
this.context = props.context
|
||||
this.solid = vision
|
||||
this.selected = props.selected
|
||||
tab("Load") {
|
||||
fileDrop("(drag file here)") { files ->
|
||||
val file = files?.get(0)
|
||||
if (file != null) {
|
||||
|
||||
FileReader().apply {
|
||||
onload = {
|
||||
val string = result as String
|
||||
@ -110,8 +62,6 @@ val GDMLApp = functionalComponent<GDMLAppProps>("GDMLApp") { props ->
|
||||
}
|
||||
}
|
||||
}
|
||||
nameCrumbs(selected, "World", onSelect)
|
||||
ringThreeControls(options, vision, selected, onSelect)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ import space.kscience.visionforge.Application
|
||||
import space.kscience.visionforge.VisionClient
|
||||
import space.kscience.visionforge.gdml.toVision
|
||||
import space.kscience.visionforge.ring.ThreeCanvasWithControls
|
||||
import space.kscience.visionforge.ring.ThreeWithControls
|
||||
import space.kscience.visionforge.ring.ThreeWithControlsPlugin
|
||||
import space.kscience.visionforge.startApplication
|
||||
import styled.css
|
||||
import styled.styledDiv
|
||||
@ -21,7 +21,7 @@ private class JsPlaygroundApp : Application {
|
||||
override fun start(state: Map<String, Any>) {
|
||||
|
||||
val playgroundContext = Context {
|
||||
plugin(ThreeWithControls)
|
||||
plugin(ThreeWithControlsPlugin)
|
||||
plugin(VisionClient)
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
import space.kscience.dataforge.misc.DFExperimental
|
||||
import space.kscience.visionforge.plotly.PlotlyPlugin
|
||||
import space.kscience.visionforge.ring.ThreeWithControls
|
||||
import space.kscience.visionforge.ring.ThreeWithControlsPlugin
|
||||
import space.kscience.visionforge.runVisionClient
|
||||
|
||||
@DFExperimental
|
||||
fun main() = runVisionClient {
|
||||
plugin(PlotlyPlugin)
|
||||
plugin(ThreeWithControls)
|
||||
plugin(ThreeWithControlsPlugin)
|
||||
}
|
@ -1,12 +1,12 @@
|
||||
package space.kscience.visionforge.gdml.jupyter
|
||||
|
||||
import space.kscience.dataforge.misc.DFExperimental
|
||||
import space.kscience.visionforge.ring.ThreeWithControls
|
||||
import space.kscience.visionforge.ring.ThreeWithControlsPlugin
|
||||
import space.kscience.visionforge.runVisionClient
|
||||
|
||||
@DFExperimental
|
||||
@JsExport
|
||||
fun main(): Unit = runVisionClient {
|
||||
plugin(ThreeWithControls)
|
||||
plugin(ThreeWithControlsPlugin)
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,5 @@
|
||||
package space.kscience.visionforge.react
|
||||
|
||||
import kotlinx.css.margin
|
||||
import kotlinx.css.padding
|
||||
import kotlinx.css.px
|
||||
import kotlinx.html.InputType
|
||||
import kotlinx.html.js.onChangeFunction
|
||||
import org.w3c.dom.HTMLInputElement
|
||||
@ -15,7 +12,6 @@ import space.kscience.dataforge.meta.double
|
||||
import space.kscience.dataforge.meta.get
|
||||
import space.kscience.dataforge.meta.string
|
||||
import space.kscience.dataforge.values.asValue
|
||||
import styled.css
|
||||
import styled.styledInput
|
||||
|
||||
@JsExport
|
||||
@ -42,10 +38,6 @@ public val RangeValueChooser: FunctionalComponent<ValueChooserProps> =
|
||||
|
||||
flexRow {
|
||||
styledInput(type = InputType.checkBox) {
|
||||
css{
|
||||
padding(0.px)
|
||||
margin(0.px)
|
||||
}
|
||||
attrs {
|
||||
defaultChecked = rangeDisabled.not()
|
||||
onChangeFunction = handleDisable
|
||||
|
@ -1,8 +1,6 @@
|
||||
package space.kscience.visionforge.react
|
||||
|
||||
import kotlinx.css.FlexBasis
|
||||
import kotlinx.css.flexBasis
|
||||
import kotlinx.css.flexGrow
|
||||
import kotlinx.css.*
|
||||
import org.w3c.dom.Element
|
||||
import org.w3c.dom.HTMLElement
|
||||
import react.*
|
||||
@ -39,7 +37,7 @@ public val ThreeCanvasComponent: FunctionalComponent<ThreeCanvasProps> = functio
|
||||
useEffect(listOf(props.solid, props.options, elementRef)) {
|
||||
if (canvas == null) {
|
||||
val element = elementRef.current as? HTMLElement ?: error("Canvas element not found")
|
||||
canvas = three.getOrCreateCanvas(element, props.options ?: Canvas3DOptions())
|
||||
canvas = ThreeCanvas(three, element, props.options ?: Canvas3DOptions())
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,8 +53,10 @@ public val ThreeCanvasComponent: FunctionalComponent<ThreeCanvasProps> = functio
|
||||
|
||||
styledDiv {
|
||||
css {
|
||||
flexGrow = 1.0
|
||||
flexBasis = FlexBasis.fill
|
||||
maxWidth = 100.vw
|
||||
maxHeight = 100.vh
|
||||
display = Display.block
|
||||
bottom = 0.px
|
||||
}
|
||||
ref = elementRef
|
||||
}
|
||||
|
@ -2,9 +2,11 @@ package space.kscience.visionforge.ring
|
||||
|
||||
import kotlinx.css.*
|
||||
import react.*
|
||||
import ringui.grid.RowPosition
|
||||
import ringui.grid.ringCol
|
||||
import ringui.grid.ringGrid
|
||||
import ringui.grid.ringRow
|
||||
import ringui.tabs.ringTab
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.visionforge.react.ThreeCanvasComponent
|
||||
@ -17,6 +19,11 @@ public external interface ThreeCanvasWithControlsProps : RProps {
|
||||
public var context: Context
|
||||
public var solid: Solid?
|
||||
public var selected: Name?
|
||||
public var additionalTabs: Map<String, RBuilder.() -> Unit>?
|
||||
}
|
||||
|
||||
public fun ThreeCanvasWithControlsProps.tab(title: String, block: RBuilder.()->Unit){
|
||||
additionalTabs = (additionalTabs?: emptyMap()) + (title to block)
|
||||
}
|
||||
|
||||
@JsExport
|
||||
@ -35,11 +42,15 @@ public val ThreeCanvasWithControls: (props: ThreeCanvasWithControlsProps) -> dyn
|
||||
styledDiv {
|
||||
css {
|
||||
height = 100.pct
|
||||
width = 100.pct
|
||||
maxHeight = 100.vh
|
||||
maxWidth = 100.vw
|
||||
}
|
||||
ringGrid {
|
||||
ringRow {
|
||||
attrs {
|
||||
start = RowPosition.sm
|
||||
}
|
||||
ringCol {
|
||||
attrs {
|
||||
xs = 12
|
||||
@ -50,12 +61,11 @@ public val ThreeCanvasWithControls: (props: ThreeCanvasWithControlsProps) -> dyn
|
||||
child(ThreeCanvasComponent) {
|
||||
attrs {
|
||||
this.context = props.context
|
||||
this.solid = props.solid as? Solid
|
||||
this.solid = props.solid
|
||||
this.selected = selected
|
||||
this.options = options
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
ringCol {
|
||||
attrs {
|
||||
@ -67,11 +77,14 @@ public val ThreeCanvasWithControls: (props: ThreeCanvasWithControlsProps) -> dyn
|
||||
styledDiv {
|
||||
css {
|
||||
padding(top = 4.px)
|
||||
width = 100.pct
|
||||
//border(1.px, BorderStyle.solid, Color.lightGray)
|
||||
height = 100.pct
|
||||
overflowY = Overflow.auto
|
||||
}
|
||||
ringThreeControls(options, props.solid, selected, onSelect)
|
||||
ringThreeControls(options, props.solid, selected, onSelect) {
|
||||
props.additionalTabs?.forEach { (title, builder) ->
|
||||
ringTab(title, title, builder)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ import space.kscience.visionforge.solid.Solid
|
||||
import space.kscience.visionforge.solid.three.ThreePlugin
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
public class ThreeWithControls : AbstractPlugin(), ElementVisionRenderer {
|
||||
public class ThreeWithControlsPlugin : AbstractPlugin(), ElementVisionRenderer {
|
||||
public val three: ThreePlugin by require(ThreePlugin)
|
||||
|
||||
override val tag: PluginTag get() = Companion.tag
|
||||
@ -27,7 +27,7 @@ public class ThreeWithControls : AbstractPlugin(), ElementVisionRenderer {
|
||||
react.dom.render(element) {
|
||||
child(ThreeCanvasWithControls) {
|
||||
attrs {
|
||||
this.context = this@ThreeWithControls.context
|
||||
this.context = this@ThreeWithControlsPlugin.context
|
||||
this.solid = vision as? Solid
|
||||
}
|
||||
}
|
||||
@ -41,9 +41,9 @@ public class ThreeWithControls : AbstractPlugin(), ElementVisionRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
public companion object : PluginFactory<ThreeWithControls> {
|
||||
public companion object : PluginFactory<ThreeWithControlsPlugin> {
|
||||
override val tag: PluginTag = PluginTag("vision.threejs.withControls", PluginTag.DATAFORGE_GROUP)
|
||||
override val type: KClass<ThreeWithControls> = ThreeWithControls::class
|
||||
override fun invoke(meta: Meta, context: Context): ThreeWithControls = ThreeWithControls()
|
||||
override val type: KClass<ThreeWithControlsPlugin> = ThreeWithControlsPlugin::class
|
||||
override fun invoke(meta: Meta, context: Context): ThreeWithControlsPlugin = ThreeWithControlsPlugin()
|
||||
}
|
||||
}
|
@ -45,12 +45,7 @@ public class Clipping : Scheme() {
|
||||
}
|
||||
}
|
||||
|
||||
public class Canvas3DOptions : Scheme() {
|
||||
public var axes: Axes by spec(Axes)
|
||||
public var light: Light by spec(Light)
|
||||
public var camera: Camera by spec(Camera)
|
||||
public var controls: Controls by spec(Controls)
|
||||
|
||||
public class CanvasSize : Scheme() {
|
||||
public var minSize: Int by int(400)
|
||||
public var minWith: Number by number { minSize }
|
||||
public var minHeight: Number by number { minSize }
|
||||
@ -59,6 +54,26 @@ public class Canvas3DOptions : Scheme() {
|
||||
public var maxWith: Number by number { maxSize }
|
||||
public var maxHeight: Number by number { maxSize }
|
||||
|
||||
public companion object : SchemeSpec<CanvasSize>(::CanvasSize) {
|
||||
override val descriptor: NodeDescriptor = NodeDescriptor {
|
||||
value(CanvasSize::minSize)
|
||||
value(CanvasSize::minWith)
|
||||
value(CanvasSize::minHeight)
|
||||
value(CanvasSize::maxSize)
|
||||
value(CanvasSize::maxWith)
|
||||
value(CanvasSize::maxHeight)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Canvas3DOptions : Scheme() {
|
||||
public var axes: Axes by spec(Axes)
|
||||
public var light: Light by spec(Light)
|
||||
public var camera: Camera by spec(Camera)
|
||||
public var controls: Controls by spec(Controls)
|
||||
|
||||
public var size: CanvasSize by spec(CanvasSize)
|
||||
|
||||
public var layers: List<Number> by numberList(0)
|
||||
|
||||
public var clipping: Clipping by spec(Clipping)
|
||||
@ -71,30 +86,19 @@ public class Canvas3DOptions : Scheme() {
|
||||
NodeDescriptor {
|
||||
scheme(Canvas3DOptions::axes, Axes)
|
||||
scheme(Canvas3DOptions::light, Light)
|
||||
|
||||
scheme(Canvas3DOptions::camera, Camera) {
|
||||
hide()
|
||||
}
|
||||
|
||||
scheme(Canvas3DOptions::controls, Controls) {
|
||||
hide()
|
||||
}
|
||||
value(Canvas3DOptions::minSize) {
|
||||
hide()
|
||||
}
|
||||
value(Canvas3DOptions::minWith) {
|
||||
hide()
|
||||
}
|
||||
value(Canvas3DOptions::minHeight) {
|
||||
hide()
|
||||
}
|
||||
value(Canvas3DOptions::maxSize) {
|
||||
hide()
|
||||
}
|
||||
value(Canvas3DOptions::maxWith) {
|
||||
hide()
|
||||
}
|
||||
value(Canvas3DOptions::maxHeight) {
|
||||
|
||||
scheme(Canvas3DOptions::size, CanvasSize) {
|
||||
hide()
|
||||
}
|
||||
|
||||
value(Canvas3DOptions::layers) {
|
||||
type(ValueType.NUMBER)
|
||||
multiple = true
|
||||
@ -108,8 +112,8 @@ public class Canvas3DOptions : Scheme() {
|
||||
}
|
||||
}
|
||||
|
||||
public fun Canvas3DOptions.computeWidth(external: Number): Int =
|
||||
public fun CanvasSize.computeWidth(external: Number): Int =
|
||||
(external.toInt()).coerceIn(minWith.toInt()..maxWith.toInt())
|
||||
|
||||
public fun Canvas3DOptions.computeHeight(external: Number): Int =
|
||||
public fun CanvasSize.computeHeight(external: Number): Int =
|
||||
(external.toInt()).coerceIn(minHeight.toInt()..maxHeight.toInt())
|
||||
|
@ -20,6 +20,7 @@ import info.laht.threekt.objects.Mesh
|
||||
import info.laht.threekt.scenes.Scene
|
||||
import org.w3c.dom.Element
|
||||
import org.w3c.dom.HTMLCanvasElement
|
||||
import org.w3c.dom.HTMLElement
|
||||
import org.w3c.dom.Node
|
||||
import org.w3c.dom.events.MouseEvent
|
||||
import space.kscience.dataforge.context.info
|
||||
@ -40,10 +41,8 @@ import kotlin.math.sin
|
||||
public class ThreeCanvas(
|
||||
public val three: ThreePlugin,
|
||||
public val element: Element,
|
||||
public val options: Canvas3DOptions = Canvas3DOptions()
|
||||
public val options: Canvas3DOptions = Canvas3DOptions(),
|
||||
) {
|
||||
|
||||
|
||||
private var boundingBox: Box3? = null
|
||||
private var root: Object3D? = null
|
||||
set(value) {
|
||||
@ -102,40 +101,10 @@ public class ThreeCanvas(
|
||||
antialias = true
|
||||
}.apply {
|
||||
setClearColor(Colors.skyblue, 1)
|
||||
//Clipping planes
|
||||
options.onChange(this@ThreeCanvas) { name, _, _ ->
|
||||
if (name.startsWith(Canvas3DOptions::clipping.name.asName())) {
|
||||
localClippingEnabled = true
|
||||
val clipping = options.clipping
|
||||
if(!clipping.isEmpty()) {
|
||||
boundingBox?.let { boundingBox ->
|
||||
val xClippingPlane = clipping.x?.let {
|
||||
val absoluteValue = boundingBox.min.x + (boundingBox.max.x - boundingBox.min.x) * it
|
||||
Plane(Vector3(-1.0, 0.0, 0.0), absoluteValue)
|
||||
|
||||
}
|
||||
val yClippingPlane = clipping.y?.let {
|
||||
val absoluteValue = boundingBox.min.y + (boundingBox.max.y - boundingBox.min.y) * it
|
||||
Plane(Vector3(0.0, -1.0, 0.0), absoluteValue)
|
||||
}
|
||||
|
||||
val zClippingPlane = clipping.z?.let {
|
||||
val absoluteValue = boundingBox.min.z + (boundingBox.max.z - boundingBox.min.z) * it
|
||||
Plane(Vector3(0.0, 0.0, -1.0), absoluteValue)
|
||||
}
|
||||
clippingPlanes = listOfNotNull(xClippingPlane, yClippingPlane, zClippingPlane).toTypedArray()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
localClippingEnabled = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val canvas = (renderer.domElement as HTMLCanvasElement).apply {
|
||||
className += "three-canvas"
|
||||
width = 600
|
||||
height = 600
|
||||
style.apply {
|
||||
width = "100%"
|
||||
height = "100%"
|
||||
@ -143,35 +112,29 @@ public class ThreeCanvas(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Force camera aspect ration and renderer size recalculation
|
||||
*/
|
||||
private fun updateSize() {
|
||||
val width = element.clientWidth
|
||||
val height = element.clientHeight
|
||||
canvas.width = width
|
||||
canvas.height = height
|
||||
renderer.setSize(width, height, false)
|
||||
camera.aspect = width.toDouble() / height.toDouble()
|
||||
camera.updateProjectionMatrix()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Attach canvas to given [HTMLElement]
|
||||
*/
|
||||
init {
|
||||
check(element.getElementsByClassName("three-canvas").length == 0) {
|
||||
"Three canvas already created in this element"
|
||||
}
|
||||
element.appendChild(canvas)
|
||||
updateSize()
|
||||
}
|
||||
|
||||
/**
|
||||
* Force camera aspect ration and renderer size recalculation
|
||||
*/
|
||||
public fun updateSize() {
|
||||
val width = canvas.clientWidth
|
||||
val height = canvas.clientHeight
|
||||
canvas.style.apply {
|
||||
minWidth = "${options.minWith.toInt()}px"
|
||||
maxWidth = "${options.maxWith.toInt()}px"
|
||||
minHeight = "${options.minHeight.toInt()}px"
|
||||
maxHeight = "${options.maxHeight.toInt()}px"
|
||||
}
|
||||
renderer.setSize(width, height, false)
|
||||
camera.aspect = width.toDouble() / height.toDouble()
|
||||
camera.updateProjectionMatrix()
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach canvas to given [HTMLElement]
|
||||
*/
|
||||
init {
|
||||
canvas.addEventListener("pointerdown", {
|
||||
val picked = pick()
|
||||
options.onSelect?.invoke(picked?.fullName())
|
||||
@ -186,7 +149,7 @@ public class ThreeCanvas(
|
||||
}
|
||||
}, false)
|
||||
|
||||
canvas.onresize = {
|
||||
(element as? HTMLElement)?.onresize = {
|
||||
updateSize()
|
||||
}
|
||||
|
||||
@ -203,6 +166,43 @@ public class ThreeCanvas(
|
||||
|
||||
renderer.render(scene, camera)
|
||||
}
|
||||
|
||||
//Clipping planes
|
||||
options.onChange(this@ThreeCanvas) { name, _, _ ->
|
||||
if (name.startsWith(Canvas3DOptions::clipping.name.asName())) {
|
||||
val clipping = options.clipping
|
||||
if (!clipping.isEmpty()) {
|
||||
renderer.localClippingEnabled = true
|
||||
boundingBox?.let { boundingBox ->
|
||||
val xClippingPlane = clipping.x?.let {
|
||||
val absoluteValue = boundingBox.min.x + (boundingBox.max.x - boundingBox.min.x) * it
|
||||
Plane(Vector3(-1.0, 0.0, 0.0), absoluteValue)
|
||||
|
||||
}
|
||||
val yClippingPlane = clipping.y?.let {
|
||||
val absoluteValue = boundingBox.min.y + (boundingBox.max.y - boundingBox.min.y) * it
|
||||
Plane(Vector3(0.0, -1.0, 0.0), absoluteValue)
|
||||
}
|
||||
|
||||
val zClippingPlane = clipping.z?.let {
|
||||
val absoluteValue = boundingBox.min.z + (boundingBox.max.z - boundingBox.min.z) * it
|
||||
Plane(Vector3(0.0, 0.0, -1.0), absoluteValue)
|
||||
}
|
||||
renderer.clippingPlanes = listOfNotNull(xClippingPlane, yClippingPlane, zClippingPlane).toTypedArray()
|
||||
}
|
||||
} else {
|
||||
renderer.localClippingEnabled = false
|
||||
}
|
||||
} else if (name.startsWith(Canvas3DOptions::size.name.asName())) {
|
||||
canvas.style.apply {
|
||||
minWidth = "${options.size.minWith.toInt()}px"
|
||||
maxWidth = "${options.size.maxWith.toInt()}px"
|
||||
minHeight = "${options.size.minHeight.toInt()}px"
|
||||
maxHeight = "${options.size.maxHeight.toInt()}px"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user