A motion-driven animation framework for Android.

Overview

the backboard icon

Backboard

CircleCI

A motion-driven animation framework for Android.

backboard is a framework on top of rebound that makes it easier to use by coupling it to views and motions.

backboard-example is an Android app with a few demos of animations made possible by Backboard.

Javadoc

follow animation bloom animation scale animation

Table of Contents

Usage

Update your build.gradle with

dependencies {
   compile 'com.facebook.rebound:rebound:0.3.8'
   compile 'com.tumblr:backboard:0.1.0'
}

Getting Started

Backboard is a framework on top of rebound that manages how Springs are used and simplifies the most common use cases:

  • Actions, such as MotionEvents, are mapped to Springs via Imitators.
  • Springs are mapped to Views and view properties via Performers.

In addition, an Actor wraps the above objects and provides a simple interface for mapping touch motion to a view's position - dragging.

Performers

A Performer takes the current value of a Spring and sets it as the value of a view property.

Spring bounce = SpringSystem.create().createSpring();
Performer xMotion = new Performer(view, View.TRANSLATION_X);
bounce.addListener(xMotion);

for those saving screen space, a fluent interface is available:

Spring bounce = SpringSystem.create().createSpring().addListener(new Performer(view, View.TRANSLATION_X));

Imitators

An Imitator constantly perturbs the Spring it is attached to. This perturbation can originate a variety of sources:

  1. A MotionEvent, where the Spring can change based on the action (ACTION_DOWN, ACTION_UP), or imitate a property (x, y, etc.). These are called EventImitators.
  2. Another Spring, which leads to results similar to springs being chained together. These are called SpringImitators.

Imitating Touch

An EventImitator primarily operates with OnTouchListeners. The simplest example is a ToggleImitator, which toggles between two different values depending on the touch state:

view.setOnTouchListener(new ToggleImitator(spring, 0, 1));

when the user touches the view, a value of 1 is set on the spring, and when the user releases, a value of 0 is set.

Imitating Motion

A MotionImitator is a special type of EventImitator that maps x and y movement to a spring. This is done with MotionProperty enums, which specifies which methods to call in a MotionEvent object. For example, MotionProperty.X.getValue(MotionEvent) calls event.getX(). It also specifies the view property to animate - MotionEvent.X.getViewProperty() corresponds to View.TRANSLATION_X. This is useful for the Actor builder later on. In addition, tracking and following strategies allow for customization of how the event value is mapped to the spring.

Tracking Strategies

Two tracking strategies are available to configure how an imitator tracks its imitatee.

  • TRACK_ABSOLUTE maps the imitatee value directly to the spring.
  • TRACK_DELTA maps the change in the imitatee value (relative to the initial touch) to the spring.
Follow Strategies

Two follow strategies are available to configure how the spring is updated.

  • FOLLOW_EXACT maps the imitatee value directly to the current and end value of the spring.
  • FOLLOW_SPRING maps the imitatee value to the end value of the spring (which allows the spring to overshoot the current position)

Imitating Springs

A SpringImitator is also a SpringListener. When the Spring it is imitating updates, it updates the end value of the Spring it is controlling. Usage is simple:

SpringSystem springSystem = SpringSystem.create();

Spring leader = springSystem.createSpring();
Spring follower = springSystem.createSpring();

SpringImitator follow = new SpringImitator(follower);
leader.addListener(follow);

Actors

Even though backboard reduces a significant amount of boilerplate code, the Actor class further simplifes view motion by connecting each component together. It also manages a View.onTouchListener() (a MotionListener), which it attaches to the View automatically (this can be disabled). Here is how to create one:

Actor actor = new Actor.Builder(SpringSystem.create(), view)
  .addTranslateMotion(MotionProperty.X)
  .build();

in two dimensions:

Actor actor = new Actor.Builder(SpringSystem.create(), view)
  .addTranslateMotion(MotionProperty.X)
  .addTranslateMotion(MotionProperty.Y)
  .build();

Two calls to addTranslateMotion(MotionProperty) are needed because each axis is independent of the other. The builder will create an OnTouchListener and attach it to the View, as well as a Spring with the default settings. A Performer is also created and attached to the Spring. When there is a touch event, it is passed to the MotionImitator, which perturbs the spring, which moves the view.

It is also possible to supply your own SpringSystem, Spring, MotionImitator and Performer, and the builder will properly connect them. The first example above can also be expressed as:

SpringSystem springSystem = SpringSystem.create();
Spring spring = springSystem.createSpring();

Actor verbose = new Actor.Builder(springSystem, view)
 .addMotion(spring, new MotionImitator(spring, MotionProperty.X),
                    new Performer(view, View.TRANSLATION_X)
 .build();

The View can be also left out of the constructor of the Performer and the Spring out of the MotionImitator (using the default SpringConfig), since the builder will connect them.

Actor walk = new Actor.Builder(SpringSystem.create(), walker)
  .addMotion(
    new MotionImitator(MotionProperty.X),
    new Performer(View.TRANSLATION_X))
  .build();

which can be further simplified to

Actor run = new Actor.Builder(SpringSystem.create(), runner).addMotion(MotionProperty.X, View.TRANSLATION_X).build();

and for more sugar, the previous case:

Actor bolt = new Actor.Builder(SpringSystem.create(), bolter).addTranslateMotion(MotionProperty.X).build();

Actor Options

  • requestDisallowTouchEvent() causes the Actor to call ViewParent.requestDisallowTouchEvent(true) which is helpful when the view is inside a ListView or another view that captures touch events.
  • dontAttachMotionListener() tells the builder to not attach the MotionListener to the View, which is useful when you want to attach your own OnTouchListener to the view.

Dependencies

Contact

License

Copyright 2015-2016 Tumblr, Inc.

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 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.

Comments
  • Update Gradle dependency

    Update Gradle dependency

    Is it possible to update the Backboard Gradle dependency from 0.1.0? Some of the examples in backboard-example are not possible to migrate over to my own codebase, for example in PressFragment there is an addMotion method where an EventImitator is passed in but the current version in Bintray does not have that.

    question 
    opened by veyndan 3
  • Fixed problem while compiling the project

    Fixed problem while compiling the project

    Since this project had *.iml and .idea/ files, it was unable to be compiled elsewhere from your computer

    • Removed .idea/ folders and *.iml files because they can mess up workspaces
    • Updated build tools version
    • Updated compile sdk version
    • Updated target SDK for a newer version
    • Updated annotations support version
    opened by cesarferreira 2
  • Plugin DSL and javadoc improvements

    Plugin DSL and javadoc improvements

    This PR builds on #24 and adds support for plugin DSL, updates compile/target sdk to 31 and fixes/improves the javadoc task.

    • 1f7e7f92ad143ca6c1efbf1a76bd386fa9df10d8 adds support for plugin DSL. This change will mean that the Gradle property logic around localBuildTools is removed, however I don't think that's necessary for a standalone library. Please let me know if you disagree and I can try and bring it back with the new setup.
    • 17b04f80ffcd40d565bab5f4c9be182b9170283a replaces deprecated jcenter with mavenCentral.
    • 20847c907b2ecc19e4dc6e6147c6a0f5432f3cef updates compile/target sdk to 31.
    • ce16218e3933dfbe2ebab5c114cfd545de8da4ce updates the source for the javadoc task. My understanding is that this is the correct path, but since there are no official docs/examples for the usecase, I can't be sure.
    • 5aa76148aa0a00c5847b0cb6788d304d7a138083 was a bit tricky and that's why it's separated from the previous commit. It updates the classpath to include the compile dependencies. Without this change ./gradlew javadocRelease would fail with several errors where compiler can't find classes such as @NonNull. It also replaces the custom androidJar setup with the getBootClasspath. I think this is correct, but (frustratingly) I have failed to find enough information on this.
    • 5aa76148aa0a00c5847b0cb6788d304d7a138083 also removes the offline links, which didn't work for me as I don't have the docs folder and couldn't find how to download them. I don't think not having the offline links is a big loss, but if there is any disagreement, we can try to get it to work in the Docker image which is where it'll be used. It also removes the link to http://facebook.github.io/rebound/javadocs/ which is no longer available and forwards to https://opensource.fb.com/. I couldn't find the updated url as the project seems to have been deprecated.

    Since there is some hesitation about the javadoc changes, one idea might be to compare the newly generated docs with the old ones if it's possible. I unfortunately don't have any prior knowledge on how to do that. It looks like the javadoc task was introduced in https://github.com/tumblr/Backboard/pull/10, so there might be some clues there.

    opened by oguzkocer 1
  • Upgrade Gradle to 7.3.3 & Android Gradle Plugin to 7.1.1

    Upgrade Gradle to 7.3.3 & Android Gradle Plugin to 7.1.1

    This PR updates Gradle and Android Gradle Plugin to their latest versions. It also addresses issues that resulted from the upgrade with the goal of getting a successful ./gradlew build command. It removes publishing related code - as it's no longer usable - in favour of adding publishing to our S3 Maven in a subsequent PR.

    • In 747e109fa58092b1179fb4b365f43833e79fd6a8, Gradle wrapper is updated with the ./gradlew wrapper --gradle-version 7.3.3 --distribution-type all command.
    • 577e58b76a4357e7fa7d2cabbf3cf1f576540b6e updates Android Gradle Plugin to its latest version 7.1.1.
    • acfc8325c52c3d9c6209e0828ef690472de60abb adds android.useAndroidX=true to gradle.properties. In PermissMe library gradle.properties was ignored, so gradle.properties-example was introduced for this. However, since gradle.properties is already checked into the project, adding the android.useAndroidX property is simpler. I think this is something we should address in the future to bring consistency across projects, however I don't think this PR is the right time & place to do it.
    • a87cea3ffc2a431ee2331fccb1cb043bf078e967 removes Bintray & Maven plugins. These are no longer supported (or needed) and will break the build.
    • 3826905239db64ddf591251a422aaa3dcda43137 removes the buildToolsVersion property which is no longer necessary and gets ignored by AGP.

    To test: I unfortunately don't have any testing instructions for the project, but these are all build related changes and at least those can be verified by ./gradlew build command which builds, tests and lints the projects. It'd be helpful to smoke test the example app if the reviewer is familiar with it.

    opened by oguzkocer 1
  • Can I set onAnimationEnd()?

    Can I set onAnimationEnd()?

    I want to know how to set functions after Spring Animation is done. Below is example code. I added some codes at the end of BloomFragment which is in backboard-example.

    // mRootView.setOnTouchListener(new ToggleImitator(spring, CLOSED, OPEN));
    // Instead of ToggleImitator, I made below codes for holding spring animation.
    mRootView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(mySpring.getEndValue() == OPEN) {
                    mySpring.setEndValue(CLOSED);
                    Log.d("SpringValue", String.valueOf(mySpring.getEndValue()));
                } else {
                    mySpring.setEndValue(OPEN);
                    Log.d("SpringValue", String.valueOf(mySpring.getEndValue()));
                }
            }
        });
    

    But, what I really want to know is getting Listener whether spring animation is over. (for adding Logs, changing circle's color, or something else which is really important to performing app)

    I already used spring.addListener(SimpleSpringListener listener) like below code.

    mySpring.addListener(new SimpleSpringListener() {
                @Override
                public void onSpringActivate(Spring spring) {
                    super.onSpringActivate(spring);
                    if (spring.getCurrentValue() == spring.getEndValue()) {
                        Log.d("Spring State", "END");
                    }
                }
    });
    

    But, not working at all.... :(

    Please help me!!

    // I already added same question on StackOverflow but no-one answer me :(

    opened by TyeolRik 1
  • PressFragment example invalid argument to .addMotion

    PressFragment example invalid argument to .addMotion

    https://github.com/tumblr/Backboard/blob/42f153ee5c96e49da25732fc6120bb22e087daff/backboard-example/src/main/java/com/tumblr/backboard/example/PressFragment.java#L27

    Actor.Builder's .addMotion method no longer takes a ToggleImitator, and even if it did, the ToggleImitator no longer takes a null spring for it's first argument.

    bug 
    opened by ersin-ertan 1
  • Fix release() call at wrong time.

    Fix release() call at wrong time.

    Other MotionEvent for example:ACTION_POINTER_DOWN... will cause release call at wrong time if MotionEvent switch default is MotionEvent.ACTION_UP.

    for example:

    I have a view which can drop with finger.

    If user drop on the way and other finger touch screen, it will cause view jump random.

    bug 
    opened by SemonCat 1
  • Publish to s3

    Publish to s3

    This PR integrates Buildkite and adds support for publishing the library artifacts to S3 Maven. It follows our standard Buildkite configuration file and publish-to-s3 Gradle plugin setup.

    • There are 2 CI steps, one to verify checkstyle & lint and one to publish to s3. The publishing job depends on the lint & checkstyle job. The publishing step uses a script we have in the Docker image to pass Buildkite environment information to the prepareToPublishToS3 task.
    • The publishing is done by Maven Publish Plugin. We use our own Gradle plugin to simplify its setup and have consistency across libraries. This plugin is the one that adds the prepareToPublishToS3 task which calculates the version, updates the information for maven-publish plugin and verifies that the version is not already published.
    • The specified version information is removed from build.gradle as this is now dynamically calculated at the time of publishing.
    • For the first time, I've used the newly introduced publishing block from AGP 7.1.0 to publish the -javadoc.jar & -sources.jar files. I've verified that the files are in our S3 and tested the Tumblr client, but I'd appreciate if it can also be verified by the reviewer. I added instructions on how to do that in the client PR as it wouldn't be possible to easily test it in this PR.

    README Updates

    • For the repositories section, it recommends using exclusiveContent syntax which makes the S3 Maven the only possible repository to fetch the Backboard library artifacts. This is an extra security measure to guard against dependency hijacking attacks.
    • Information about how to publish a new version and how that version will be formatted has been added. Note that Buildkite logs also contain information about the published version.
    • After this PR is merged, I think we should create a new 0.2.0 tag. This is why I opted to use this version in the README.

    To Test

    There are no testing instructions specific to this PR. However, since this PR builds on #24 & #25, there is a Tumblr client PR that can be used to test the changes made in these PRs and verify that it's correctly published to S3.

    opened by oguzkocer 0
  • Add Javadoc Task to Gradle

    Add Javadoc Task to Gradle

    running

    Generate Javadoc with:

    $ ./gradlew javadocRelease
    

    Instead of Release, any build variant could be substituted (like Debug).

    The generated Javadoc is in

    /backboard/build/docs/javadoc
    

    publishing

    To publish the Javadoc, move the above directory to /javadoc in the gh-pages branch. This appears to the public as

    http://tumblr.github.io/Backboard/javadoc/

    redirect

    To redirect from the root directory, http://tumblr.github.io/Backboard, to the Javadoc, jekyll-redirect-from is used.

    In the root directory, an index.html file was created with these contents:

    
    ---
    redirect_to: "./javadoc"
    
    ---
    
    enhancement 
    opened by ericleong 0
  • Unite MotionImitator and ToggleImitator

    Unite MotionImitator and ToggleImitator

    EventImitator is a bit of a strange class. It provides an imitate() method, but it's never called directly, since Actor uses MotionImitator directly. That leaves ToggleImitator in a weird spot because Actor is no longer able to use it. This pull request seeks to bring ToggleImitator back into the fold by:

    • Adding an abstract method, imitate(View, MotionEvent). This matches View.OnClickListener.
    • Refactoring Actor to use EventImitator instead of MotionEvent in arguments, so that any subclass may be passed in.

    This pull request was inspired by the Rebound demo. It can now be implemented with:

    new Actor.Builder(SpringSystem.create(), view)
                    .addMotion(new ToggleImitator(null, 1.0, 0.5), View.SCALE_X, View.SCALE_Y)
                    .build();
    

    A new demo can be found in PressFragment.

    One bug was discovered and fixed in this pull request: Imitator.setSpring() does not set the rest value or current value of the new spring. fed6a2e sets the current value of the spring to the rest value of the Imitator.

    A small optimization was made by passing the ToggleImitator as the View.OnTouchListener of the Actor in FlowerFragment.

    testing

    Open each of the demos and ensure that they act as expected.

    enhancement 
    opened by ericleong 0
  • add animation listener

    add animation listener

    When I create an animation using actor like the following:

    new Actor.Builder(SpringSystem.create(), rootView.findViewById(R.id.circle)) .addTranslateMotion(Imitator.TRACK_DELTA, Imitator.FOLLOW_EXACT, MotionProperty.X).build();

    I want to add a listener to control the behavior of the animation itself or to track the user actions, ex. when the user touch the view down, up or start moving it.

    Note: I want to use this animation to create "Slide to Cancel" function. how can I achieve this function using the above animation.

    question 
    opened by KhalidElSayed 1
Releases(0.2.0)
Owner
Tumblr
Tumblr
Sophisticated and cool intro with Material Motion Animation

☯️Sophisticated and cool intro with Material Motion Animations(No more viewpager transformer)

Ranbir Singh 34 Sep 8, 2022
Animations driven by finger movement

OffsetAnimator OffsetAnimator lets animate objects basing on touchevents, so users can be engaged in an animation process. Usage Add the library to yo

Ruslan Urmeev 314 Nov 24, 2022
An application demoing meaningful motion on Android

Animate You'll find the supporting medium article for this project here! Animate is a simple application I quickly put together to demo meaningful mot

Joe Birch 3.1k Dec 30, 2022
How to apply meaningful and delightful motion in a sample Android app

Applying meaningful motion on Android How to apply meaningful and delightful motion in a sample Android app Read the complete post at https://medium.c

André Mion 166 Nov 12, 2022
💠Metaphor is the library to easily add Material Motion animations

Metaphor Metaphor is the library to easily add Material Motion animations. Who's using Metaphor? ?? Check out who's using Metaphor Include in your pro

Ranbir Singh 132 Dec 25, 2022
☯️Sophisticated and cool intro with Material Motion Animations(No more viewpager transformer or Memory leak)

Material Intro Sophisticated and cool intro with Material Motion Animations. Who's using Material Intro? ?? Check out who's using Material Intro Inclu

Ranbir Singh 34 Sep 8, 2022
Android Animation Easing Functions. Let's make animation more real!

Android Easing Functions This project is originally from my another project, AndroidViewAnimation, which is an animation collection, to help you make

代码家 2.5k Jan 4, 2023
A component for flip animation on Android, which is similar to the effect in Flipboard iPhone/Android

android-flip Aphid FlipView is a UI component to accomplish the flipping animation like Flipboard does. A pre-built demo APK file for Android OS 2.2+

Bo 2.8k Dec 21, 2022
Deprecated in favour of https://developer.android.com/reference/android/support/v4/view/animation/PathInterpolatorCompat.html

Deprecated: use https://developer.android.com/reference/android/support/v4/view/animation/PathInterpolatorCompat.html instead. android-cubic-bezier-in

Codesoup 161 Jan 1, 2023
[] Android library for using the Honeycomb animation API on all versions of the platform back to 1.0!

DEPRECATED NineOldAndroids is deprecated. No new development will be taking place. Existing versions will (of course) continue to function. New applic

Jake Wharton 4.5k Jan 9, 2023
DuGuang 1k Dec 14, 2022
Android library to control Transition animates. A simple way to create a interactive animation.

TransitionPlayer Android library to control Transition animates. A simple way to create a interactive animation. Demo1 SimpleTransition Code: ....

林法鑫 1.2k Dec 17, 2022
Collect android animation

Interactive-animation 描述:收集android上开源的酷炫的交互动画和视觉效果。 1.交互篇 2.视觉篇 交互篇 1.SlidingUpPanelLayout 项目介绍:他的库提供了一种简单的方式来添加一个可拖动滑动面板(由谷歌音乐推广,谷歌地图和Rdio)你的Android应

Ra 749 Dec 14, 2022
Road Runner is a library for android which allow you to make your own loading animation using a SVG image

Road Runner Road Runner is a library for android which allow you to make your own loading animation using a SVG image Sample video View in Youtube Dem

Adrián Lomas 1.2k Nov 18, 2022
Thirty-one different easing animation interpolators for Android.

EasingInterpolator Thirty-one different easing animation interpolators for Android. It does not use the standard 4 param ease signature. Instead it us

Masayuki Suda 1.1k Dec 28, 2022
With MVVM Architecture pattern using Android Architecture Components This is a sample app demonstrating Youtube player animation using constraint layout

Youtube UI/UX Animation This is a sample app demonstrating Youtube UX/UI animation using ConstraintLayout.It implements the Keyframe Animation feature

Burhanuddin Rashid 866 Dec 29, 2022
FPSAnimator is very easy animation library for Android TextureView and SurfaceView.

FPSAnimator A simple but powerful Tween / SpriteSheet / ParabolicMotion / animation library for Android TextureView and SurfaceView. Features The cont

Masayuki Suda 756 Dec 30, 2022
Android library to make notes drop animation for music players

VusikView Min SDK 11 Screnshots How to use If you want use this library, you can download project and import it into your workspace and add the projec

Chetan Kaushik 119 Nov 29, 2022
An simple & awesome animation library written in Kotlin for Android

An simple & awesome animation library written in Kotlin for Android

Romman Sabbir 53 Oct 17, 2022