Shagen Ogandzhanian
3 years ago
2 changed files with 396 additions and 0 deletions
@ -0,0 +1,138 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers. |
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
||||||
|
*/ |
||||||
|
|
||||||
|
package org.jetbrains.compose.web.css |
||||||
|
|
||||||
|
import org.jetbrains.compose.web.ExperimentalComposeWebApi |
||||||
|
|
||||||
|
fun interface TransformFunction { |
||||||
|
fun apply(): String |
||||||
|
} |
||||||
|
|
||||||
|
interface TransformBuilder { |
||||||
|
fun matrix(a: Number, b: Number, c: Number, d: Number, tx: Number, ty: Number): Boolean |
||||||
|
fun matrix3d( |
||||||
|
a1: Number, b1: Number, c1: Number, d1: Number, |
||||||
|
a2: Number, b2: Number, c2: Number, d2: Number, |
||||||
|
a3: Number, b3: Number, c3: Number, d3: Number, |
||||||
|
a4: Number, b4: Number, c4: Number, d4: Number |
||||||
|
): Boolean |
||||||
|
|
||||||
|
fun perspective(d: CSSLengthValue): Boolean |
||||||
|
fun rotate(a: CSSAngleValue): Boolean |
||||||
|
fun rotate3d(x: Number, y: Number, z: Number, a: CSSAngleValue): Boolean |
||||||
|
fun rotateX(a: CSSAngleValue): Boolean |
||||||
|
fun rotateY(a: CSSAngleValue): Boolean |
||||||
|
fun rotateZ(a: CSSAngleValue): Boolean |
||||||
|
fun scale(sx: Number): Boolean |
||||||
|
fun scale(sx: Number, sy: Number): Boolean |
||||||
|
fun scale3d(sx: Number, sy: Number, sz: Number): Boolean |
||||||
|
fun scaleX(s: Number): Boolean |
||||||
|
fun scaleY(s: Number): Boolean |
||||||
|
fun scaleZ(s: Number): Boolean |
||||||
|
fun skew(ax: CSSAngleValue): Boolean |
||||||
|
fun skew(ax: CSSAngleValue, ay: CSSAngleValue): Boolean |
||||||
|
fun skewX(a: CSSAngleValue): Boolean |
||||||
|
fun skewY(a: CSSAngleValue): Boolean |
||||||
|
fun translate(tx: CSSLengthValue): Boolean |
||||||
|
fun translate(tx: CSSPercentageValue): Boolean |
||||||
|
fun translate(tx: CSSLengthValue, ty: CSSLengthValue): Boolean |
||||||
|
fun translate(tx: CSSLengthValue, ty: CSSPercentageValue): Boolean |
||||||
|
fun translate(tx: CSSPercentageValue, ty: CSSLengthValue): Boolean |
||||||
|
fun translate(tx: CSSPercentageValue, ty: CSSPercentageValue): Boolean |
||||||
|
fun translate3d(tx: CSSLengthValue, ty: CSSLengthValue, tz: CSSLengthValue): Boolean |
||||||
|
fun translate3d(tx: CSSLengthValue, ty: CSSPercentageValue, tz: CSSLengthValue): Boolean |
||||||
|
fun translate3d(tx: CSSPercentageValue, ty: CSSLengthValue, tz: CSSLengthValue): Boolean |
||||||
|
fun translate3d(tx: CSSPercentageValue, ty: CSSPercentageValue, tz: CSSLengthValue): Boolean |
||||||
|
fun translateX(tx: CSSLengthValue): Boolean |
||||||
|
fun translateX(tx: CSSPercentageValue): Boolean |
||||||
|
fun translateY(ty: CSSLengthValue): Boolean |
||||||
|
fun translateY(ty: CSSPercentageValue): Boolean |
||||||
|
fun translateZ(tz: CSSLengthValue): Boolean |
||||||
|
} |
||||||
|
|
||||||
|
private class TransformBuilderImplementation : TransformBuilder { |
||||||
|
private val transformations = mutableListOf<TransformFunction>() |
||||||
|
|
||||||
|
override fun matrix(a: Number, b: Number, c: Number, d: Number, tx: Number, ty: Number) = |
||||||
|
transformations.add { "matrix($a, $b, $c, $d, $tx, $ty)" } |
||||||
|
|
||||||
|
override fun matrix3d( |
||||||
|
a1: Number, b1: Number, c1: Number, d1: Number, |
||||||
|
a2: Number, b2: Number, c2: Number, d2: Number, |
||||||
|
a3: Number, b3: Number, c3: Number, d3: Number, |
||||||
|
a4: Number, b4: Number, c4: Number, d4: Number |
||||||
|
) = |
||||||
|
transformations.add { "matrix3d($a1, $b1, $c1, $d1, $a2, $b2, $c2, $d2, $a3, $b3, $c3, $d3, $a4, $b4, $c4, $d4)" } |
||||||
|
|
||||||
|
override fun perspective(d: CSSLengthValue) = transformations.add { "perspective($d)" } |
||||||
|
|
||||||
|
override fun rotate(a: CSSAngleValue) = transformations.add { "rotate($a)" } |
||||||
|
override fun rotate3d(x: Number, y: Number, z: Number, a: CSSAngleValue) = |
||||||
|
transformations.add({ "rotate3d($x, $y, $z, $a)" }) |
||||||
|
|
||||||
|
override fun rotateX(a: CSSAngleValue) = transformations.add { "rotateX($a)" } |
||||||
|
override fun rotateY(a: CSSAngleValue) = transformations.add { "rotateY($a)" } |
||||||
|
override fun rotateZ(a: CSSAngleValue) = transformations.add { "rotateZ($a)" } |
||||||
|
|
||||||
|
override fun scale(sx: Number) = transformations.add { "scale($sx)" } |
||||||
|
override fun scale(sx: Number, sy: Number) = transformations.add { "scale($sx, $sy)" } |
||||||
|
override fun scale3d(sx: Number, sy: Number, sz: Number) = |
||||||
|
transformations.add { "scale3d($sx, $sy, $sz)" } |
||||||
|
|
||||||
|
override fun scaleX(s: Number) = transformations.add { "scaleX($s)" } |
||||||
|
override fun scaleY(s: Number) = transformations.add { "scaleY($s)" } |
||||||
|
override fun scaleZ(s: Number) = transformations.add { "scaleZ($s)" } |
||||||
|
|
||||||
|
override fun skew(ax: CSSAngleValue) = transformations.add { "skew($ax)" } |
||||||
|
override fun skew(ax: CSSAngleValue, ay: CSSAngleValue) = transformations.add { "skew($ax, $ay)" } |
||||||
|
override fun skewX(a: CSSAngleValue) = transformations.add { "skewX($a)" } |
||||||
|
override fun skewY(a: CSSAngleValue) = transformations.add { "skewY($a)" } |
||||||
|
|
||||||
|
override fun translate(tx: CSSLengthValue) = transformations.add { "translate($tx)" } |
||||||
|
override fun translate(tx: CSSPercentageValue) = transformations.add { "translate($tx)" } |
||||||
|
|
||||||
|
override fun translate(tx: CSSLengthValue, ty: CSSLengthValue) = |
||||||
|
transformations.add { "translate($tx, $ty)" } |
||||||
|
|
||||||
|
override fun translate(tx: CSSLengthValue, ty: CSSPercentageValue) = |
||||||
|
transformations.add { "translate($tx, $ty)" } |
||||||
|
|
||||||
|
override fun translate(tx: CSSPercentageValue, ty: CSSLengthValue) = |
||||||
|
transformations.add { "translate($tx, $ty)" } |
||||||
|
|
||||||
|
override fun translate(tx: CSSPercentageValue, ty: CSSPercentageValue) = |
||||||
|
transformations.add { "translate($tx, $ty)" } |
||||||
|
|
||||||
|
override fun translate3d(tx: CSSLengthValue, ty: CSSLengthValue, tz: CSSLengthValue) = |
||||||
|
transformations.add { "translate3d($tx, $ty, $tz)" } |
||||||
|
|
||||||
|
override fun translate3d(tx: CSSLengthValue, ty: CSSPercentageValue, tz: CSSLengthValue) = |
||||||
|
transformations.add { "translate3d($tx, $ty, $tz)" } |
||||||
|
|
||||||
|
override fun translate3d(tx: CSSPercentageValue, ty: CSSLengthValue, tz: CSSLengthValue) = |
||||||
|
transformations.add { "translate3d($tx, $ty, $tz)" } |
||||||
|
|
||||||
|
override fun translate3d(tx: CSSPercentageValue, ty: CSSPercentageValue, tz: CSSLengthValue) = |
||||||
|
transformations.add { "translate3d($tx, $ty, $tz)" } |
||||||
|
|
||||||
|
override fun translateX(tx: CSSLengthValue) = transformations.add { "translateX($tx)" } |
||||||
|
override fun translateX(tx: CSSPercentageValue) = transformations.add { "translateX($tx)" } |
||||||
|
|
||||||
|
override fun translateY(ty: CSSLengthValue) = transformations.add { "translateY($ty)" } |
||||||
|
override fun translateY(ty: CSSPercentageValue) = transformations.add { "translateY($ty)" } |
||||||
|
|
||||||
|
override fun translateZ(tz: CSSLengthValue) = transformations.add { "translateZ($tz)" } |
||||||
|
|
||||||
|
override fun toString(): String { |
||||||
|
return transformations.joinToString(" ") { it.apply() } |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@ExperimentalComposeWebApi |
||||||
|
fun StyleBuilder.transform(transformFunction: TransformBuilder.() -> Unit) { |
||||||
|
val transformBuilder = TransformBuilderImplementation() |
||||||
|
property("transform", transformBuilder.apply(transformFunction).toString()) |
||||||
|
} |
@ -0,0 +1,258 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers. |
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
||||||
|
*/ |
||||||
|
package org.jetbrains.compose.web.core.tests.css |
||||||
|
|
||||||
|
import org.jetbrains.compose.web.ExperimentalComposeWebApi |
||||||
|
import org.jetbrains.compose.web.core.tests.runTest |
||||||
|
import org.jetbrains.compose.web.css.* |
||||||
|
import org.jetbrains.compose.web.dom.Div |
||||||
|
import kotlin.test.Test |
||||||
|
import kotlin.test.assertEquals |
||||||
|
|
||||||
|
@ExperimentalComposeWebApi |
||||||
|
class TransformTests { |
||||||
|
@Test |
||||||
|
fun matrix() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { matrix(1, 2, -1, 1, 80, 80) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("matrix(1, 2, -1, 1, 80, 80)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun matrix3d() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { matrix3d(1, 0, 0, 0, 0, 1, 6, 0, 0, 0, 1, 0, 50, 100, 0, 1.1) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("matrix3d(1, 0, 0, 0, 0, 1, 6, 0, 0, 0, 1, 0, 50, 100, 0, 1.1)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun perspective() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { perspective(3.cm) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("perspective(3cm)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun rotate() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { rotate(3.deg) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("rotate(3deg)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun rotate3d() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { rotate3d(1, 1, 0, 2.deg) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("rotate3d(1, 1, 0, 2deg)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun rotateX() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { rotateX(60.deg) } } }) |
||||||
|
Div({ style { transform { rotateX(-0.25.turn) } } }) |
||||||
|
Div({ style { transform { rotateX(3.14.rad) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("rotateX(60deg)", nextChild().style.transform) |
||||||
|
assertEquals("rotateX(-0.25turn)", nextChild().style.transform) |
||||||
|
assertEquals("rotateX(3.14rad)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun rotateY() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { rotateY(60.deg) } } }) |
||||||
|
Div({ style { transform { rotateY(-0.25.turn) } } }) |
||||||
|
Div({ style { transform { rotateY(3.14.rad) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("rotateY(60deg)", nextChild().style.transform) |
||||||
|
assertEquals("rotateY(-0.25turn)", nextChild().style.transform) |
||||||
|
assertEquals("rotateY(3.14rad)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun rotateZ() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { rotateZ(60.deg) } } }) |
||||||
|
Div({ style { transform { rotateZ(-0.25.turn) } } }) |
||||||
|
Div({ style { transform { rotateZ(3.14.rad) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("rotateZ(60deg)", nextChild().style.transform) |
||||||
|
assertEquals("rotateZ(-0.25turn)", nextChild().style.transform) |
||||||
|
assertEquals("rotateZ(3.14rad)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun scale() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { scale(0.6) } } }) |
||||||
|
Div({ style { transform { scale(0.2, 0.3) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("scale(0.6)", nextChild().style.transform) |
||||||
|
assertEquals("scale(0.2, 0.3)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun scale3d() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { scale3d(0.2, 0.3, 0.1) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("scale3d(0.2, 0.3, 0.1)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun scaleX() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { scaleX(0.5) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("scaleX(0.5)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun scaleY() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { scaleY(0.7) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("scaleY(0.7)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun scaleZ() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { scaleZ(0.12) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("scaleZ(0.12)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun skew() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { skew(2.deg) } } }) |
||||||
|
Div({ style { transform { skew(1.rad, 2.deg) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("skew(2deg)", nextChild().style.transform) |
||||||
|
assertEquals("skew(1rad, 2deg)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun skewX() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { skewX(2.deg) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("skewX(2deg)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun skewY() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { skewY(2.rad) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("skewY(2rad)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun translate() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { translate(10.px) } } }) |
||||||
|
Div({ style { transform { translate(4.percent) } } }) |
||||||
|
Div({ style { transform { translate(2.percent, 10.px) } } }) |
||||||
|
Div({ style { transform { translate(10.px, 3.percent) } } }) |
||||||
|
Div({ style { transform { translate(20.px, 10.px) } } }) |
||||||
|
Div({ style { transform { translate(5.percent, 8.percent) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("translate(10px)", nextChild().style.transform) |
||||||
|
assertEquals("translate(4%)", nextChild().style.transform) |
||||||
|
assertEquals("translate(2%, 10px)", nextChild().style.transform) |
||||||
|
assertEquals("translate(10px, 3%)", nextChild().style.transform) |
||||||
|
assertEquals("translate(20px, 10px)", nextChild().style.transform) |
||||||
|
assertEquals("translate(5%, 8%)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun translate3d() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { translate3d(2.percent, 10.px, 1.em) } } }) |
||||||
|
Div({ style { transform { translate3d(10.px, 3.percent, 2.em) } } }) |
||||||
|
Div({ style { transform { translate3d(20.px, 10.px, 3.em) } } }) |
||||||
|
Div({ style { transform { translate3d(5.percent, 8.percent, 4.em) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("translate3d(2%, 10px, 1em)", nextChild().style.transform) |
||||||
|
assertEquals("translate3d(10px, 3%, 2em)", nextChild().style.transform) |
||||||
|
assertEquals("translate3d(20px, 10px, 3em)", nextChild().style.transform) |
||||||
|
assertEquals("translate3d(5%, 8%, 4em)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Test |
||||||
|
fun translateX() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { translateX(10.px) } } }) |
||||||
|
Div({ style { transform { translateX(4.percent) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("translateX(10px)", nextChild().style.transform) |
||||||
|
assertEquals("translateX(4%)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun translateY() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { translateY(12.px) } } }) |
||||||
|
Div({ style { transform { translateY(3.percent) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("translateY(12px)", nextChild().style.transform) |
||||||
|
assertEquals("translateY(3%)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun translateZ() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { translateZ(7.px) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("translateZ(7px)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun mutliples() = runTest { |
||||||
|
composition { |
||||||
|
Div({ |
||||||
|
style { |
||||||
|
transform { |
||||||
|
perspective(3.cm) |
||||||
|
translate(10.px, 3.px) |
||||||
|
rotateY(3.deg) |
||||||
|
} |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("perspective(3cm) translate(10px, 3px) rotateY(3deg)", nextChild().style.transform) |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue