Score
0
Watch 11 Star 58 Fork 13

prostory / AndroidZdogKotlinMIT

Join us
Explore and code with more than 2 million developers,Free private repositories !:)
Sign up
Android平台上的伪3D图形动画引擎Zdog,使用kotlin编写 spread retract

https://gitee.com/prostory/AndroidZdog

Clone or download
Cancel
Notice: Creating folder will generate an empty file .keep, because not support in Git
Loading...
README.md

AndroidZdog

Porting Zdog(Round, flat, designer-friendly pseudo-3D engine for canvas) to Android with kotlin

Table of content

Getting started

Gradle

Step 1. Add the JitPack repository to your build file

Add it in your root build.gradle at the end of repositories:

	allprojects {
		repositories {
			...
			maven { url 'https://jitpack.io' }
		}
	}

Step 2. Add the dependency

	dependencies {
	        implementation 'com.github.prostory:AndroidZdog:v1.0.0'
	}

Maven

Step 1. Add the JitPack repository to your build file

	<repositories>
		<repository>
		    <id>jitpack.io</id>
		    <url>https://jitpack.io</url>
		</repository>
	</repositories>

Step 2. Add the dependency

	<dependency>
	    <groupId>com.github.prostory</groupId>
	    <artifactId>AndroidZdog</artifactId>
	    <version>v1.0.0</version>
	</dependency>

What can it do?

Simple graphics and animation

Basic Shapes Extended Features Dynamic icons
basic shapes extended features dynamic icons

More complex graphics and animations

Day Night Rotate
day night rotate

Usage

Contrast with Zdog

  • Line

    • For Zdog

      // line
      new Zdog.Shape({
        addTo: illo,
        path: [
          { x: -40 }, // start at 1st point
          { x:  40 }, // line to 2nd point
        ],
        stroke: 20,
        color: '#636',
      });
      // z-shape
      new Zdog.Shape({
        addTo: illo,
        path: [
          { x: -32, y: -40 }, // start at top left
          { x:  32, y: -40 }, // line to top right
          { x: -32, y:  40 }, // line to bottom left
          { x:  32, y:  40 }, // line to bottom right
        ],
        closed: false,
        stroke: 20,
        color: '#636',
      });
      // 3D shape
      new Zdog.Shape({
        addTo: illo,
        path: [
          { x: -32, y: -40, z:  40 },
          { x:  32, y: -40 },
          { x:  32, y:  40, z:  40 },
          { x:  32, y:  40, z: -40 },
        ],
        closed: false,
        stroke: 20,
        color: '#636',
      });
    • For AndroidZdog

      // line
      shape {
          addTo = illo
          path(
              move(x = -40f), // start at 1st point
              line(x = 40f)   // line to 2nd point
          )
          stroke = 20f
          color = "#636"
      }
      // z-shape
      shape {
          addTo = illo
          path(
              move(x = -32f, y = -40f), // start at top left
              line(x = 32f, y = -40f),  // line to top right
              line(x = -32f, y = 40f),  // line to bottom left
              line(x = 32f, y = 40f)    // line to bottom right
          )
          closed = false
          stroke = 20f
          color = "#636"
      }
      // 3D shape
      shape {
          addTo = illo
          path(
              move(x = -32f, y = -40f, z = 40f),
              line(x = 32f, y = -40f),
              line(x = 32f, y = 40f, z = 40f),
              line(x = 32f, y = 40f, z = -40f)
          )
          closed = false
          stroke = 20f
          color = "#636"
      }
    • Shapes

      line z-shape 3D shape
      line line line
  • Arc

    • For Zdog

      new Zdog.Shape({
        addTo: illo,
        path: [
          { x: -60, y: -60 },   // start
          { arc: [
            { x:  20, y: -60 }, // corner
            { x:  20, y:  20 }, // end point
          ]},
          { arc: [ // start next arc from last end point
            { x:  20, y:  60 }, // corner
            { x:  60, y:  60 }, // end point
          ]},
        ],
        closed: false,
        stroke: 20,
        color: '#636'
      });
    • For AndroidZdog

      shape {
          addTo = illo
          path(
              move(x = -60f, y = -60f),		// start
              arc(
                  vector(x = 20f, y = -60f),	// corner
                  vector(x = 20f, y = 20f)	// end point
              ),
              arc(				// start next arc from last end point
                  vector(x = 20f, y = 60f),	// corner
                  vector(x = 60f, y = 60f)	// end point
              )
          )
          closed = false
          stroke = 20f
          color = "#636"
      }
    • Shapes

      arc

  • Bezier

    • For Zdog

      new Zdog.Shape({
        addTo: illo,
        path: [
          { x: -60, y: -60 },   // start
          { bezier: [
            { x:  20, y: -60 }, // start control point
            { x:  20, y:  60 }, // end control point
            { x:  60, y:  60 }, // end point
          ]},
        ],
        closed: false,
        stroke: 20,
        color: '#636'
      });
    • For AndroidZdog

      shape {
          addTo = illo
          path(
              move(x = -60f, y = -60f),		// start
              bezier(
                  vector(x = 20f, y = -60f),	// start control point
                  vector(x = 20f, y = 60f),	// end control point
                  vector(x = 60f, y = 60f)	// end point
              )
          )
          closed = false
          stroke = 20f
          color = "#636"
      }
    • Shapes

      bezier

  • Closed

    • For Zdog

      // Closed
      new Zdog.Shape({
        addTo: illo,
        path: [ // triangle
          { x:   0, y: -40 },
          { x:  40, y:  40 },
          { x: -40, y:  40 },
        ],
        // closed by default
        stroke: 20,
        color: '#636'
      });
      // Unclosed
      new Zdog.Shape({
        addTo: illo,
        path: [
          { x:   0, y: -40 },
          { x:  40, y:  40 },
          { x: -40, y:  40 },
        ],
        closed: false, // unclosed
        stroke: 20,
        color: '#636'
      });
    • For AndroidZdog

      // Closed
      shape {
          addTo = illo
          path( // triangle
              move(x = 0f, y = -40f),
              line(x = 40f, y = 40f),
              line(x = -40f, y = 40f)
          )
          // closed by default
          stroke = 20f
          color = "#636"
      }
      // Unclosed
      shape {
          addTo = illo
          path( // triangle
              move(x = 0f, y = -40f),
              line(x = 40f, y = 40f),
              line(x = -40f, y = 40f)
          )
          closed = false // unclosed
          stroke = 20f
          color = "#636"
      }
    • Shapes

      Closed Unclosed
      closed unclosed
  • Hemisphere

    • For Zdog

      let dome = new Zdog.Hemisphere({
        addTo: illo,
        diameter: 120,
        // fill enabled by default
        // disable stroke for crisp edge
        stroke: false,
        color: '#C25',
        backface: '#EA0',
      });
    • For AndroidZdog

      val demo = hemisphere {
          addTo = illo
          diameter = 120f
          // fill enabled by default
        	// disable stroke for crisp edge
          stroke = 0f // zero for no stroke
          color = "#C25"
          backface = "#EA0"
      }
    • Shapes

      hemisphere

  • Cone

    • For Zdog

      let partyHat = new Zdog.Cone({
        addTo: illo,
        diameter: 70,
        length: 90,
        stroke: false,
        color: '#636',
        backface: '#C25',
      });
    • For AndroidZdog

      val partyHat = cone {
          addTo = illo
          diameter = 70f
          length = 90f
          stroke = 0f // zero for no stroke
          color = "#636"
          backface = "#C25"
      }
    • Shapes

      cone

  • Cylinder

    • For Zdog

      let can = new Zdog.Cylinder({
        addTo: illo,
        diameter: 80,
        length: 120,
        stroke: false,
        color: '#C25',
        frontFace: '#EA0',
        backface: '#636',
      });
    • For AndroidZdog

      val can = cylinder {
          addTo = illo
          diameter = 80f
          length = 120f
          stroke = 0f // zero for no stroke
          color = "#C25"
          frontFace = "#EA0"
          backface = "#636"
      }
    • Shapes

      cylinder

  • Box

    • For Zdog

      let box = new Zdog.Box({
        addTo: illo,
        width: 120,
        height: 100,
        depth: 80,
        stroke: false,
        color: '#C25', // default face color
        leftFace: '#EA0',
        rightFace: '#E62',
        topFace: '#ED0',
        bottomFace: '#636',
      });
    • For AndroidZdog

      val box = box {
          addTo = illo
          width = 120f
          height = 100f
          depth = 80f
          stroke = 0f
          color = "#C25" // default face color
          leftFace = "#EA0"
          rightFace = "#E62"
          topFace = "#ED0"
          bottomFace = "#636"
      }
    • Shapes

      box

  • Z-fighting

    • For Zdog

      const distance = 40;
      
      let dot = new Zdog.Shape({
        addTo: illo,
        translate: { y: -distance },
        stroke: 80,
        color: '#636',
      });
      dot.copy({
        translate: { x: -distance },
        color: '#EA0',
      });
      dot.copy({
        translate: { z: distance },
        color: '#C25',
      });
      dot.copy({
        translate: { x: distance },
        color: '#E62',
      });
      dot.copy({
        translate: { z: -distance },
        color: '#C25',
      });
      dot.copy({
        translate: { y: distance },
      });
    • For AndroidZdog

      val distance = 40f
      
      val dot = shape {
          addTo = illo
          translate(y = -distance)
          stroke = 80f
          color = "#636"
      }
      dot.copy {
          translate(x = -distance)
          color = "#EA0"
      }
      dot.copy {
          translate(z = distance)
          color = "#C25"
      }
      dot.copy {
          translate(x = distance)
          color = "#E62"
      }
      dot.copy {
          translate(z = -distance)
          color = "#C25"
      }
      dot.copy {
          translate(y = distance)
      }
    • Shapes

      z-fighting

Display shapes in ImageView

It's very simple to display Shapes in ImageView. You just need to create shapes, add shapes to ZdogDrawable, and then call the setImageDrawable method of ImageView to display ZdogDrawable.

// Attach shapes to ZdogDrawable and set animations
val drawable = ZdogDrawable().apply { 
    // Create a shape 
    shape {
        addTo = illo // add to ZdogDrawable
        path(
            move(x = -32f, y = -40f),
            line(x = 32f, y = -40f),
            line(x = -32f, y = 40f),
            line(x = 32f, y = 40f)
        )
        closed = false
        stroke = 20f
        color = "#636"
    }
    // Set animations, rotate the Illustration
    play(illo.rotateTo(y = TAU.toFloat()).duration(3000).repeat())
}

// Attach ZdogDrawable to ImageView
imageView.setImageDrawable(drawable)

// Start animation
drawable.start()

Final display effect:

z shape

Extended features

We can also use the powerful features of Android Canvas to achieve some cool effects that can't be achieved in Zdog. Here I extend the following features. Through the combination of these features, you can achieve many cool effects.

Segment

It allows shapes to display only part of the image.

ZdogDrawable().apply {
    illo.alpha(0f) // Set background transparent
    val line = shape { // Create a shape
        addTo = illo // Add to drawable
        path(
            move(x = -32f, y = -40f),
            line(x = 32f, y = -40f),
            line(x = -32f, y = 40f),
            line(x = 32f, y = 40f)
        )
        closed = false
        stroke = 20f
        color = "#636"
        updateSegment(0f, 0f) // Set segement 0
    }

    play(line.animate {
        onReset {
            line.updateSegment(0f, 1f) // Set segement 0-1, When the animation ends
        }

        update {
            line.updateSegment(0f, it) // Update segment by fraction
        }
    }.duration(1500).interpolator(FastOutSlowInInterpolator()).toReverse())
}

segment

Path Effect

It allows lines to be displayed in different effects, such as dashed lines.

ZdogDrawable().apply {
    illo.alpha(0f)
    shape { // A dot at (-90, 0, 0)
        addTo = illo
        path(
            move(-90f),
            line(-90f)
        )
        color = "#FD4"
        stroke = 16f
    }

    shape { // A dot at (90, 0, 0)
        addTo = illo
        path(
            move(90f),
            line(90f)
        )
        color = "#FD4"
        stroke = 16f
    }

    shape { // Create a half circle
        addTo = illo
        path(
            move(-90f, 0f),
            arc(
                vector(-90f, -90f),
                vector(0f, -90f)
            ),
            arc(
                vector(90f, -90f),
                vector(90f, 0f)
            )
        )
        translate { z = -8f }
        color = "#636"
        effect = DashPathEffect(floatArrayOf(20f, 10f), 0f) // Set dotted line effect
        stroke = 4f
        closed = false
    }

    illo.rotate { z = -(TAU / 8).toFloat() }
    play(
        illo.rotateBy(z = (TAU / 4).toFloat()).duration(1500)
            .interpolator(OvershootInterpolator()).toReverse()
    )
}

path effect

Gradient

It can fill shapes with gradient colors.

ZdogDrawable().apply {
    illo.alpha(0f)
    shape {
        addTo = illo
        path(
            move(-90f, 0f),
            arc(
                vector(-90f, 90f),
                vector(0f, 90f)
            ),
            arc(
                vector(90f, 90f),
                vector(90f, 0f)
            )
        )
        // Set a Vertical Linear Gradient from (0, 90) to (0, 0)
        shader = LinearGradient(
            0f, 90f, 0f, 0f,
            "#636".color, Color.TRANSPARENT, Shader.TileMode.CLAMP
        ) 
        fill = true
        stroke = 0f
        closed = false
    }

    illo.rotate { z = (TAU / 8).toFloat() }
    play(
        illo.rotateBy(z = -(TAU / 4).toFloat()).duration(1500)
            .interpolator(OvershootInterpolator()).toReverse()
    )
}

gradient

Shadow

It adds shadows to shapes.

ZdogDrawable().apply {
    illo.alpha(0f)
    shape {
        addTo = illo
        path(
            move(-90f, 0f),
            arc(
                vector(-90f, 90f),
                vector(0f, 90f)
            ),
            arc(
                vector(90f, 90f),
                vector(90f, 0f)
            )
        )
        color = "#fff"
        // Set a Shader Layer witch radius is 16
        layer = ShaderLayer(
            16f, 0f, 0f,
            Colors.shader.colour
        )
        stroke = 8f
        closed = false
    }

    illo.rotate { z = (TAU / 8).toFloat() }
    play(
        illo.rotateBy(z = -(TAU / 4).toFloat()).duration(1500)
            .interpolator(OvershootInterpolator()).toReverse()
    )
}

shadow

Path Animation

It allows the shape to move along a path.

ZdogDrawable().apply {
    illo.alpha(0f)
    val dotted = shape {
        addTo = illo
        path(
            move(-90f, 0f),
            arc(
                vector(-90f, -90f),
                vector(0f, -90f)
            ),
            arc(
                vector(90f, -90f),
                vector(90f, 0f)
            )
        )
        translate { z = -8f }
        color = "#636"
        effect = DashPathEffect(floatArrayOf(20f, 10f), 0f)
        stroke = 4f
        closed = false
    }

    // Get dotted path
    val keyframes =
        PathKeyframes(illo.renderToPath(dotted))
    val xFrames = keyframes.createXFloatKeyframes()
    val yFrames = keyframes.createYFloatKeyframes()

    val dot = shape {
        addTo = illo
        color = "#FD4"
        stroke = 16f

        translate {
            x = xFrames.getFloatValue(0f)
            y = yFrames.getFloatValue(0f)
        }
    }

    play(
        // Let the dot move along the dotted line
        dot.animate {
            onReset {
                dot.translate {
                    x = xFrames.getFloatValue(0f)
                    y = yFrames.getFloatValue(0f)
                }
            }

            update {
                dot.translate {
                    x = xFrames.getFloatValue(it)
                    y = yFrames.getFloatValue(it)
                }
            }
        }.duration(1500).interpolator(FastOutSlowInInterpolator())
            .toReverse()
    )
}

path_animation

Real-time update path

It can update the path to change the shape in animations.

ZdogDrawable().apply {
    illo.alpha(0f)
    val arrow = shape {
        addTo = illo
        path(
            move(-80f, 40f),
            line(0f, -40f),
            line(80f, 40f)
        )
        color = "#fff"
        stroke = 10f
        layer = ShaderLayer(
            16f, 0f, 0f,
            Colors.shader.colour
        )
        closed = false
    }

    // Update the path to change the shape of the arrow
    fun updatePath(shape: Shape, top: Float) {
        shape.apply {
            path[0].point().y = -top
            path[1].point().y = top
            path[2].point().y = -top
        }
    }

    play(arrow.animate {
        onReset {
            updatePath(arrow, 40f)
        }

        update {
            updatePath(arrow, -40f + it * 80f)
        }
    }.duration(1500).toReverse())
}

update path

Comments ( 2 )

Sign in for post a comment

Kotlin
1
https://gitee.com/prostory/AndroidZdog.git
git@gitee.com:prostory/AndroidZdog.git
prostory
AndroidZdog
AndroidZdog
master

Help Search