/* * Copyright 2017-present The Material Motion Authors. All Rights Reserved. * * 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. */ package com.google.android.material.motion.interactions; import android.util.Property; import com.google.android.material.motion.ConstraintApplicator; import com.google.android.material.motion.Interaction; import com.google.android.material.motion.MotionObservable; import com.google.android.material.motion.MotionRuntime; import com.google.android.material.motion.ReactiveProperty; import com.google.android.material.motion.sources.SpringSource; import com.google.android.material.motion.springs.TypeVectorizer; /** * A spring can pull a value from an initial position to a destination using a physical simulation. * <p> * This class defines the spring type for use in creating a spring source. */ public class MaterialSpring<O, T> extends Interaction<O, T> { /** * The default spring tension coefficient. * <p> * Default extracted from a POP spring with speed = 12 and bounciness = 4. */ public static final float DEFAULT_TENSION = 342f; /** * The default spring friction coefficient. * <p> * Default extracted from a POP spring with speed = 12 and bounciness = 4. */ public static final float DEFAULT_FRICTION = 30f; /** * The default spring tension coefficient. Represents {@link #DEFAULT_TENSION}. * <p> * Default extracted from a POP spring with speed = 12 and bounciness = 4. */ public static final ReactiveProperty<Float> DEFAULT_TENSION_PROPERTY = ReactiveProperty.ofImmutableValue(DEFAULT_TENSION); /** * The default spring friction coefficient. Represents {@link #DEFAULT_FRICTION}. * <p> * Default extracted from a POP spring with speed = 12 and bounciness = 4. */ public static final ReactiveProperty<Float> DEFAULT_FRICTION_PROPERTY = ReactiveProperty.ofImmutableValue(DEFAULT_FRICTION); /** * The destination value of the spring represented as a property. */ public final ReactiveProperty<T> destination; /** * The initial value of the spring represented as a readable. */ public final ReactiveProperty<T> initialValue; /** * The initial velocity of the spring represented as a readable. */ public final ReactiveProperty<T> initialVelocity; /** * The value used when determining completion of the spring simulation. */ public final ReactiveProperty<Float> threshold; /** * The tension coefficient of the spring represented as a property. */ public final ReactiveProperty<Float> tension; /** * The friction coefficient of the spring represented as a property. */ public final ReactiveProperty<Float> friction; public final TypeVectorizer<T> vectorizer; private final Property<O, T> property; private final MotionObservable<T> stream; /** * Creates a spring with the provided values. */ public MaterialSpring( Property<O, T> property, TypeVectorizer<T> vectorizer, T destination, T initialValue, T initialVelocity, float threshold, float tension, float friction, SpringSource.System system) { this(property, vectorizer, ReactiveProperty.of(destination), ReactiveProperty.of(initialValue), ReactiveProperty.of(initialVelocity), ReactiveProperty.of(threshold), ReactiveProperty.of(tension), ReactiveProperty.of(friction), system); } /** * Creates a spring with the provided properties. */ public MaterialSpring( Property<O, T> property, TypeVectorizer<T> vectorizer, ReactiveProperty<T> destination, ReactiveProperty<T> initialValue, ReactiveProperty<T> initialVelocity, ReactiveProperty<Float> threshold, ReactiveProperty<Float> tension, ReactiveProperty<Float> friction, SpringSource.System system) { this.property = property; this.vectorizer = vectorizer; this.destination = destination; this.initialValue = initialValue; this.initialVelocity = initialVelocity; this.threshold = threshold; this.tension = tension; this.friction = friction; this.stream = system.create(this).getStream(); } @Override public void apply(MotionRuntime runtime, O target, ConstraintApplicator<T> constraints) { runtime.write(constraints.apply(stream), target, property); } }