Git Product home page Git Product logo

Comments (2)

SerVB avatar SerVB commented on May 9, 2024 1

Made some experiments. Sample code:

@Composable
fun example0() {
    val (r, setR) = remember { mutableStateOf(true) }

    val rot = when (r) {
        true -> 45f
        false -> 0f
    }

    Box(Modifier.padding(100.dp).size(50.dp).graphicsLayer(rotationX = rot, rotationY = rot).background(Color.Green).clickable {
        setR(!r)
    }) {
        Text("R")
    }
}

Android:

grafik

Desktop (perspective-ish but still differs):

grafik

It's achieved with the following patch, inspired by the link from the description of this ticket:

Index: compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/SkiaLayer.skiko.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/SkiaLayer.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/SkiaLayer.skiko.kt
--- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/SkiaLayer.skiko.kt	(revision f4b9436637e0391351984ebfa5470ff77051815e)
+++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/SkiaLayer.skiko.kt	(date 1651230735840)
@@ -24,6 +24,7 @@
 import androidx.compose.ui.graphics.Canvas
 import androidx.compose.ui.graphics.ClipOp
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.DefaultCameraDistance
 import androidx.compose.ui.graphics.DefaultShadowColor
 import androidx.compose.ui.graphics.Matrix
 import androidx.compose.ui.graphics.Outline
@@ -205,6 +206,12 @@
             rotateZ(rotationZ)
             scale(scaleX, scaleY)
         }
+
+        val depth = DefaultCameraDistance * 42  // todo: use cameraDistance passed in graphicsLayer (#1129)
+
+        matrix *= Matrix().apply {
+            set(2, 3, -1f / depth)
+        }
         matrix *= Matrix().apply {
             translate(x = pivotX, y = pivotY)
         }

However, I couldn't find the depth that will make the image equal to the Android version, so probably more complex change is needed.

Also, there is some code from https://www.scratchapixel.com/lessons/3d-basic-rendering/perspective-and-orthographic-projection-matrix/opengl-perspective-projection-matrix, probably it can help somehow.

      val angleOfView = 90f
      val near = 0.1f
      val far = 100f
      val imageAspectRatio = size.width.toFloat() / size.height
      val n = near
      val f = far

      // gluPerspective
      val scale = tan(angleOfView * 0.5f * PI.toFloat() / 180f) * n
      val r = imageAspectRatio * scale
      val l = -r
      val t = scale
      val b = -t
      // gluPerspective

      // glFrustum
      val m = Matrix(
          floatArrayOf(
              2 * n / (r - l),
              0f,
              0f,
              0f,

              0f,
              2 * n / (t - b),
              0f,
              0f,

              (r + l) / (r - l),
              (t + b) / (t - b),
              -(f + n) / (f - n),
              -1f,

              0f,
              0f,
              -2 * f * n / (f - n),
              0f,
          )
      )
      // glFrustum

from compose-multiplatform.

 avatar commented on May 9, 2024

I also found it not working correctly.

I tried to achieve an effect like this:
https://codepen.io/iremlopsum/pen/WzKBpE

But the result of my code is somehow random and unexpected.

Sometimes negative values are treated the same way as positive, sometimes it works.
Really strange behaviour.

        val offset = remember { mutableStateOf(Offset.Zero) }
        val size = remember { mutableStateOf(IntSize.Zero) }

        val rotationX = if (offset.value == Offset.Zero)
            0f
        else
            ((offset.value.y / size.value.height) - 0.5f) * 90

        val rotationY = if (offset.value == Offset.Zero)
            0f
        else
            ((offset.value.x / size.value.width) - 0.5f) * 90

        Box(
            modifier = Modifier
                .graphicsLayer(
                    rotationX = rotationX,
                    rotationY = rotationY
                )
                .pointerMoveFilter(
                    onExit = {
                        offset.value = Offset.Zero
                        return@pointerMoveFilter true
                    },
                    onMove = {
                        offset.value = it
                        return@pointerMoveFilter true
                    }
                )
                .onSizeChanged {
                    size.value = it
                }
        ) {

            // The content
        }
    }
}

from compose-multiplatform.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.