{"id":14961277,"url":"https://github.com/tumblr/backboard","last_synced_at":"2025-05-15T10:07:37.163Z","repository":{"id":35073935,"uuid":"39222173","full_name":"tumblr/Backboard","owner":"tumblr","description":"A motion-driven animation framework for Android.","archived":false,"fork":false,"pushed_at":"2023-12-05T08:16:43.000Z","size":814,"stargazers_count":1692,"open_issues_count":2,"forks_count":188,"subscribers_count":78,"default_branch":"master","last_synced_at":"2025-05-15T10:07:21.415Z","etag":null,"topics":["android","android-library","animation","motion"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"beam-community/avro_ex","license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tumblr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-07-16T21:49:58.000Z","updated_at":"2025-05-02T16:01:15.000Z","dependencies_parsed_at":"2024-01-15T16:51:41.885Z","dependency_job_id":null,"html_url":"https://github.com/tumblr/Backboard","commit_stats":{"total_commits":59,"total_committers":12,"mean_commits":4.916666666666667,"dds":0.6779661016949152,"last_synced_commit":"8fec03fb8f52d69b98e60f0058b0edbccf6a5c4e"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tumblr%2FBackboard","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tumblr%2FBackboard/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tumblr%2FBackboard/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tumblr%2FBackboard/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tumblr","download_url":"https://codeload.github.com/tumblr/Backboard/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254319721,"owners_count":22051074,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","android-library","animation","motion"],"created_at":"2024-09-24T13:24:21.209Z","updated_at":"2025-05-15T10:07:32.145Z","avatar_url":"https://github.com/tumblr.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"![the backboard icon](backboard-example/src/main/res/mipmap-xxhdpi/ic_launcher.png?raw=true)\n\n# Backboard\n\nA motion-driven animation framework for Android.\n\n`backboard` is a framework on top of [rebound](http://facebook.github.io/rebound/) that makes it easier to use by coupling it to views and motions.\n\n`backboard-example` is an Android app with a few demos of animations made possible by Backboard.\n\n[Javadoc](http://tumblr.github.io/Backboard/javadoc/)\n\n![follow animation](../screenshots/screenshots/follow.gif?raw=true)\n![bloom animation](../screenshots/screenshots/bloom.gif?raw=true)\n![scale animation](../screenshots/screenshots/scale.gif?raw=true)\n\n## Table of Contents\n\n* [Usage](#usage)\n* [Publishing a new version](#publishing-a-new-version)\n* [Getting Started](#getting-started)\n    * [Performers](#performers)\n    * [Imitators](#imitators)\n    * [Actors](#actors)\n* [Dependencies](#dependencies)\n* [Contact](#contact)\n* [License](#license)\n\n## Usage\n\nUpdate your `build.gradle` with\n\n```groovy\nrepositories {\n    exclusiveContent {\n        forRepository {\n            maven {\n                url \"https://a8c-libs.s3.amazonaws.com/android\"\n            }\n        }\n        filter {\n            includeModule \"com.tumblr\", \"backboard\"\n        }\n    }\n}\n\ndependencies {\n   implementation 'com.facebook.rebound:rebound:0.3.8'\n   implementation 'com.tumblr:backboard:0.2.0'\n}\n```\n\n## Publishing a new version\n\nIn the following cases, the CI will publish a new version with the following format to our S3 Maven repo:\n\n* For each commit in an open PR: `\u003cPR-number\u003e-\u003ccommit full SHA1\u003e`\n* Each time a PR is merged to `master`: `master-\u003ccommit full SHA1\u003e`\n* Each time a new tag is created: `{tag-name}`\n\n## Getting Started\n\nBackboard is a framework on top of [rebound](http://facebook.github.io/rebound/) that manages how `Springs` are used and simplifies the\nmost common use cases:\n\n- Actions, such as `MotionEvents`, are mapped to `Springs` via `Imitators`.\n- `Springs` are mapped to `Views` and view properties via `Performers`.\n\nIn addition, an `Actor` wraps the above objects and provides a simple interface for mapping touch motion to a view's position - dragging.\n\n### Performers\n\nA `Performer` takes the current value of a `Spring` and sets it as the value of a view property.\n```Java\nSpring bounce = SpringSystem.create().createSpring();\nPerformer xMotion = new Performer(view, View.TRANSLATION_X);\nbounce.addListener(xMotion);\n```\nfor those saving screen space, a [fluent interface](http://en.wikipedia.org/wiki/Fluent_interface) is available:\n```Java\nSpring bounce = SpringSystem.create().createSpring().addListener(new Performer(view, View.TRANSLATION_X));\n```\n\n### Imitators\n\nAn `Imitator` constantly perturbs the `Spring` it is attached to. This perturbation can originate a variety of sources:\n\n1. 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`.\n2. Another `Spring`, which leads to results similar to springs being chained together. These are called `SpringImitators`.\n\n\n#### Imitating Touch\n\nAn `EventImitator` primarily operates with `OnTouchListeners`. The simplest example is a `ToggleImitator`, which toggles between two different values depending on the touch state:\n```Java\nview.setOnTouchListener(new ToggleImitator(spring, 0, 1));\n```\nwhen 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.\n\n#### Imitating Motion\n\nA `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.\n\n##### Tracking Strategies\n\nTwo tracking strategies are available to configure how an imitator tracks its imitatee.\n\n* `TRACK_ABSOLUTE` maps the imitatee value directly to the spring.\n* `TRACK_DELTA` maps the change in the imitatee value (relative to the initial touch) to the spring.\n\n##### Follow Strategies\n\nTwo follow strategies are available to configure how the spring is updated.\n\n* `FOLLOW_EXACT` maps the imitatee value directly to the current and end value of the spring.\n* `FOLLOW_SPRING` maps the imitatee value to the end value of the spring (which allows the spring\n to overshoot the current position)\n\n#### Imitating Springs\n\nA `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:\n```Java\nSpringSystem springSystem = SpringSystem.create();\n\nSpring leader = springSystem.createSpring();\nSpring follower = springSystem.createSpring();\n\nSpringImitator follow = new SpringImitator(follower);\nleader.addListener(follow);\n```\n\n### Actors\n\nEven 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:\n```Java\nActor actor = new Actor.Builder(SpringSystem.create(), view)\n  .addTranslateMotion(MotionProperty.X)\n  .build();\n```\nin two dimensions:\n```Java\nActor actor = new Actor.Builder(SpringSystem.create(), view)\n  .addTranslateMotion(MotionProperty.X)\n  .addTranslateMotion(MotionProperty.Y)\n  .build();\n```\nTwo 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.\n\nIt 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:\n```Java\nSpringSystem springSystem = SpringSystem.create();\nSpring spring = springSystem.createSpring();\n\nActor verbose = new Actor.Builder(springSystem, view)\n .addMotion(spring, new MotionImitator(spring, MotionProperty.X),\n                    new Performer(view, View.TRANSLATION_X)\n .build();\n```\n\nThe `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.\n```Java\nActor walk = new Actor.Builder(SpringSystem.create(), walker)\n  .addMotion(\n    new MotionImitator(MotionProperty.X),\n    new Performer(View.TRANSLATION_X))\n  .build();\n```\nwhich can be further simplified to\n```Java\nActor run = new Actor.Builder(SpringSystem.create(), runner).addMotion(MotionProperty.X, View.TRANSLATION_X).build();\n```\nand for more sugar, the previous case:\n```Java\nActor bolt = new Actor.Builder(SpringSystem.create(), bolter).addTranslateMotion(MotionProperty.X).build();\n```\n\n#### Actor Options\n\n- `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.\n- `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.\n\n## Dependencies\n\n* [rebound](http://facebook.github.io/rebound/)\n\n## Contact\n\n* [Eric Leong](mailto:ericleong@tumblr.com)\n\n## License\n\nCopyright 2015-2016 Tumblr, Inc.\n\nLicensed under the Apache License, Version 2.0 (the “License”); you may not use\nthis file except in compliance with the License. You may obtain a copy of the\nLicense at [apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0).\n\n\u003e Unless required by applicable law or agreed to in writing, software\n\u003e distributed under the License is distributed on an “AS IS” BASIS, WITHOUT\n\u003e WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n\u003e License for the specific language governing permissions and limitations under\n\u003e the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftumblr%2Fbackboard","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftumblr%2Fbackboard","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftumblr%2Fbackboard/lists"}