Giter Site home page Giter Site logo

wajahatkarim3 / flippable Goto Github PK

View Code? Open in Web Editor NEW
453.0 3.0 33.0 5.28 MB

A Jetpack Compose library for animating a flip transition between the front and back of something, such as a card.

Home Page: https://wajahatkarim3.github.io/Flippable

License: Apache License 2.0

Kotlin 100.00%
jetpack-compose jetpack-android library android-library android android-development kotlin kotlin-android kotlin-library kotlin-coroutines

flippable's Introduction

๐Ÿ’ณ Flippable

A Jetpack Compose utility library to create flipping Composable views with 2 sides.


Built with โค๏ธŽ by Wajahat Karim and contributors


Demo

FlippableDemo.mp4


๐Ÿ’ป Installation

In build.gradle of app module, include this dependency

implementation "com.wajahatkarim:flippable:x.y.z"

Please replace x, y and z with the latest version numbers .

Or you can find latest version and changelogs in the releases.


โ“ Usage

Add the Flippable composable and define the front and back side composable methods inside. That's it.

Flippable(
    frontSide = {
        // Composable content for the front side
    },

    backSide = {
        // Composable content for the back side
    },

    flipController = rememberFlipController(),

    // Other optional parameters
)

The FlippableController allows you to programatically flip the view from any event or button click or any method call etc. There's a method rememberFlipController() to get an instance of FlippableController. If you want to use any key for the remember, you can do so by directly creating FlippableController yourself like the code below:

val flipController = remember { FlippableController() }

val flipController1 = remember(key = "2") { FlippableController() }

๐ŸŽจ Customization Parameters

If you'd like to discover what Flippable offers, here is an exhaustive description of customizable parameters.

    
val controller = rememberFlipController()
    
Flippable(
    frontSide = {
        // Composable content for the front side
    },
    
    backSide = {
        // Composable content for the back side
    },
    
    // To manually controll the flipping, you would need an instance of FlippableController. 
    // You can access it using rememberFlipController() method.
    // This provides methods like controller.flip(), controller.flipToFront(), controller.flipToBack() etc.
    flipController = controller,
    
    // The obvious one - if you have done Jetpack Compose before.
    modifier = Modifier,
    
    // The duration it takes for the flip transition in Milliseconds. Default is 400
    flipDurationMs = 400,
    
    // If true, this will flip the view when touched. 
    // If you want to programatically flip the view without touching, use FlippableController.
    flipOnTouch = flipOnTouchEnabled,
    
    // If false, flipping will be disabled completely. 
    // The flipping will not be triggered with either touch or with controller methods.
    flipEnabled = flipEnabled,
    
    // The Flippable is contained in a Box, so this tells
    // the alignment to organize both Front and Back side composable.
    contentAlignment = Alignment.TopCenter,
    
    //If true, the Flippable will automatically flip back after 
    //duration defined in autoFlipDurationMs. By default, this is false..
    autoFlip = false,
    
    //The duration in Milliseconds after which auto-flip back animation will start. Default is 1 second.
    autoFlipDurationMs = 1000,
    
    // The animation type of flipping effect. Currently there are 4 animations. 
    // Horizontal Clockwise and Anti-Clockwise, Vertical Clockwise and Anti-Clockwise
    // See animation types section below.
    flipAnimationType = FlipAnimationType.HORIZONTAL_CLOCKWISE,
    
    // The [GraphicsLayerScope.cameraDistance] for the flip animation. 
    // Sets the distance along the Z axis (orthogonal to the X/Y plane
    // on which layers are drawn) from the camera to this layer.
    cameraDistance = 30.0F,
    
    // The listener which is triggered when flipping animation is finished.
    onFlippedListener = { currentSide ->
        // This is called when any flip animation is finished. 
        // This gives the current side which is visible now in Flippable.
    }
)

I encourage you to play around with the sample app to get a better look and feel. It showcases advanced usage with customized parameters.


๐Ÿ“„ API Documentation

Visit the API documentation of this library to get more information in detail.


โš™๏ธ Animation Types

Horizontal Clockwise

Kapture 2022-02-15 at 23 20 11

Horizontal Anti-Clockwise

Kapture 2022-02-15 at 23 24 05

Vertical Clockwise

Kapture 2022-02-15 at 23 26 00

Vertical Anti-Clockwise

Kapture 2022-02-15 at 23 26 33


๐Ÿ‘จ Developed By

Wajahat Karim

Twitter Web Medium Linkedin


๐Ÿ‘ How to Contribute

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

๐Ÿ“ƒ License

Copyright 2022 Wajahat Karim

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

flippable's People

Contributors

mcxinyu avatar thomaspoulainconsulting avatar wajahatkarim3 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

flippable's Issues

Update dependencies

It looks like the compose dependencies are very out of date.

we are currently at 1.5.5 but this lib is still depending on 1.1 which has breaking changes between them.

[Feature request] Ability to provide the initial side

Currently, all Flippables start out facing with the front side.

I have encountered a scenario in which it would be desirable to specify which side should be shown first (front or back).
This could be achieved by adding a parameter to the rememberFlipController() and the corresponding FlippableController constructor.

Of course, I can conditionally specify the composables of the front/back sides but that is nothing more than a workaround and it adds unnecessary complexity that has to be managed.

Thanks!

Flippable crashes when attempting to flip the card.

Compose Version = 1.5.7
Kotlin Version = 1.9.21
agpVersion = 8.2.0
Gradle wrapper = 8.5

java.lang.NoSuchMethodError: No virtual method at(Ljava/lang/Object;I)Landroidx/compose/animation/core/KeyframesSpec$KeyframeEntity; in class Landroidx/compose/animation/core/KeyframesSpec$KeyframesSpecConfig; or its super classes (declaration of 'androidx.compose.animation.core.KeyframesSpec$KeyframesSpecConfig')
at com.wajahatkarim.flippable.FlippableKt$Flippable$frontRotation$2$1.invoke(Flippable.kt:167)
at com.wajahatkarim.flippable.FlippableKt$Flippable$frontRotation$2$1.invoke(Flippable.kt:165)
at androidx.compose.animation.core.AnimationSpecKt.keyframes(AnimationSpec.kt:649)
at com.wajahatkarim.flippable.FlippableKt$Flippable$frontRotation$2.invoke(Flippable.kt:165)
at com.wajahatkarim.flippable.FlippableKt$Flippable$frontRotation$2.invoke(Flippable.kt:161)
at com.wajahatkarim.flippable.FlippableKt.Flippable(Flippable.kt:372)
at com.wajahatkarim.flippable.FlippableKt$Flippable$7.invoke(Unknown Source:46)
at com.wajahatkarim.flippable.FlippableKt$Flippable$7.invoke(Unknown Source:10)
at androidx.compose.runtime.RecomposeScopeImpl.compose(RecomposeScopeImpl.kt:192)
at androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd(Composer.kt:2556)
at androidx.compose.runtime.ComposerImpl.skipCurrentGroup(Composer.kt:2827)
at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3314)
at androidx.compose.runtime.ComposerImpl.recompose$runtime_release(Composer.kt:3265)
at androidx.compose.runtime.CompositionImpl.recompose(Composition.kt:938)
at androidx.compose.runtime.Recomposer.performRecompose(Recomposer.kt:1155)
at androidx.compose.runtime.Recomposer.access$performRecompose(Recomposer.kt:127)
at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$1.invoke(Recomposer.kt:583)
at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$1.invoke(Recomposer.kt:551)
at androidx.compose.ui.platform.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame(AndroidUiFrameClock.android.kt:41)
at androidx.compose.ui.platform.AndroidUiDispatcher.performFrameDispatch(AndroidUiDispatcher.android.kt:109)
at androidx.compose.ui.platform.AndroidUiDispatcher.access$performFrameDispatch(AndroidUiDispatcher.android.kt:41)
at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame(AndroidUiDispatcher.android.kt:69)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1337)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1348)
at android.view.Choreographer.doCallbacks(Choreographer.java:952)
at android.view.Choreographer.doFrame(Choreographer.java:878)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1322)
at android.os.Handler.handleCallback(Handler.java:958)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:205)
at android.os.Looper.loop(Looper.java:294)
at android.app.ActivityThread.main(ActivityThread.java:8177)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [androidx.compose.runtime.PausableMonotonicFrame

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.