How to use SVG with kotlin-react

时间:2018-02-03 10:33:45

标签: reactjs kotlin

Hi could someone help me how use SVGs with Kotlin React.

I'd like to achieve similar thing as with following example using react and javascript:

const MyComponent = ({radius, color}) => (
  <svg width={radius * 2} height={radius * 2}>
    <circle cx={radius} cy={radius} r={radius} fill=  {color}/>
  </svg>
)

Unfortunately I haven't been able to find by myself any example or sufficient documentation.

Using Kotlin i don't know what language features I could use to achieve the same. Could anyone help me to fill following snippet using Kotlin?

fun RBuilder.MyComponent(radius: Int, color: String) {
  svg {
     ...
  }
}

Thanks a lot.

2 个答案:

答案 0 :(得分:5)

在撰写本文时,Kotlin似乎没有与kotlinx.html类似的svg库。 话虽如此,通过对kotlin-react和kotlinx.html交互的方式进行反向工程,可以在kotlin-react中创建任意xml。 或者只是使用基本的react函数。

方法1:使用kotlinx.html

import kotlinx.html.HTMLTag 
import react.*
import react.dom.*

// a custom tag builder, reuses the tag(...) function from kotlin-react and HTMLTag from kotlinx.html
inline fun RBuilder.custom(tagName: String, block: RDOMBuilder<HTMLTag>.() -> Unit): ReactElement = tag(block) {
    HTMLTag(tagName, it, mapOf(), null, true, false) // I dont know yet what the last 3 params mean... to lazy to look it up
}

// example use
inline fun RBuilder.mySVG(animTime: Double) {
    svg() {
        attrs["width"] = "800"
        attrs["height"] = "600"
        attrs["viewBox"] = "0 0 800 600"

        custom("circle") {
            attrs["cx"] = 150
            attrs["cy"] = 150
            attrs["r"] = 50.0 + sin(animTime) * 50.0
            attrs["style"] = object {
                val stroke = "black"
                val fill = "red"
            }
        }
    }
}

方法2:使用react.dom中的childcreateElement

open class CircleProps (
    val cx: Int,
    val cy: Int,
    val r: Int,
    val stroke: String,
    val fill: String,
    val strokeWidth: Int
    ): RProps {
}

inline fun RBuilder.mySVG2(animTime: Double) {
svg() {
    attrs["width"] = "800"
    attrs["height"] = "600"
    attrs["viewBox"] = "0 0 800 600"

    child(createElement("circle", CircleProps(150,150, 50.0 + sin(animTime) * 50.0, "black", "blue", 3)))
}

答案 1 :(得分:0)

我不确定如何在Kotlin / React文件中编写SVG内联,但JetBrain自己的示例显示how to load an external SVG file in Kotlin-React

@JsModule("src/logo/react.svg")
external val reactLogo: dynamic
@JsModule("src/logo/kotlin.svg")
external val kotlinLogo: dynamic

fun RBuilder.logo(height: Int = 100) {
    div("Logo") {
        attrs.jsStyle.height = height
        img(alt = "React logo.logo", src = reactLogo, classes = "Logo-react") {}
        img(alt = "Kotlin logo.logo", src = kotlinLogo, classes = "Logo-kotlin") {}
    }
}

如果您确实想要如何内联,请将此解决方案发布回社区,谢谢。