├── .gitignore
├── Android
├── .gitignore
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── gaia
│ │ └── MotionCurve
│ │ ├── GaiaMotionCurveAccelerateInterpolator.java
│ │ ├── GaiaMotionCurveAnticipateInterpolator.java
│ │ ├── GaiaMotionCurveBounceInterpolator.java
│ │ ├── GaiaMotionCurveCosineInterpolator.java
│ │ ├── GaiaMotionCurveCubicBezierInterpolator.java
│ │ ├── GaiaMotionCurveDecelerateInterpolator.java
│ │ ├── GaiaMotionCurveLinearInterpolator.java
│ │ ├── GaiaMotionCurveOvershootInterpolator.java
│ │ ├── GaiaMotionCurveSpringInterpolator.java
│ │ └── GaiaMotionCurveStandardInterpolator.java
│ └── res
│ └── values
│ └── strings.xml
├── LICENSE
├── README.md
├── README_en.md
├── docs
├── assets
│ ├── accelerate.gif
│ ├── anticipate.gif
│ ├── bounce.gif
│ ├── cosine.gif
│ ├── decelerate.gif
│ ├── linear.gif
│ ├── overshoot.gif
│ ├── spring.gif
│ └── standard.gif
├── en-US
│ ├── accelerate.md
│ ├── anticipate.md
│ ├── bounce.md
│ ├── cosine.md
│ ├── decelerate.md
│ ├── linear.md
│ ├── overshoot.md
│ ├── spring.md
│ └── standard.md
└── zh-CN
│ ├── accelerate.md
│ ├── anticipate.md
│ ├── bounce.md
│ ├── cosine.md
│ ├── decelerate.md
│ ├── linear.md
│ ├── overshoot.md
│ ├── spring.md
│ └── standard.md
├── examples
├── Android
│ ├── .gitignore
│ ├── app
│ │ ├── .gitignore
│ │ ├── build.gradle
│ │ ├── libs
│ │ │ └── gaia-motion-curve-0.1.aar
│ │ ├── proguard-rules.pro
│ │ └── src
│ │ │ ├── androidTest
│ │ │ └── java
│ │ │ │ └── com
│ │ │ │ └── gaia
│ │ │ │ └── demo
│ │ │ │ └── ExampleInstrumentedTest.java
│ │ │ ├── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java
│ │ │ │ └── com
│ │ │ │ │ └── gaia
│ │ │ │ │ └── demo
│ │ │ │ │ ├── AnimationActivity.java
│ │ │ │ │ └── MainActivity.java
│ │ │ └── res
│ │ │ │ ├── drawable-v24
│ │ │ │ └── ic_launcher_foreground.xml
│ │ │ │ ├── drawable
│ │ │ │ └── ic_launcher_background.xml
│ │ │ │ ├── layout
│ │ │ │ ├── activity_animation.xml
│ │ │ │ ├── activity_listview.xml
│ │ │ │ └── activity_main.xml
│ │ │ │ ├── mipmap-anydpi-v26
│ │ │ │ ├── ic_launcher.xml
│ │ │ │ └── ic_launcher_round.xml
│ │ │ │ ├── mipmap-hdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ │ ├── mipmap-mdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ │ ├── values-night
│ │ │ │ └── themes.xml
│ │ │ │ └── values
│ │ │ │ ├── colors.xml
│ │ │ │ ├── strings.xml
│ │ │ │ └── themes.xml
│ │ │ └── test
│ │ │ └── java
│ │ │ └── com
│ │ │ └── gaia
│ │ │ └── demo
│ │ │ └── ExampleUnitTest.java
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
└── iOS
│ ├── GaiaMotionCurveDemo.xcodeproj
│ └── project.pbxproj
│ ├── GaiaMotionCurveDemo
│ ├── AnimationViewController.h
│ ├── AnimationViewController.m
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── 111.png
│ │ │ ├── Contents.json
│ │ │ └── Ico1n.png
│ │ ├── Contents.json
│ │ └── LaunchImage.launchimage
│ │ │ ├── Contents.json
│ │ │ └── 画板@2x.png
│ ├── Info.plist
│ ├── ViewController.h
│ ├── ViewController.m
│ └── main.m
│ ├── Podfile
│ └── Podfile.lock
└── iOS
├── GaiaMotionCurve.podspec
├── GaiaMotionCurve.xcodeproj
└── project.pbxproj
├── GaiaMotionCurve
├── CALayer+GaiaMotionCurve.h
├── CALayer+GaiaMotionCurve.m
├── GMCDefines.h
├── GMCFunctions.h
├── GMCFunctions.m
├── GMCHelper.h
├── GMCHelper.m
├── GMCModel+Internal.h
├── GMCModel+Internal.m
├── GMCModel.h
├── GMCModel.m
├── GaiaMotionCurve.h
├── NSValue+GMCCGFloat.h
├── NSValue+GMCCGFloat.m
├── NSValue+GMCUIColor.h
└── NSValue+GMCUIColor.m
├── GaiaMotionCurveTests
└── GaiaMotionCurveTests.m
└── Podfile
/.gitignore:
--------------------------------------------------------------------------------
1 | *.mode1
2 | *.mode1v3
3 | *.mode2v3
4 | *.perspective
5 | *.perspectivev3
6 | *.pbxuser
7 | *.xcworkspace
8 | *.framework/
9 | xcuserdata
10 | examples/iOS/Pods/
11 | src/iOS/Pods/
12 | src/Android/build/
13 | examples/Android/build/
14 | **/.idea
15 | **/.vscode
16 |
--------------------------------------------------------------------------------
/Android/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea
5 | .DS_Store
6 | /build
7 | /captures
8 | .externalNativeBuild
9 | .cxx
10 | local.properties
11 | github.properties
--------------------------------------------------------------------------------
/Android/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'maven-publish'
3 |
4 | allprojects {
5 | repositories {
6 | // The order in which you list these repositories matter.
7 | google()
8 | jcenter()
9 | maven {
10 | url "https://jitpack.io"
11 | }
12 | }
13 | }
14 |
15 | buildscript{
16 | repositories{
17 | google()
18 | jcenter()
19 | maven {
20 | url "https://jitpack.io"
21 | }
22 | }
23 |
24 | dependencies{
25 | classpath "com.android.tools.build:gradle:7.0.2"
26 | }
27 | }
28 |
29 | android {
30 | compileSdk 32
31 |
32 | defaultConfig {
33 | minSdk 21
34 | targetSdk 32
35 | versionCode 1
36 | versionName "0.1.0"
37 |
38 | }
39 |
40 |
41 | lintOptions {
42 | abortOnError false
43 | }
44 |
45 | buildTypes {
46 | release {
47 | minifyEnabled false
48 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
49 | }
50 | }
51 | compileOptions {
52 | sourceCompatibility JavaVersion.VERSION_1_8
53 | targetCompatibility JavaVersion.VERSION_1_8
54 | }
55 | }
56 |
57 |
58 | // Because the components are created only during the afterEvaluate phase, you must
59 | // configure your publications using the afterEvaluate() lifecycle method.
60 | afterEvaluate {
61 | publishing {
62 | publications {
63 | // Creates a Maven publication called "release".
64 | release(MavenPublication) {
65 | // Applies the component for the release build variant.
66 | from components.release
67 |
68 | // You can then customize attributes of the publication as shown below.
69 | groupId = 'com.github.alibaba'
70 | artifactId = 'gaia-motion-curve'
71 | version = '0.1.0'
72 | }
73 | // Creates a Maven publication called “debug”.
74 | debug(MavenPublication) {
75 | // Applies the component for the debug build variant.
76 | from components.debug
77 |
78 | groupId = 'com.github.alibaba'
79 | artifactId = 'gaia-motion-curve'
80 | version = '0.1.0-DEV'
81 | }
82 | }
83 | }
84 | }
--------------------------------------------------------------------------------
/Android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app"s APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
--------------------------------------------------------------------------------
/Android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alibaba/gaia-motion-curve/84f3567dd2725efb9e4dd459c3e303591eafcbfd/Android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/Android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Jan 06 14:12:50 CST 2022
2 | distributionBase=GRADLE_USER_HOME
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
4 | distributionPath=wrapper/dists
5 | zipStorePath=wrapper/dists
6 | zipStoreBase=GRADLE_USER_HOME
7 |
--------------------------------------------------------------------------------
/Android/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | #
4 | # Copyright 2015 the original author or authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | ##
21 | ## Gradle start up script for UN*X
22 | ##
23 | ##############################################################################
24 |
25 | # Attempt to set APP_HOME
26 | # Resolve links: $0 may be a link
27 | PRG="$0"
28 | # Need this for relative symlinks.
29 | while [ -h "$PRG" ] ; do
30 | ls=`ls -ld "$PRG"`
31 | link=`expr "$ls" : '.*-> \(.*\)$'`
32 | if expr "$link" : '/.*' > /dev/null; then
33 | PRG="$link"
34 | else
35 | PRG=`dirname "$PRG"`"/$link"
36 | fi
37 | done
38 | SAVED="`pwd`"
39 | cd "`dirname \"$PRG\"`/" >/dev/null
40 | APP_HOME="`pwd -P`"
41 | cd "$SAVED" >/dev/null
42 |
43 | APP_NAME="Gradle"
44 | APP_BASE_NAME=`basename "$0"`
45 |
46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
48 |
49 | # Use the maximum available, or set MAX_FD != -1 to use that value.
50 | MAX_FD="maximum"
51 |
52 | warn () {
53 | echo "$*"
54 | }
55 |
56 | die () {
57 | echo
58 | echo "$*"
59 | echo
60 | exit 1
61 | }
62 |
63 | # OS specific support (must be 'true' or 'false').
64 | cygwin=false
65 | msys=false
66 | darwin=false
67 | nonstop=false
68 | case "`uname`" in
69 | CYGWIN* )
70 | cygwin=true
71 | ;;
72 | Darwin* )
73 | darwin=true
74 | ;;
75 | MINGW* )
76 | msys=true
77 | ;;
78 | NONSTOP* )
79 | nonstop=true
80 | ;;
81 | esac
82 |
83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84 |
85 |
86 | # Determine the Java command to use to start the JVM.
87 | if [ -n "$JAVA_HOME" ] ; then
88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
89 | # IBM's JDK on AIX uses strange locations for the executables
90 | JAVACMD="$JAVA_HOME/jre/sh/java"
91 | else
92 | JAVACMD="$JAVA_HOME/bin/java"
93 | fi
94 | if [ ! -x "$JAVACMD" ] ; then
95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
96 |
97 | Please set the JAVA_HOME variable in your environment to match the
98 | location of your Java installation."
99 | fi
100 | else
101 | JAVACMD="java"
102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
103 |
104 | Please set the JAVA_HOME variable in your environment to match the
105 | location of your Java installation."
106 | fi
107 |
108 | # Increase the maximum file descriptors if we can.
109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
110 | MAX_FD_LIMIT=`ulimit -H -n`
111 | if [ $? -eq 0 ] ; then
112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
113 | MAX_FD="$MAX_FD_LIMIT"
114 | fi
115 | ulimit -n $MAX_FD
116 | if [ $? -ne 0 ] ; then
117 | warn "Could not set maximum file descriptor limit: $MAX_FD"
118 | fi
119 | else
120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
121 | fi
122 | fi
123 |
124 | # For Darwin, add options to specify how the application appears in the dock
125 | if $darwin; then
126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
127 | fi
128 |
129 | # For Cygwin or MSYS, switch paths to Windows format before running java
130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
133 |
134 | JAVACMD=`cygpath --unix "$JAVACMD"`
135 |
136 | # We build the pattern for arguments to be converted via cygpath
137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
138 | SEP=""
139 | for dir in $ROOTDIRSRAW ; do
140 | ROOTDIRS="$ROOTDIRS$SEP$dir"
141 | SEP="|"
142 | done
143 | OURCYGPATTERN="(^($ROOTDIRS))"
144 | # Add a user-defined pattern to the cygpath arguments
145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
147 | fi
148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
149 | i=0
150 | for arg in "$@" ; do
151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
153 |
154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
156 | else
157 | eval `echo args$i`="\"$arg\""
158 | fi
159 | i=`expr $i + 1`
160 | done
161 | case $i in
162 | 0) set -- ;;
163 | 1) set -- "$args0" ;;
164 | 2) set -- "$args0" "$args1" ;;
165 | 3) set -- "$args0" "$args1" "$args2" ;;
166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
172 | esac
173 | fi
174 |
175 | # Escape application args
176 | save () {
177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
178 | echo " "
179 | }
180 | APP_ARGS=`save "$@"`
181 |
182 | # Collect all arguments for the java command, following the shell quoting and substitution rules
183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
184 |
185 | exec "$JAVACMD" "$@"
186 |
--------------------------------------------------------------------------------
/Android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/Android/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/Android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
--------------------------------------------------------------------------------
/Android/src/main/java/com/gaia/MotionCurve/GaiaMotionCurveAccelerateInterpolator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022, Alibaba Group Holding Limited;
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.gaia.MotionCurve;
18 |
19 |
20 | import android.view.animation.Interpolator;
21 |
22 |
23 | public class GaiaMotionCurveAccelerateInterpolator implements Interpolator {
24 | private float x1;
25 | private float y1;
26 | private float x2;
27 | private float y2;
28 |
29 | public GaiaMotionCurveAccelerateInterpolator() {
30 | x1 = 0.4f;
31 | y1 = 0.0f;
32 | x2 = 1.0f;
33 | y2 = 1.0f;
34 | }
35 |
36 | public GaiaMotionCurveAccelerateInterpolator(float a_x1, float a_y1, float a_x2, float a_y2) {
37 | x1 = a_x1;
38 | y1 = a_y1;
39 | x2 = a_x2;
40 | y2 = a_y2;
41 | }
42 |
43 | @Override
44 | public float getInterpolation(float p) {
45 | float x = p;
46 | float z;
47 | float ax, ay, bx, by, cx, cy;
48 | for (int i = 1; i < 14; i++) {
49 | cx = 3.0f * x1;
50 | bx = 3.0f * (x2 - x1) - cx;
51 | ax = 1.0f - cx - bx;
52 | float b = x * (cx + x * (bx + x * ax));
53 | z = b - p;
54 | if (Math.abs(z) < 1e-3) {
55 | break;
56 | }
57 | float d = cx + x * (2.0f * bx + 3.0f * ax * x);
58 | x -= z / d;
59 | }
60 | cy = 3.0f * y1;
61 | by = 3.0f * (y2 - y1) - cy;
62 | ay = 1.0f - cy - by;
63 | return x * (cy + x * (by + x * ay));
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/Android/src/main/java/com/gaia/MotionCurve/GaiaMotionCurveAnticipateInterpolator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022, Alibaba Group Holding Limited;
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.gaia.MotionCurve;
18 |
19 | import android.view.animation.Interpolator;
20 |
21 |
22 | public class GaiaMotionCurveAnticipateInterpolator implements Interpolator {
23 | private float d, x1, y1, x2, y2, x3, y3, x4, y4;
24 |
25 | public GaiaMotionCurveAnticipateInterpolator() {
26 | d = 1.2f;
27 | x1 = 0.33f;
28 | y1 = 0.0f;
29 | x2 = 0.3f;
30 | y2 = 1.0f;
31 | x3 = 0.33f;
32 | y3 = 0.0f;
33 | x4 = 0.5f;
34 | y4 = 1.0f;
35 | }
36 |
37 | public GaiaMotionCurveAnticipateInterpolator(float a_d, float a_x1, float a_y1, float a_x2, float a_y2, float a_x3, float a_y3, float a_x4, float a_y4) {
38 | d = a_d;
39 | x1 = a_x1;
40 | y1 = a_y1;
41 | x2 = a_x2;
42 | y2 = a_y2;
43 | x3 = a_x3;
44 | y3 = a_y3;
45 | x4 = a_x4;
46 | y4 = a_y4;
47 | }
48 |
49 | @Override
50 | public float getInterpolation(float p) {
51 | if (p <= 0.3f) {
52 | return -d * mcx_standard_curve(p * 3.33f, x1, y1, x2, y2);
53 | } else {
54 | return -d * mcx_standard_curve(0.3f * 3.33f, x1, y1, x2, y2) + (1 + d) * mcx_standard_curve((p - 0.3f) * 1.42f, x3, y3, x4, y4);
55 | }
56 | }
57 |
58 | private float mcx_standard_curve(float p, float a_x1, float a_y1, float a_x2, float a_y2) {
59 | float x = p;
60 | float z;
61 | float ax, ay, bx, by, cx, cy;
62 | for (int i = 1; i < 14; i++) {
63 | cx = 3 * a_x1;
64 | bx = 3 * (a_x2 - a_x1) - cx;
65 | ax = 1 - cx - bx;
66 | float b = x * (cx + x * (bx + x * ax));
67 | z = b - p;
68 | if (Math.abs(z) < 1e-3) {
69 | break;
70 | }
71 | float d = cx + x * (2 * bx + 3 * ax * x);
72 | x -= z / d;
73 | }
74 | cy = 3 * a_y1;
75 | by = 3 * (a_y2 - a_y1) - cy;
76 | ay = 1 - cy - by;
77 | return x * (cy + x * (by + x * ay));
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/Android/src/main/java/com/gaia/MotionCurve/GaiaMotionCurveBounceInterpolator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022, Alibaba Group Holding Limited;
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.gaia.MotionCurve;
18 |
19 | import android.view.animation.Interpolator;
20 |
21 |
22 |
23 | public class GaiaMotionCurveBounceInterpolator implements Interpolator {
24 | private float v, d;
25 |
26 | public GaiaMotionCurveBounceInterpolator() {
27 | v = 1.0f;
28 | d = 1.0f;
29 | }
30 |
31 | public GaiaMotionCurveBounceInterpolator(float a_v, float a_d) {
32 | v = a_v;
33 | d = a_d;
34 | }
35 |
36 | @Override
37 | public float getInterpolation(float p) {
38 | float tp = p;
39 | float b = 2.75f*v;
40 | if (tp < (1.0f/b)) {
41 | return (float) Math.pow(b, 2.0f)*tp*tp;
42 | } else if (tp < (2.0f/b)) {
43 | return (float)Math.pow(b*d, 2.0f)*(tp - 1.5f/b)*(tp - 1.5f/b) + (float)(1.0f - Math.pow(b*d, 2.0f)*(1.0f/b - 1.5f/b)*(1.0f/b - 1.5f/b));
44 | } else if (tp < (2.5f/b)) {
45 | return (float)Math.pow(b*d, 2.0f)*(tp - 2.25f/b)*(tp - 2.25f/b) + (float)(1.0f - Math.pow(b*d, 2.0f)*(2.0f/b- 2.25f/b)*(2.0f/b - 2.25f/b));
46 | } else {
47 | return (float)Math.min(1.0f, Math.pow(b*d, 2.0f)*(tp - 2.625f/b)*(tp - 2.625f/b) + (float)(1.0f - Math.pow(b*d, 2.0f)*(2.5f/b - 2.625f/b)*(2.5f/b - 2.625f/b))) ;
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Android/src/main/java/com/gaia/MotionCurve/GaiaMotionCurveCosineInterpolator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022, Alibaba Group Holding Limited;
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.gaia.MotionCurve;
18 |
19 | import android.view.animation.Interpolator;
20 |
21 |
22 | public class GaiaMotionCurveCosineInterpolator implements Interpolator {
23 | private float d, c;
24 |
25 | public GaiaMotionCurveCosineInterpolator() {
26 | d = 1.0f;
27 | c = 1.0f;
28 | }
29 |
30 | public GaiaMotionCurveCosineInterpolator(float a_d, float a_c) {
31 | d = a_d;
32 | c = a_c;
33 | }
34 |
35 | @Override
36 | public float getInterpolation(float p) {
37 | return d * 0.5f * (1.0f - (float) Math.cos(p * 2.0f * c * Math.PI));
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Android/src/main/java/com/gaia/MotionCurve/GaiaMotionCurveCubicBezierInterpolator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022, Alibaba Group Holding Limited;
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.gaia.MotionCurve;
18 |
19 | import android.view.animation.Interpolator;
20 |
21 |
22 | public class GaiaMotionCurveCubicBezierInterpolator implements Interpolator {
23 | private float x1, y1, x2, y2;
24 |
25 | public GaiaMotionCurveCubicBezierInterpolator() {
26 | x1 = 0.4f;
27 | y1 = 0.0f;
28 | x2 = 0.1f;
29 | y2 = 1.0f;
30 | }
31 |
32 | public GaiaMotionCurveCubicBezierInterpolator(float a_x1, float a_y1, float a_x2, float a_y2) {
33 | x1 = a_x1;
34 | y1 = a_y1;
35 | x2 = a_x2;
36 | y2 = a_y2;
37 | }
38 |
39 | @Override
40 | public float getInterpolation(float p) {
41 | float x = p;
42 | float z;
43 | float ax, ay, bx, by, cx, cy;
44 | for (int i = 1; i < 14; i++) {
45 | cx = 3 * x1;
46 | bx = 3 * (x2 - x1) - cx;
47 | ax = 1 - cx - bx;
48 | float b = x * (cx + x * (bx + x * ax));
49 | z = b - p;
50 | if (Math.abs(z) < 1e-3) {
51 | break;
52 | }
53 | float d = cx + x * (2 * bx + 3 * ax * x);
54 | x -= z / d;
55 | }
56 | cy = 3 * y1;
57 | by = 3 * (y2 - y1) - cy;
58 | ay = 1 - cy - by;
59 | return x * (cy + x * (by + x * ay));
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/Android/src/main/java/com/gaia/MotionCurve/GaiaMotionCurveDecelerateInterpolator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022, Alibaba Group Holding Limited;
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.gaia.MotionCurve;
18 |
19 | import android.view.animation.Interpolator;
20 |
21 | public class GaiaMotionCurveDecelerateInterpolator implements Interpolator {
22 | private float x1;
23 | private float y1;
24 | private float x2;
25 | private float y2;
26 |
27 | public GaiaMotionCurveDecelerateInterpolator() {
28 | x1 = 0.0f;
29 | y1 = 0.0f;
30 | x2 = 0.1f;
31 | y2 = 1.0f;
32 | }
33 |
34 | public GaiaMotionCurveDecelerateInterpolator(float a_x1, float a_y1, float a_x2, float a_y2) {
35 | x1 = a_x1;
36 | y1 = a_y1;
37 | x2 = a_x2;
38 | y2 = a_y2;
39 | }
40 |
41 | @Override
42 | public float getInterpolation(float p) {
43 | float x = p;
44 | float z;
45 | float ax, ay, bx, by, cx, cy;
46 | for (int i = 1; i < 14; i++) {
47 | cx = 3.0f * x1;
48 | bx = 3.0f * (x2 - x1) - cx;
49 | ax = 1.0f - cx - bx;
50 | float b = x * (cx + x * (bx + x * ax));
51 | z = b - p;
52 | if (Math.abs(z) < 1e-3) {
53 | break;
54 | }
55 | float d = cx + x * (2.0f * bx + 3.0f * ax * x);
56 | x -= z / d;
57 | }
58 | cy = 3.0f * y1;
59 | by = 3.0f * (y2 - y1) - cy;
60 | ay = 1.0f - cy - by;
61 | return x * (cy + x * (by + x * ay));
62 | }
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/Android/src/main/java/com/gaia/MotionCurve/GaiaMotionCurveLinearInterpolator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022, Alibaba Group Holding Limited;
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.gaia.MotionCurve;
18 |
19 | import android.view.animation.Interpolator;
20 |
21 |
22 | public class GaiaMotionCurveLinearInterpolator implements Interpolator {
23 | @Override
24 | public float getInterpolation(float p) {
25 | return p;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Android/src/main/java/com/gaia/MotionCurve/GaiaMotionCurveOvershootInterpolator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022, Alibaba Group Holding Limited;
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.gaia.MotionCurve;
18 |
19 | import android.view.animation.Interpolator;
20 |
21 |
22 | public class GaiaMotionCurveOvershootInterpolator implements Interpolator {
23 | private float d, x1, y1, x2, y2, x3, y3, x4, y4;
24 |
25 | public GaiaMotionCurveOvershootInterpolator() {
26 | d = 1.2f;
27 | x1 = 0.33f;
28 | y1 = 0.0f;
29 | x2 = 0.3f;
30 | y2 = 1.0f;
31 | x3 = 0.33f;
32 | y3 = 0.0f;
33 | x4 = 0.5f;
34 | y4 = 1.0f;
35 | }
36 |
37 | public GaiaMotionCurveOvershootInterpolator(float a_d, float a_x1, float a_y1, float a_x2, float a_y2, float a_x3, float a_y3, float a_x4, float a_y4) {
38 | d = a_d;
39 | x1 = a_x1;
40 | y1 = a_y1;
41 | x2 = a_x2;
42 | y2 = a_y2;
43 | x3 = a_x3;
44 | y3 = a_y3;
45 | x4 = a_x4;
46 | y4 = a_y4;
47 | }
48 |
49 | public GaiaMotionCurveOvershootInterpolator setDamping(float d){
50 | this.d = d;
51 | return this;
52 | }
53 |
54 | @Override
55 | public float getInterpolation(float p) {
56 | if (p <= 0.5f) {
57 | return d * mcx_standard_curve(p * 2, x1, y1, x2, y2);
58 | } else {
59 | return d * mcx_standard_curve(0.5f * 2.0f, x1, y1, x2, y2) - (d - 1) * mcx_standard_curve((p - 0.5f) * 2.0f, x3, y3, x4, y4);
60 | }
61 | }
62 |
63 | private float mcx_standard_curve(float p, float a_x1, float a_y1, float a_x2, float a_y2) {
64 | float x = p;
65 | float z;
66 | float ax, ay, bx, by, cx, cy;
67 | for (int i = 1; i < 14; i++) {
68 | cx = 3 * a_x1;
69 | bx = 3 * (a_x2 - a_x1) - cx;
70 | ax = 1 - cx - bx;
71 | float b = x * (cx + x * (bx + x * ax));
72 | z = b - p;
73 | if (Math.abs(z) < 1e-3) {
74 | break;
75 | }
76 | float d = cx + x * (2 * bx + 3 * ax * x);
77 | x -= z / d;
78 | }
79 | cy = 3 * a_y1;
80 | by = 3 * (a_y2 - a_y1) - cy;
81 | ay = 1 - cy - by;
82 | return x * (cy + x * (by + x * ay));
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/Android/src/main/java/com/gaia/MotionCurve/GaiaMotionCurveSpringInterpolator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022, Alibaba Group Holding Limited;
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.gaia.MotionCurve;
18 |
19 | import android.view.animation.Interpolator;
20 |
21 |
22 | public class GaiaMotionCurveSpringInterpolator implements Interpolator {
23 | private float m, s, d, iv;
24 | // private float t, f, v;
25 | private boolean MassSystem;
26 |
27 | public GaiaMotionCurveSpringInterpolator() {
28 | m = 0.7f;
29 | s = 380.0f;
30 | d = 10.0f;
31 | iv = -2.0f;
32 | // t = 533.0f;
33 | // f = 14.0f;
34 | // v = -2.0f;
35 | MassSystem = true;
36 | }
37 |
38 | public GaiaMotionCurveSpringInterpolator(float a_m, float a_s, float a_d, float a_iv) {
39 | m = a_m;
40 | s = a_s;
41 | d = a_d;
42 | iv = a_iv;
43 | MassSystem = true;
44 | }
45 |
46 | // GaiaMotionCurveSpringInterpolator(float a_t, float a_f, float a_v) {
47 | // t = a_t;
48 | // f = a_f;
49 | // v = a_v;
50 | // }
51 |
52 | @Override
53 | public float getInterpolation(float p) {
54 | float result = 0;
55 | // if (MassSystem) {
56 | float m_w0 = (float) Math.sqrt(s / m);
57 | float m_zeta = (float) (d / (2.0f * Math.sqrt(s * m)));
58 | float m_wd;
59 | float m_A;
60 | float m_B;
61 | if (m_zeta < 1.0f) {
62 | m_wd = (float) (m_w0 * Math.sqrt(1.0f - m_zeta * m_zeta));
63 | m_A = 1.0f;
64 | m_B = (m_zeta * m_w0 + -iv) / m_wd;
65 | } else {
66 | m_wd = 0.0f;
67 | m_A = 1.0f;
68 | m_B = -iv + m_w0;
69 | }
70 | float t;
71 | if (m_zeta < 1.0f) {
72 | t = (float) (Math.exp(-p * m_zeta * m_w0) * (m_A * Math.cos(m_wd * p) + m_B * Math.sin(m_wd * p)));
73 | } else {
74 | t = (float) ((m_A + m_B * p) * Math.exp(-p * m_w0));
75 | }
76 | result = 1.0f - t;
77 | // }
78 | return result;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/Android/src/main/java/com/gaia/MotionCurve/GaiaMotionCurveStandardInterpolator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022, Alibaba Group Holding Limited;
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.gaia.MotionCurve;
18 |
19 | import android.view.animation.Interpolator;
20 |
21 | public class GaiaMotionCurveStandardInterpolator implements Interpolator {
22 | private float x1, y1, x2, y2;
23 |
24 | public GaiaMotionCurveStandardInterpolator() {
25 | x1 = 0.4f;
26 | y1 = 0.0f;
27 | x2 = 0.1f;
28 | y2 = 1.0f;
29 | }
30 |
31 | public GaiaMotionCurveStandardInterpolator(float a_x1, float a_y1, float a_x2, float a_y2) {
32 | x1 = a_x1;
33 | y1 = a_y1;
34 | x2 = a_x2;
35 | y2 = a_y2;
36 | }
37 |
38 | @Override
39 | public float getInterpolation(float p) {
40 | float x = p;
41 | float z;
42 | float ax, ay, bx, by, cx, cy;
43 | for (int i = 1; i < 14; i++) {
44 | cx = 3 * x1;
45 | bx = 3 * (x2 - x1) - cx;
46 | ax = 1 - cx - bx;
47 | float b = x * (cx + x * (bx + x * ax));
48 | z = b - p;
49 | if (Math.abs(z) < 1e-3) {
50 | break;
51 | }
52 | float d = cx + x * (2 * bx + 3 * ax * x);
53 | x -= z / d;
54 | }
55 | cy = 3 * y1;
56 | by = 3 * (y2 - y1) - cy;
57 | ay = 1 - cy - by;
58 | return x * (cy + x * (by + x * ay));
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/Android/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | GaiaMotionCurve
3 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 动效曲线
2 |
3 | > [en-US](./README_en.md)
4 |
5 | 动效曲线SDK 由一系列的动效曲线函数构成,为了解决开发动效的成本高、效果和设计的预期不一致的问题,每个动效曲线函数可应用于任意一个可动效的属性上,通过改变动效过程中的速率和方向给用户带来更好的体验,目前包括线性曲线、加速曲线、减速曲线、余弦曲线、过度曲线、预期曲线、标准曲线(三次贝塞尔曲线)、弹跳曲线、弹性曲线等,目前支持 iOS 和 Android;
6 |
7 | [语雀知识库地址](https://www.yuque.com/youku-gaia/gaia-motion-curve)
8 |
9 | `iOS`和`Android`均用同一套动效曲线的算法实现,保证双端的动效的一致性,iOS 上层封装使用的是`Core Animation`,Android 则是使用的`插值器`。
10 |
11 | ## iOS
12 |
13 | #### 安装
14 |
15 | ```ruby
16 | pod 'GaiaMotionCurve', '0.1.0'
17 | ```
18 |
19 | #### 头文件
20 |
21 | ```objc
22 | #import
23 | ```
24 |
25 | #### 例子
26 |
27 | ```objc
28 |
29 | #import
30 |
31 | NSMutableArray *animationModels = [[NSMutableArray alloc] init];
32 | GMCModel *model1 =[GMCModel modelWithKeyPath:@"opacity"
33 | duration:0.2
34 | delay:0
35 | curveType:MCXCurveTypeStandard
36 | fromValue:[NSValue gmc_valueWithCGFloat:0]
37 | toValue:[NSValue gmc_valueWithCGFloat:0.9]];
38 | [animationModels addObject:model1];
39 | [_tipsImageView.layer gmc_animateWithAnimationModels:animationModels completion:^(BOOL finished) {}];
40 |
41 | ```
42 |
43 | #### [完整iOS Demo 工程](./examples/iOS)
44 |
45 |
46 | ## Android
47 |
48 | #### 安装
49 |
50 | 引入编译的aar文件
51 |
52 | > 目录:src/Android/build/outputs
53 |
54 | #### 包名
55 |
56 | ```java
57 |
58 | import com.gaia.MotionCurve.*;
59 |
60 | ```
61 |
62 | #### 例子
63 |
64 | ```java
65 |
66 | TranslateAnimation animation = new TranslateAnimation(0, displaySize.x - maxTextWidth - 2 * margin, 0, 0);
67 | animation.setFillAfter(true);
68 | animation.setDuration(ANIMATION_DURATION);
69 | animation.setInterpolator(new MotionCurveXStandardInterpolator());
70 | view.startAnimation(animation);
71 |
72 | ```
73 |
74 | #### [完整Android Demo 工程](./examples/Android)
75 |
76 | ## 曲线分类
77 |
78 | * [线性曲线](./docs/zh-CN/linear.md)
79 | * [加速曲线](./docs/zh-CN/accelerate.md)
80 | * [减速曲线](./docs/zh-CN/decelerate.md)
81 | * [标准曲线](./docs/zh-CN/standard.md)
82 | * [预期曲线](./docs/zh-CN/anticipate.md)
83 | * [过度曲线](./docs/zh-CN/overshoot.md)
84 | * [弹性曲线](./docs/zh-CN/spring.md)
85 | * [弹跳曲线](./docs/zh-CN/bounce.md)
86 | * [余弦曲线](./docs/zh-CN/cosine.md)
87 |
88 | # 行为准则
89 |
90 | 请参考[Alibaba Open Source Code of Conduct](https://github.com/AlibabaDR/community/blob/master/CODE_OF_CONDUCT.md) ([中文版](https://github.com/AlibabaDR/community/blob/master/CODE_OF_CONDUCT_zh.md)).
91 |
92 |
93 | # 开源协议
94 |
95 | gaia-motion-curve is licensed under the Apache License, Version 2.0. See LICENSE for the full license text.
96 |
97 |
--------------------------------------------------------------------------------
/README_en.md:
--------------------------------------------------------------------------------
1 | # Motion Curve
2 |
3 | The Motion Curve SDK consists of a series of dynamic curve functions. In order to solve the problems of high cost of developing dynamic effects and inconsistent effects and design expectations, each dynamic curve function can be applied to any dynamic attribute. Bring a better experience to users by changing the speed and direction in the animation process, currently including linear curve, acceleration curve, deceleration curve, cosine curve, transition curve, expected curve, standard curve (cubic Bezier curve), bounce Curves, elastic curves, etc., currently support iOS and Android;
4 |
5 | [YuQue](https://www.yuque.com/youku-gaia/gaia-motion-curve)
6 |
7 | Both `iOS` and `Android` are implemented with the same set of motion curve algorithms to ensure the consistency of motion effects at both ends. The upper layer package of iOS uses `Core Animation`, and Android uses `Interpolator`.
8 |
9 | ## iOS
10 |
11 | #### Install
12 |
13 | ```ruby
14 | pod 'GaiaMotionCurve', '0.1.0'
15 | ```
16 |
17 | #### Header
18 |
19 | ```objc
20 | #import
21 | ```
22 |
23 | #### Example
24 |
25 | ```objc
26 | #import
27 |
28 | NSMutableArray *animationModels = [[NSMutableArray alloc] init];
29 | GMCModel *model1 =[GMCModel modelWithKeyPath:@"opacity"
30 | duration:0.2
31 | delay:0
32 | curveType:MCXCurveTypeStandard
33 | fromValue:[NSValue gmc_valueWithCGFloat:0]
34 | toValue:[NSValue gmc_valueWithCGFloat:0.9]];
35 | [animationModels addObject:model1];
36 | [_tipsImageView.layer gmc_animateWithAnimationModels:animationModels completion:^(BOOL finished) {}];
37 |
38 | ```
39 |
40 | #### [Full iOS Demo Project](./examples/iOS)
41 |
42 |
43 | ## Android
44 |
45 | #### Install
46 |
47 | import compiled aar file
48 |
49 | > Directory:src/Android/build/outputs
50 |
51 | #### Package
52 |
53 | ```java
54 | import com.gaia.MotionCurve.*;
55 | ```
56 |
57 | #### Example
58 |
59 | ```java
60 | TranslateAnimation animation = new TranslateAnimation(0, displaySize.x - maxTextWidth - 2 * margin, 0, 0);
61 | animation.setFillAfter(true);
62 | animation.setDuration(ANIMATION_DURATION);
63 | animation.setInterpolator(new MotionCurveXStandardInterpolator());
64 | view.startAnimation(animation);
65 |
66 | ```
67 |
68 | #### [Full Android Demo Project](./examples/Android)
69 |
70 | ## Motion Curve Categories
71 |
72 | * [Linear](./docs/en-US/linear.md)
73 | * [Accelerate](./docs/en-US/accelerate.md)
74 | * [Decelerate](./docs/en-US/decelerate.md)
75 | * [Standard](./docs/en-US/standard.md)
76 | * [Anticipate](./docs/en-US/anticipate.md)
77 | * [Overshoot](./docs/en-US/overshoot.md)
78 | * [Spring](./docs/en-US/spring.md)
79 | * [Bounce](./docs/en-US/bounce.md)
80 | * [Cosine](./docs/en-US/cosine.md)
81 |
82 | # Code of Conduct
83 |
84 | Please refer to [Alibaba Open Source Code of Conduct](https://github.com/AlibabaDR/community/blob/master/CODE_OF_CONDUCT.md).
85 |
86 |
87 | # LICENCE
88 |
89 | gaia-motion-curve is licensed under the Apache License, Version 2.0. See LICENSE for the full license text.
90 |
91 |
--------------------------------------------------------------------------------
/docs/assets/accelerate.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alibaba/gaia-motion-curve/84f3567dd2725efb9e4dd459c3e303591eafcbfd/docs/assets/accelerate.gif
--------------------------------------------------------------------------------
/docs/assets/anticipate.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alibaba/gaia-motion-curve/84f3567dd2725efb9e4dd459c3e303591eafcbfd/docs/assets/anticipate.gif
--------------------------------------------------------------------------------
/docs/assets/bounce.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alibaba/gaia-motion-curve/84f3567dd2725efb9e4dd459c3e303591eafcbfd/docs/assets/bounce.gif
--------------------------------------------------------------------------------
/docs/assets/cosine.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alibaba/gaia-motion-curve/84f3567dd2725efb9e4dd459c3e303591eafcbfd/docs/assets/cosine.gif
--------------------------------------------------------------------------------
/docs/assets/decelerate.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alibaba/gaia-motion-curve/84f3567dd2725efb9e4dd459c3e303591eafcbfd/docs/assets/decelerate.gif
--------------------------------------------------------------------------------
/docs/assets/linear.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alibaba/gaia-motion-curve/84f3567dd2725efb9e4dd459c3e303591eafcbfd/docs/assets/linear.gif
--------------------------------------------------------------------------------
/docs/assets/overshoot.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alibaba/gaia-motion-curve/84f3567dd2725efb9e4dd459c3e303591eafcbfd/docs/assets/overshoot.gif
--------------------------------------------------------------------------------
/docs/assets/spring.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alibaba/gaia-motion-curve/84f3567dd2725efb9e4dd459c3e303591eafcbfd/docs/assets/spring.gif
--------------------------------------------------------------------------------
/docs/assets/standard.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alibaba/gaia-motion-curve/84f3567dd2725efb9e4dd459c3e303591eafcbfd/docs/assets/standard.gif
--------------------------------------------------------------------------------
/docs/en-US/accelerate.md:
--------------------------------------------------------------------------------
1 | # Accelerate
2 |
3 | ## Demo
4 |
5 |
6 |
7 | ## iOS
8 |
9 | Enumerate:GMCCurveTypeAccelerate
10 |
11 | ```objc
12 | #import
13 |
14 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
15 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
16 | duration:0.75
17 | delay:0
18 | curveType:GMCCurveTypeAccelerate
19 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
20 | toValue:[NSValue gmc_valueWithCGFloat:right]];
21 | __weak typeof(self) weakSelf = self;
22 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
23 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
24 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
25 | });
26 | }];
27 | ```
28 |
29 | ## Android
30 |
31 | Interpolator:GaiaMotionCurveAccelerateInterpolator
32 |
33 | ```java
34 | import com.gaia.MotionCurve.*;
35 |
36 | View animationView = findViewById(R.id.animation_view);
37 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
38 | animation.setFillAfter(true);
39 | animation.setDuration(700);
40 | animation.setInterpolator(new GaiaMotionCurveAccelerateInterpolator());
41 | animationView.startAnimation(animation);
42 | ```
43 |
44 | ## Customizable Parameters
45 |
46 | Configurable Parameters:
47 |
48 | ```
49 | x1: x coordinate of control point x1
50 | y1: y coordinate of control point y1
51 | x2: x coordinate of control point x2
52 | y2: y coordinate of control point y2
53 | ```
54 |
55 | Default:
56 |
57 | ```
58 | x1 = 0.4
59 | y1 = 0.0
60 | x2 = 1.0
61 | y2 = 1.0
62 | ```
63 |
64 | iOS
65 |
66 | ```objective-c
67 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
68 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
69 | duration:0.75
70 | delay:0
71 | curveType:GMCCurveTypeAccelerate
72 | customArgs:@{@"x1":@0.4,@"y1":@0.0,@"x2":@1.0,@"y2":@1.0}
73 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
74 | toValue:[NSValue gmc_valueWithCGFloat:right]];
75 | __weak typeof(self) weakSelf = self;
76 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
77 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
78 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
79 | });
80 | }];
81 | ```
82 |
83 | Android
84 |
85 | ```java
86 | View animationView = findViewById(R.id.animation_view);
87 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
88 | animation.setFillAfter(true);
89 | animation.setDuration(700);
90 | animation.setInterpolator(new GaiaMotionCurveAccelerateInterpolator(0.4, 0.0, 1.0, 1.0));
91 | animationView.startAnimation(animation);
92 | ```
93 |
94 |
--------------------------------------------------------------------------------
/docs/en-US/anticipate.md:
--------------------------------------------------------------------------------
1 | # Anticipate
2 |
3 | ## Demo
4 |
5 |
6 |
7 | ## iOS
8 |
9 | Enumerate:GMCCurveTypeAnticipate
10 |
11 | ```objc
12 | #import
13 |
14 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
15 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
16 | duration:0.75
17 | delay:0
18 | curveType:GMCCurveTypeAnticipate
19 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
20 | toValue:[NSValue gmc_valueWithCGFloat:right]];
21 | __weak typeof(self) weakSelf = self;
22 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
23 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
24 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
25 | });
26 | }];
27 | ```
28 |
29 | ## Android
30 |
31 | Interpolator:GaiaMotionCurveAnticipateInterpolator
32 |
33 | ```java
34 | import com.gaia.MotionCurve.*;
35 |
36 | View animationView = findViewById(R.id.animation_view);
37 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
38 | animation.setFillAfter(true);
39 | animation.setDuration(700);
40 | animation.setInterpolator(new GaiaMotionCurveAnticipateInterpolator());
41 | animationView.startAnimation(animation);
42 | ```
43 |
44 | ## Customizable Parameters
45 |
46 | Configurable Parameters:
47 |
48 | ```
49 | d: damping, controls the height of the highest point
50 | x1: x coordinate of control point x1
51 | y1: y coordinate of control point y1
52 | x2: x coordinate of control point x2
53 | y2: y coordinate of control point y2
54 | x3: x coordinate of control point x3
55 | y3: y coordinate of control point y3
56 | x4: x coordinate of control point x4
57 | y4: y coordinate of control point y4
58 | ```
59 |
60 | Default:
61 |
62 | ```
63 | d = 0.2
64 | x1 = 0.33
65 | y1 = 0.0
66 | x2 = 0.67
67 | y2 = 1.0
68 | x3 = 0.33
69 | y3 = 0.0
70 | x4 = 0.2
71 | y4 = 1.0
72 | ```
73 |
74 | iOS
75 |
76 | ```objective-c
77 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
78 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
79 | duration:0.75
80 | delay:0
81 | curveType:GMCCurveTypeAnticipate
82 | customArgs:@{@"d":@0.2,@"x1":@0.33,@"y1":@0.0,@"x2":@0.67,@"y2":@1.0,
83 | @"x3":@0.33,@"y3":@0.0,@"x4":@0.2,@"y4":@1.0}
84 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
85 | toValue:[NSValue gmc_valueWithCGFloat:right]];
86 | __weak typeof(self) weakSelf = self;
87 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
88 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
89 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
90 | });
91 | }];
92 | ```
93 |
94 | Android
95 |
96 | ```java
97 | View animationView = findViewById(R.id.animation_view);
98 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
99 | animation.setFillAfter(true);
100 | animation.setDuration(700);
101 | animation.setInterpolator(new GaiaMotionCurveAnticipateInterpolator(0.2,0.33,0.0,0.67,1.0,0.33,0.0,0.2,1.0));
102 | animationView.startAnimation(animation);
103 | ```
104 |
105 |
--------------------------------------------------------------------------------
/docs/en-US/bounce.md:
--------------------------------------------------------------------------------
1 | # Bounce
2 |
3 | ## Demo
4 |
5 |
6 |
7 | ## iOS
8 |
9 | Enumerate:GMCCurveTypeBounce
10 |
11 | ```objc
12 | #import
13 |
14 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
15 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
16 | duration:0.75
17 | delay:0
18 | curveType:GMCCurveTypeBounce
19 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
20 | toValue:[NSValue gmc_valueWithCGFloat:right]];
21 | __weak typeof(self) weakSelf = self;
22 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
23 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
24 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
25 | });
26 | }];
27 | ```
28 |
29 | ## Android
30 |
31 | Interpolator:GaiaMotionCurveBounceInterpolator
32 |
33 | ```java
34 | import com.gaia.MotionCurve.*;
35 |
36 | View animationView = findViewById(R.id.animation_view);
37 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
38 | animation.setFillAfter(true);
39 | animation.setDuration(700);
40 | animation.setInterpolator(new GaiaMotionCurveBounceInterpolator());
41 | animationView.startAnimation(animation);
42 | ```
43 |
44 | ## Customizable Parameters
45 |
46 | Configurable Parameters:
47 |
48 | ```
49 | v:velocity
50 | d:damping
51 | ```
52 |
53 | Default:
54 |
55 | ```
56 | v = 1.0
57 | d = 1.0
58 | ```
59 |
60 | iOS
61 |
62 | ```objective-c
63 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
64 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
65 | duration:0.75
66 | delay:0
67 | curveType:GMCCurveTypeBounce
68 | customArgs:@{@"v":@1.0,@"d":@1.0}
69 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
70 | toValue:[NSValue gmc_valueWithCGFloat:right]];
71 | __weak typeof(self) weakSelf = self;
72 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
73 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
74 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
75 | });
76 | }];
77 | ```
78 |
79 | Android
80 |
81 | ```java
82 | View animationView = findViewById(R.id.animation_view);
83 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
84 | animation.setFillAfter(true);
85 | animation.setDuration(700);
86 | animation.setInterpolator(new GaiaMotionCurveBounceInterpolator(1.0, 1.0));
87 | animationView.startAnimation(animation);
88 | ```
89 |
90 |
--------------------------------------------------------------------------------
/docs/en-US/cosine.md:
--------------------------------------------------------------------------------
1 | # Cosine
2 |
3 | ## Demo
4 |
5 |
6 |
7 | ## iOS
8 |
9 | Enumerate:GMCCurveTypeCosine
10 |
11 | ```objc
12 | #import
13 |
14 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
15 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
16 | duration:0.75
17 | delay:0
18 | curveType:GMCCurveTypeCosine
19 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
20 | toValue:[NSValue gmc_valueWithCGFloat:right]];
21 | __weak typeof(self) weakSelf = self;
22 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
23 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
24 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
25 | });
26 | }];
27 | ```
28 |
29 | ## Android
30 |
31 | Interpolator:GaiaMotionCurveCosineInterpolator
32 |
33 | ```java
34 | import com.gaia.MotionCurve.*;
35 |
36 | View animationView = findViewById(R.id.animation_view);
37 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
38 | animation.setFillAfter(true);
39 | animation.setDuration(700);
40 | animation.setInterpolator(new GaiaMotionCurveCosineInterpolator());
41 | animationView.startAnimation(animation);
42 | ```
43 |
44 | ## Customizable Parameters
45 |
46 | Configurable Parameters:
47 |
48 | ```
49 | d:damping
50 | c:cycles, multiples of 0.25
51 | ```
52 |
53 | Default:
54 |
55 | ```
56 | d = 1.0
57 | c = 1.0
58 | ```
59 |
60 | iOS
61 |
62 | ```objective-c
63 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
64 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
65 | duration:0.75
66 | delay:0
67 | curveType:GMCCurveTypeCosine
68 | customArgs:@{@"d":@1.0,@"c":@1.0}
69 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
70 | toValue:[NSValue gmc_valueWithCGFloat:right]];
71 | __weak typeof(self) weakSelf = self;
72 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
73 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
74 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
75 | });
76 | }];
77 | ```
78 |
79 | Android
80 |
81 | ```java
82 | View animationView = findViewById(R.id.animation_view);
83 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
84 | animation.setFillAfter(true);
85 | animation.setDuration(700);
86 | animation.setInterpolator(new GaiaMotionCurveCosineInterpolator(1.0, 1.0));
87 | animationView.startAnimation(animation);
88 | ```
89 |
90 |
--------------------------------------------------------------------------------
/docs/en-US/decelerate.md:
--------------------------------------------------------------------------------
1 | # Decelerate
2 |
3 | ## Demo
4 |
5 |
6 |
7 | ## iOS
8 |
9 | Enumerate:GMCCurveTypeDecelerate
10 |
11 | ```objc
12 | #import
13 |
14 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
15 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
16 | duration:0.75
17 | delay:0
18 | curveType:GMCCurveTypeDecelerate
19 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
20 | toValue:[NSValue gmc_valueWithCGFloat:right]];
21 | __weak typeof(self) weakSelf = self;
22 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
23 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
24 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
25 | });
26 | }];
27 | ```
28 |
29 | ## Android
30 |
31 | Interpolator:GaiaMotionCurveDecelerateInterpolator
32 |
33 | ```java
34 | import com.gaia.MotionCurve.*;
35 |
36 | View animationView = findViewById(R.id.animation_view);
37 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
38 | animation.setFillAfter(true);
39 | animation.setDuration(700);
40 | animation.setInterpolator(new GaiaMotionCurveDecelerateInterpolator());
41 | animationView.startAnimation(animation);
42 | ```
43 |
44 | ## Customizable Parameters
45 |
46 | Configurable Parameters:
47 |
48 | ```
49 | x1: x coordinate of control point x1
50 | y1: y coordinate of control point y1
51 | x2: x coordinate of control point x2
52 | y2: y coordinate of control point y2
53 | ```
54 |
55 | Default:
56 |
57 | ```
58 | x1 = 0.0
59 | y1 = 0.0
60 | x2 = 0.1
61 | y2 = 1.0
62 | ```
63 |
64 | iOS
65 |
66 | ```objective-c
67 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
68 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
69 | duration:0.75
70 | delay:0
71 | curveType:GMCCurveTypeDecelerate
72 | customArgs:@{@"x1":@0.0,@"y1":@0.0,@"x2":@0.1,@"y2":@1.0}
73 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
74 | toValue:[NSValue gmc_valueWithCGFloat:right]];
75 | __weak typeof(self) weakSelf = self;
76 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
77 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
78 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
79 | });
80 | }];
81 | ```
82 |
83 | Android
84 |
85 | ```java
86 | View animationView = findViewById(R.id.animation_view);
87 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
88 | animation.setFillAfter(true);
89 | animation.setDuration(700);
90 | animation.setInterpolator(new GaiaMotionCurveDecelerateInterpolator(0.0, 0.0, 0.1, 1.0));
91 | animationView.startAnimation(animation);
92 | ```
93 |
94 |
--------------------------------------------------------------------------------
/docs/en-US/linear.md:
--------------------------------------------------------------------------------
1 | # Linear
2 |
3 | ## Demo
4 |
5 |
6 |
7 | ## iOS
8 |
9 | Enumerate:GMCCurveTypeLinear
10 |
11 | ```objc
12 | #import
13 |
14 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
15 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
16 | duration:0.75
17 | delay:0
18 | curveType:GMCCurveTypeLinear
19 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
20 | toValue:[NSValue gmc_valueWithCGFloat:right]];
21 | __weak typeof(self) weakSelf = self;
22 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
23 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
24 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
25 | });
26 | }];
27 | ```
28 |
29 | ## Android
30 |
31 | Interpolator:GaiaMotionCurveLinearInterpolator
32 |
33 | ```java
34 | import com.gaia.MotionCurve.*;
35 |
36 | View animationView = findViewById(R.id.animation_view);
37 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
38 | animation.setFillAfter(true);
39 | animation.setDuration(700);
40 | animation.setInterpolator(new GaiaMotionCurveLinearInterpolator());
41 | animationView.startAnimation(animation);
42 | ```
43 |
44 | ## Customizable Parameters
45 |
46 | None
47 |
--------------------------------------------------------------------------------
/docs/en-US/overshoot.md:
--------------------------------------------------------------------------------
1 | # Overshoot
2 |
3 | ## Demo
4 |
5 |
6 |
7 |
8 |
9 | ## iOS
10 |
11 | Enumerate:GMCCurveTypeOvershoot
12 |
13 | ```objc
14 | #import
15 |
16 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
17 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
18 | duration:0.75
19 | delay:0
20 | curveType:GMCCurveTypeOvershoot
21 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
22 | toValue:[NSValue gmc_valueWithCGFloat:right]];
23 | __weak typeof(self) weakSelf = self;
24 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
25 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
26 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
27 | });
28 | }];
29 | ```
30 |
31 | ## Android
32 |
33 | Interpolator:GaiaMotionCurveOvershootInterpolator
34 |
35 | ```java
36 | import com.gaia.MotionCurve.*;
37 |
38 | View animationView = findViewById(R.id.animation_view);
39 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
40 | animation.setFillAfter(true);
41 | animation.setDuration(700);
42 | animation.setInterpolator(new GaiaMotionCurveOvershootInterpolator());
43 | animationView.startAnimation(animation);
44 | ```
45 |
46 | ## Customizable Parameters
47 |
48 | Configurable Parameters:
49 |
50 | ```
51 | d: damping, controls the height of the highest point
52 | x1: x coordinate of control point x1
53 | y1: y coordinate of control point y1
54 | x2: x coordinate of control point x2
55 | y2: y coordinate of control point y2
56 | x3: x coordinate of control point x3
57 | y3: y coordinate of control point y3
58 | x4: x coordinate of control point x4
59 | y4: y coordinate of control point y4
60 | ```
61 |
62 | Default:
63 |
64 | ```
65 | d = 1.2
66 | x1 = 0.33
67 | y1 = 0.0
68 | x2 = 0.3
69 | y2 = 1.0
70 | x3 = 0.33
71 | y3 = 0.0
72 | x4 = 0.5
73 | y4 = 1.0
74 | ```
75 |
76 | iOS
77 |
78 | ```objective-c
79 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
80 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
81 | duration:0.75
82 | delay:0
83 | curveType:GMCCurveTypeOvershoot
84 | customArgs:@{@"d":@1.2,@"x1":@0.33,@"y1":@0.0,@"x2":@0.3,@"y2":@1.0,
85 | @"x3":@0.33,@"y3":@0.0,@"x4":@0.5,@"y4":@1.0}
86 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
87 | toValue:[NSValue gmc_valueWithCGFloat:right]];
88 | __weak typeof(self) weakSelf = self;
89 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
90 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
91 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
92 | });
93 | }];
94 | ```
95 |
96 | Android
97 |
98 | ```java
99 | View animationView = findViewById(R.id.animation_view);
100 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
101 | animation.setFillAfter(true);
102 | animation.setDuration(700);
103 | animation.setInterpolator(new GaiaMotionCurveOvershootInterpolator(1.2,0.33,0.0,0.3,1.0,0.33,0.0,0.5,1.0));
104 | animationView.startAnimation(animation);
105 | ```
106 |
107 |
--------------------------------------------------------------------------------
/docs/en-US/spring.md:
--------------------------------------------------------------------------------
1 | # Spring
2 |
3 | ## Demo
4 |
5 |
6 |
7 | ## iOS
8 |
9 | Enumerate:GMCCurveTypeSpring
10 |
11 | ```objc
12 | #import
13 |
14 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
15 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
16 | duration:0.75
17 | delay:0
18 | curveType:GMCCurveTypeSpring
19 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
20 | toValue:[NSValue gmc_valueWithCGFloat:right]];
21 | __weak typeof(self) weakSelf = self;
22 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
23 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
24 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
25 | });
26 | }];
27 | ```
28 |
29 | ## Android
30 |
31 | Interpolator:GaiaMotionCurveSpringInterpolator
32 |
33 | ```java
34 | import com.gaia.MotionCurve.*;
35 |
36 | View animationView = findViewById(R.id.animation_view);
37 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
38 | animation.setFillAfter(true);
39 | animation.setDuration(700);
40 | animation.setInterpolator(new GaiaMotionCurveSpringInterpolator());
41 | animationView.startAnimation(animation);
42 | ```
43 |
44 | ## Customizable Parameters
45 |
46 | Configurable Parameters:
47 |
48 | Spring curve supports two parameter systems, Mass and RK4 (Android only supports Mass system temporarily)
49 |
50 | **Mass System:**
51 |
52 | ```
53 | m: mass
54 | s: stiffness
55 | d: damping
56 | iv:velocity
57 | ```
58 |
59 | Default:
60 |
61 | ```
62 | m = 0.7
63 | s = 380.0
64 | d = 10.0
65 | iv = -2.0
66 | ```
67 |
68 | iOS
69 |
70 | ```objective-c
71 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
72 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
73 | duration:0.75
74 | delay:0
75 | curveType:GMCCurveTypeSpring
76 | customArgs:@{@"m":@1.0,@"s":@380.0,@"d":@10.0,@"iv":@-2.0}
77 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
78 | toValue:[NSValue gmc_valueWithCGFloat:right]];
79 | __weak typeof(self) weakSelf = self;
80 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
81 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
82 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
83 | });
84 | }];
85 | ```
86 |
87 | Android
88 |
89 | ```java
90 | View animationView = findViewById(R.id.animation_view);
91 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
92 | animation.setFillAfter(true);
93 | animation.setDuration(700);
94 | animation.setInterpolator(new GaiaMotionCurveSpringInterpolator(0.7, 380.0, 10.0, -2.0));
95 | animationView.startAnimation(animation);
96 | ```
97 |
98 | **RK4 System:**
99 |
100 | ```
101 | t: tension
102 | f: friction
103 | v: velocity
104 | ```
105 |
106 | Default:
107 |
108 | ```
109 | t = 533.0
110 | f = 14.0
111 | v = -2.0
112 | ```
113 |
114 | iOS
115 |
116 | ```objective-c
117 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
118 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
119 | duration:0.75
120 | delay:0
121 | curveType:GMCCurveTypeSpring
122 | customArgs:@{@"t":@533.0,@"f":@14.0,@"v":@-2.0}
123 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
124 | toValue:[NSValue gmc_valueWithCGFloat:right]];
125 | __weak typeof(self) weakSelf = self;
126 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
127 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
128 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
129 | });
130 | }];
131 | ```
132 |
133 |
--------------------------------------------------------------------------------
/docs/en-US/standard.md:
--------------------------------------------------------------------------------
1 | # Standard
2 |
3 | ## Demo
4 |
5 |
6 |
7 | ## iOS
8 |
9 | Enumerate:GMCCurveTypeStandard
10 |
11 | ```objc
12 | #import
13 |
14 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
15 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
16 | duration:0.75
17 | delay:0
18 | curveType:GMCCurveTypeStandard
19 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
20 | toValue:[NSValue gmc_valueWithCGFloat:right]];
21 | __weak typeof(self) weakSelf = self;
22 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
23 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
24 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
25 | });
26 | }];
27 | ```
28 |
29 | ## Android
30 |
31 | Interpolator:GaiaMotionCurveStandardInterpolator
32 |
33 | ```java
34 | import com.gaia.MotionCurve.*;
35 |
36 | View animationView = findViewById(R.id.animation_view);
37 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
38 | animation.setFillAfter(true);
39 | animation.setDuration(700);
40 | animation.setInterpolator(new GaiaMotionCurveStandardInterpolator());
41 | animationView.startAnimation(animation);
42 | ```
43 |
44 | ## Customizable Parameters
45 |
46 | Configurable Parameters:
47 |
48 | ```
49 | x1: x coordinate of control point x1
50 | y1: y coordinate of control point y1
51 | x2: x coordinate of control point x2
52 | y2: y coordinate of control point y2
53 | ```
54 |
55 | Default:
56 |
57 | ```
58 | x1 = 0.4
59 | y1 = 0.0
60 | x2 = 0.1
61 | y2 = 1.0
62 | ```
63 |
64 | iOS
65 |
66 | ```objective-c
67 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
68 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
69 | duration:0.75
70 | delay:0
71 | curveType:GMCCurveTypeStandard
72 | customArgs:@{@"x1":@0.4,@"y1":@0.0,@"x2":@0.1,@"y2":@1.0}
73 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
74 | toValue:[NSValue gmc_valueWithCGFloat:right]];
75 | __weak typeof(self) weakSelf = self;
76 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
77 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
78 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
79 | });
80 | }];
81 | ```
82 |
83 | Android
84 |
85 | ```java
86 | View animationView = findViewById(R.id.animation_view);
87 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
88 | animation.setFillAfter(true);
89 | animation.setDuration(700);
90 | animation.setInterpolator(new GaiaMotionCurveStandardInterpolator(0.4, 0.0, 0.1, 1.0));
91 | animationView.startAnimation(animation);
92 | ```
93 |
94 |
--------------------------------------------------------------------------------
/docs/zh-CN/accelerate.md:
--------------------------------------------------------------------------------
1 | # 加速曲线
2 |
3 | ## 演示
4 |
5 |
6 |
7 | ## iOS
8 |
9 | 枚举:GMCCurveTypeAccelerate
10 |
11 | ```objc
12 | #import
13 |
14 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
15 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
16 | duration:0.75
17 | delay:0
18 | curveType:GMCCurveTypeAccelerate
19 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
20 | toValue:[NSValue gmc_valueWithCGFloat:right]];
21 | __weak typeof(self) weakSelf = self;
22 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
23 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
24 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
25 | });
26 | }];
27 | ```
28 |
29 | ## Android
30 |
31 | 差值器:GaiaMotionCurveAccelerateInterpolator
32 |
33 | ```java
34 | import com.gaia.MotionCurve.*;
35 |
36 | View animationView = findViewById(R.id.animation_view);
37 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
38 | animation.setFillAfter(true);
39 | animation.setDuration(700);
40 | animation.setInterpolator(new GaiaMotionCurveAccelerateInterpolator());
41 | animationView.startAnimation(animation);
42 | ```
43 |
44 | ## 可自定义的参数
45 |
46 | 可配置的参数:
47 |
48 | ```
49 | x1:控制点1的x坐标
50 | y1:控制点1的y坐标
51 | x2:控制点2的x坐标
52 | y2:控制点2的y坐标
53 | ```
54 |
55 | 默认值:
56 |
57 | ```
58 | x1 = 0.4
59 | y1 = 0.0
60 | x2 = 1.0
61 | y2 = 1.0
62 | ```
63 |
64 | iOS
65 |
66 | ```objective-c
67 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
68 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
69 | duration:0.75
70 | delay:0
71 | curveType:GMCCurveTypeAccelerate
72 | customArgs:@{@"x1":@0.4,@"y1":@0.0,@"x2":@1.0,@"y2":@1.0}
73 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
74 | toValue:[NSValue gmc_valueWithCGFloat:right]];
75 | __weak typeof(self) weakSelf = self;
76 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
77 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
78 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
79 | });
80 | }];
81 | ```
82 |
83 | Android
84 |
85 | ```java
86 | View animationView = findViewById(R.id.animation_view);
87 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
88 | animation.setFillAfter(true);
89 | animation.setDuration(700);
90 | animation.setInterpolator(new GaiaMotionCurveAccelerateInterpolator(0.4, 0.0, 1.0, 1.0));
91 | animationView.startAnimation(animation);
92 | ```
93 |
94 |
--------------------------------------------------------------------------------
/docs/zh-CN/anticipate.md:
--------------------------------------------------------------------------------
1 | # 预期曲线
2 |
3 | ## 演示
4 |
5 |
6 |
7 | ## iOS
8 |
9 | 枚举:GMCCurveTypeAnticipate
10 |
11 | ```objc
12 | #import
13 |
14 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
15 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
16 | duration:0.75
17 | delay:0
18 | curveType:GMCCurveTypeAnticipate
19 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
20 | toValue:[NSValue gmc_valueWithCGFloat:right]];
21 | __weak typeof(self) weakSelf = self;
22 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
23 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
24 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
25 | });
26 | }];
27 | ```
28 |
29 | ## Android
30 |
31 | 差值器:GaiaMotionCurveAnticipateInterpolator
32 |
33 | ```java
34 | import com.gaia.MotionCurve.*;
35 |
36 | View animationView = findViewById(R.id.animation_view);
37 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
38 | animation.setFillAfter(true);
39 | animation.setDuration(700);
40 | animation.setInterpolator(new GaiaMotionCurveAnticipateInterpolator());
41 | animationView.startAnimation(animation);
42 | ```
43 |
44 | ## 可自定义的参数
45 |
46 | 可配置的参数:
47 |
48 | ```
49 | d:damping的缩写,控制的是最低点的高低
50 | x1:控制点1的x坐标
51 | y1:控制点1的y坐标
52 | x2:控制点2的x坐标
53 | y2:控制点2的y坐标
54 | x3:控制点3的x坐标
55 | y3:控制点3的y坐标
56 | x4:控制点4的x坐标
57 | y4:控制点4的y坐标
58 | ```
59 |
60 | 默认值为:
61 |
62 | ```
63 | d = 0.2
64 | x1 = 0.33
65 | y1 = 0.0
66 | x2 = 0.67
67 | y2 = 1.0
68 | x3 = 0.33
69 | y3 = 0.0
70 | x4 = 0.2
71 | y4 = 1.0
72 | ```
73 |
74 | iOS
75 |
76 | ```objective-c
77 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
78 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
79 | duration:0.75
80 | delay:0
81 | curveType:GMCCurveTypeAnticipate
82 | customArgs:@{@"d":@0.2,@"x1":@0.33,@"y1":@0.0,@"x2":@0.67,@"y2":@1.0,
83 | @"x3":@0.33,@"y3":@0.0,@"x4":@0.2,@"y4":@1.0}
84 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
85 | toValue:[NSValue gmc_valueWithCGFloat:right]];
86 | __weak typeof(self) weakSelf = self;
87 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
88 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
89 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
90 | });
91 | }];
92 | ```
93 |
94 | Android
95 |
96 | ```java
97 | View animationView = findViewById(R.id.animation_view);
98 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
99 | animation.setFillAfter(true);
100 | animation.setDuration(700);
101 | animation.setInterpolator(new GaiaMotionCurveAnticipateInterpolator(0.2,0.33,0.0,0.67,1.0,0.33,0.0,0.2,1.0));
102 | animationView.startAnimation(animation);
103 | ```
104 |
105 |
--------------------------------------------------------------------------------
/docs/zh-CN/bounce.md:
--------------------------------------------------------------------------------
1 | # 弹跳曲线
2 |
3 | ## 演示
4 |
5 |
6 |
7 | ## iOS
8 |
9 | 枚举:GMCCurveTypeBounce
10 |
11 | ```objc
12 | #import
13 |
14 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
15 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
16 | duration:0.75
17 | delay:0
18 | curveType:GMCCurveTypeBounce
19 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
20 | toValue:[NSValue gmc_valueWithCGFloat:right]];
21 | __weak typeof(self) weakSelf = self;
22 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
23 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
24 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
25 | });
26 | }];
27 | ```
28 |
29 | ## Android
30 |
31 | 差值器:GaiaMotionCurveBounceInterpolator
32 |
33 | ```java
34 | import com.gaia.MotionCurve.*;
35 |
36 | View animationView = findViewById(R.id.animation_view);
37 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
38 | animation.setFillAfter(true);
39 | animation.setDuration(700);
40 | animation.setInterpolator(new GaiaMotionCurveBounceInterpolator());
41 | animationView.startAnimation(animation);
42 | ```
43 |
44 | ## 可自定义的参数
45 |
46 | 可配置的参数:
47 |
48 | ```
49 | v:velocity的缩写
50 | d:damping的缩写
51 | ```
52 |
53 | 默认值为:
54 |
55 | ```
56 | v = 1.0
57 | d = 1.0
58 | ```
59 |
60 | iOS
61 |
62 | ```objective-c
63 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
64 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
65 | duration:0.75
66 | delay:0
67 | curveType:GMCCurveTypeBounce
68 | customArgs:@{@"v":@1.0,@"d":@1.0}
69 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
70 | toValue:[NSValue gmc_valueWithCGFloat:right]];
71 | __weak typeof(self) weakSelf = self;
72 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
73 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
74 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
75 | });
76 | }];
77 | ```
78 |
79 | Android
80 |
81 | ```java
82 | View animationView = findViewById(R.id.animation_view);
83 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
84 | animation.setFillAfter(true);
85 | animation.setDuration(700);
86 | animation.setInterpolator(new GaiaMotionCurveBounceInterpolator(1.0, 1.0));
87 | animationView.startAnimation(animation);
88 | ```
89 |
90 |
--------------------------------------------------------------------------------
/docs/zh-CN/cosine.md:
--------------------------------------------------------------------------------
1 | # 余弦曲线
2 |
3 | ## 演示
4 |
5 |
6 |
7 | ## iOS
8 |
9 | 枚举:GMCCurveTypeCosine
10 |
11 | ```objc
12 | #import
13 |
14 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
15 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
16 | duration:0.75
17 | delay:0
18 | curveType:GMCCurveTypeCosine
19 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
20 | toValue:[NSValue gmc_valueWithCGFloat:right]];
21 | __weak typeof(self) weakSelf = self;
22 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
23 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
24 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
25 | });
26 | }];
27 | ```
28 |
29 | ## Android
30 |
31 | 差值器:GaiaMotionCurveCosineInterpolator
32 |
33 | ```java
34 | import com.gaia.MotionCurve.*;
35 |
36 | View animationView = findViewById(R.id.animation_view);
37 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
38 | animation.setFillAfter(true);
39 | animation.setDuration(700);
40 | animation.setInterpolator(new GaiaMotionCurveCosineInterpolator());
41 | animationView.startAnimation(animation);
42 | ```
43 |
44 | ## 可自定义的参数
45 |
46 | 可配置的参数:
47 |
48 | ```
49 | d:damping的缩写,控制的是最高点的高低
50 | c:cycles的缩写,周期的次数且是0.25的倍数
51 | ```
52 |
53 | 默认值为:
54 |
55 | ```
56 | d = 1.0
57 | c = 1.0
58 | ```
59 |
60 | iOS
61 |
62 | ```objective-c
63 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
64 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
65 | duration:0.75
66 | delay:0
67 | curveType:GMCCurveTypeCosine
68 | customArgs:@{@"d":@1.0,@"c":@1.0}
69 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
70 | toValue:[NSValue gmc_valueWithCGFloat:right]];
71 | __weak typeof(self) weakSelf = self;
72 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
73 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
74 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
75 | });
76 | }];
77 | ```
78 |
79 | Android
80 |
81 | ```java
82 | View animationView = findViewById(R.id.animation_view);
83 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
84 | animation.setFillAfter(true);
85 | animation.setDuration(700);
86 | animation.setInterpolator(new GaiaMotionCurveCosineInterpolator(1.0, 1.0));
87 | animationView.startAnimation(animation);
88 | ```
89 |
90 |
--------------------------------------------------------------------------------
/docs/zh-CN/decelerate.md:
--------------------------------------------------------------------------------
1 | # 减速曲线
2 |
3 | ## 演示
4 |
5 |
6 |
7 | ## iOS
8 |
9 | 枚举:GMCCurveTypeDecelerate
10 |
11 | ```objc
12 | #import
13 |
14 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
15 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
16 | duration:0.75
17 | delay:0
18 | curveType:GMCCurveTypeDecelerate
19 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
20 | toValue:[NSValue gmc_valueWithCGFloat:right]];
21 | __weak typeof(self) weakSelf = self;
22 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
23 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
24 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
25 | });
26 | }];
27 | ```
28 |
29 | ## Android
30 |
31 | 差值器:GaiaMotionCurveDecelerateInterpolator
32 |
33 | ```java
34 | import com.gaia.MotionCurve.*;
35 |
36 | View animationView = findViewById(R.id.animation_view);
37 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
38 | animation.setFillAfter(true);
39 | animation.setDuration(700);
40 | animation.setInterpolator(new GaiaMotionCurveDecelerateInterpolator());
41 | animationView.startAnimation(animation);
42 | ```
43 |
44 | ## 可自定义的参数
45 |
46 | 可配置的参数:
47 |
48 | ```
49 | x1:控制点1的x坐标
50 | y1:控制点1的y坐标
51 | x2:控制点2的x坐标
52 | y2:控制点2的y坐标
53 | ```
54 |
55 | 默认值为:
56 |
57 | ```
58 | x1 = 0.0
59 | y1 = 0.0
60 | x2 = 0.1
61 | y2 = 1.0
62 | ```
63 |
64 | iOS
65 |
66 | ```objective-c
67 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
68 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
69 | duration:0.75
70 | delay:0
71 | curveType:GMCCurveTypeDecelerate
72 | customArgs:@{@"x1":@0.0,@"y1":@0.0,@"x2":@0.1,@"y2":@1.0}
73 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
74 | toValue:[NSValue gmc_valueWithCGFloat:right]];
75 | __weak typeof(self) weakSelf = self;
76 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
77 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
78 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
79 | });
80 | }];
81 | ```
82 |
83 | Android
84 |
85 | ```java
86 | View animationView = findViewById(R.id.animation_view);
87 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
88 | animation.setFillAfter(true);
89 | animation.setDuration(700);
90 | animation.setInterpolator(new GaiaMotionCurveDecelerateInterpolator(0.0, 0.0, 0.1, 1.0));
91 | animationView.startAnimation(animation);
92 | ```
93 |
94 |
--------------------------------------------------------------------------------
/docs/zh-CN/linear.md:
--------------------------------------------------------------------------------
1 | # 线性曲线
2 |
3 | ## 演示
4 |
5 |
6 |
7 | ## iOS
8 |
9 | 枚举:GMCCurveTypeLinear
10 |
11 | ```objc
12 | #import
13 |
14 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
15 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
16 | duration:0.75
17 | delay:0
18 | curveType:GMCCurveTypeLinear
19 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
20 | toValue:[NSValue gmc_valueWithCGFloat:right]];
21 | __weak typeof(self) weakSelf = self;
22 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
23 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
24 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
25 | });
26 | }];
27 | ```
28 |
29 | ## Android
30 |
31 | 差值器:GaiaMotionCurveLinearInterpolator
32 |
33 | ```java
34 | import com.gaia.MotionCurve.*;
35 |
36 | View animationView = findViewById(R.id.animation_view);
37 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
38 | animation.setFillAfter(true);
39 | animation.setDuration(700);
40 | animation.setInterpolator(new GaiaMotionCurveLinearInterpolator());
41 | animationView.startAnimation(animation);
42 | ```
43 |
44 | ## 可自定义的参数
45 |
46 | 无
47 |
--------------------------------------------------------------------------------
/docs/zh-CN/overshoot.md:
--------------------------------------------------------------------------------
1 | # 过度曲线
2 |
3 | ## 演示
4 |
5 |
6 |
7 | ## iOS
8 |
9 | 枚举:GMCCurveTypeOvershoot
10 |
11 | ```objc
12 | #import
13 |
14 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
15 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
16 | duration:0.75
17 | delay:0
18 | curveType:GMCCurveTypeOvershoot
19 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
20 | toValue:[NSValue gmc_valueWithCGFloat:right]];
21 | __weak typeof(self) weakSelf = self;
22 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
23 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
24 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
25 | });
26 | }];
27 | ```
28 |
29 | ## Android
30 |
31 | 差值器:GaiaMotionCurveOvershootInterpolator
32 |
33 | ```java
34 | import com.gaia.MotionCurve.*;
35 |
36 | View animationView = findViewById(R.id.animation_view);
37 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
38 | animation.setFillAfter(true);
39 | animation.setDuration(700);
40 | animation.setInterpolator(new GaiaMotionCurveOvershootInterpolator());
41 | animationView.startAnimation(animation);
42 | ```
43 |
44 | ## 可自定义的参数
45 |
46 | 可配置的参数:
47 |
48 | ```
49 | d:damping的缩写,控制的是最高点的高低
50 | x1:控制点1的x坐标
51 | y1:控制点1的y坐标
52 | x2:控制点2的x坐标
53 | y2:控制点2的y坐标
54 | x3:控制点3的x坐标
55 | y3:控制点3的y坐标
56 | x4:控制点4的x坐标
57 | y4:控制点4的y坐标
58 | ```
59 |
60 | 默认值为:
61 |
62 | ```
63 | d = 1.2
64 | x1 = 0.33
65 | y1 = 0.0
66 | x2 = 0.3
67 | y2 = 1.0
68 | x3 = 0.33
69 | y3 = 0.0
70 | x4 = 0.5
71 | y4 = 1.0
72 | ```
73 |
74 | iOS
75 |
76 | ```objective-c
77 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
78 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
79 | duration:0.75
80 | delay:0
81 | curveType:GMCCurveTypeOvershoot
82 | customArgs:@{@"d":@1.2,@"x1":@0.33,@"y1":@0.0,@"x2":@0.3,@"y2":@1.0,
83 | @"x3":@0.33,@"y3":@0.0,@"x4":@0.5,@"y4":@1.0}
84 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
85 | toValue:[NSValue gmc_valueWithCGFloat:right]];
86 | __weak typeof(self) weakSelf = self;
87 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
88 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
89 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
90 | });
91 | }];
92 | ```
93 |
94 | Android
95 |
96 | ```java
97 | View animationView = findViewById(R.id.animation_view);
98 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
99 | animation.setFillAfter(true);
100 | animation.setDuration(700);
101 | animation.setInterpolator(new GaiaMotionCurveOvershootInterpolator(1.2,0.33,0.0,0.3,1.0,0.33,0.0,0.5,1.0));
102 | animationView.startAnimation(animation);
103 | ```
104 |
105 |
--------------------------------------------------------------------------------
/docs/zh-CN/spring.md:
--------------------------------------------------------------------------------
1 | # 弹性曲线
2 |
3 | ## 演示
4 |
5 |
6 |
7 | ## iOS
8 |
9 | 枚举:GMCCurveTypeSpring
10 |
11 | ```objc
12 | #import
13 |
14 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
15 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
16 | duration:0.75
17 | delay:0
18 | curveType:GMCCurveTypeSpring
19 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
20 | toValue:[NSValue gmc_valueWithCGFloat:right]];
21 | __weak typeof(self) weakSelf = self;
22 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
23 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
24 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
25 | });
26 | }];
27 | ```
28 |
29 | ## Android
30 |
31 | 差值器:GaiaMotionCurveSpringInterpolator
32 |
33 | ```java
34 | import com.gaia.MotionCurve.*;
35 |
36 | View animationView = findViewById(R.id.animation_view);
37 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
38 | animation.setFillAfter(true);
39 | animation.setDuration(700);
40 | animation.setInterpolator(new GaiaMotionCurveSpringInterpolator());
41 | animationView.startAnimation(animation);
42 | ```
43 |
44 | ## 可自定义的参数
45 |
46 | 可配置的参数:
47 |
48 | 弹性曲线支持Mass和RK4两套参数系统(Android暂时只支持Mass参数系统)
49 |
50 | **Mass参数系统:**
51 |
52 | ```
53 | m: mass的缩写
54 | s: stiffness的缩写
55 | d: damping的缩写
56 | iv:velocity的缩写
57 | ```
58 |
59 | 默认值为:
60 |
61 | ```
62 | m = 0.7
63 | s = 380.0
64 | d = 10.0
65 | iv = -2.0
66 | ```
67 |
68 | iOS
69 |
70 | ```objective-c
71 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
72 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
73 | duration:0.75
74 | delay:0
75 | curveType:GMCCurveTypeSpring
76 | customArgs:@{@"m":@1.0,@"s":@380.0,@"d":@10.0,@"iv":@-2.0}
77 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
78 | toValue:[NSValue gmc_valueWithCGFloat:right]];
79 | __weak typeof(self) weakSelf = self;
80 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
81 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
82 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
83 | });
84 | }];
85 | ```
86 |
87 | Android
88 |
89 | ```java
90 | View animationView = findViewById(R.id.animation_view);
91 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
92 | animation.setFillAfter(true);
93 | animation.setDuration(700);
94 | animation.setInterpolator(new GaiaMotionCurveSpringInterpolator(0.7, 380.0, 10.0, -2.0));
95 | animationView.startAnimation(animation);
96 | ```
97 |
98 | **RK4参数系统:**
99 |
100 | ```
101 | t: tension的缩写
102 | f: friction的缩写
103 | v: velocity的缩写
104 | ```
105 |
106 | 默认值为:
107 |
108 | ```
109 | t = 533.0
110 | f = 14.0
111 | v = -2.0
112 | ```
113 |
114 | iOS
115 |
116 | ```objective-c
117 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
118 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
119 | duration:0.75
120 | delay:0
121 | curveType:GMCCurveTypeSpring
122 | customArgs:@{@"t":@533.0,@"f":@14.0,@"v":@-2.0}
123 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
124 | toValue:[NSValue gmc_valueWithCGFloat:right]];
125 | __weak typeof(self) weakSelf = self;
126 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
127 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
128 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
129 | });
130 | }];
131 | ```
132 |
133 |
--------------------------------------------------------------------------------
/docs/zh-CN/standard.md:
--------------------------------------------------------------------------------
1 | # 标准曲线
2 |
3 | ## 演示
4 |
5 |
6 |
7 | ## iOS
8 |
9 | 枚举:GMCCurveTypeStandard
10 |
11 | ```objc
12 | #import
13 |
14 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
15 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
16 | duration:0.75
17 | delay:0
18 | curveType:GMCCurveTypeStandard
19 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
20 | toValue:[NSValue gmc_valueWithCGFloat:right]];
21 | __weak typeof(self) weakSelf = self;
22 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
23 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
24 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
25 | });
26 | }];
27 | ```
28 |
29 | ## Android
30 |
31 | 差值器:GaiaMotionCurveStandardInterpolator
32 |
33 | ```java
34 | import com.gaia.MotionCurve.*;
35 |
36 | View animationView = findViewById(R.id.animation_view);
37 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
38 | animation.setFillAfter(true);
39 | animation.setDuration(700);
40 | animation.setInterpolator(new GaiaMotionCurveStandardInterpolator());
41 | animationView.startAnimation(animation);
42 | ```
43 |
44 | ## 可自定义的参数
45 |
46 | 可配置的参数:
47 |
48 | ```
49 | x1:控制点1的x坐标
50 | y1:控制点1的y坐标
51 | x2:控制点2的x坐标
52 | y2:控制点2的y坐标
53 | ```
54 |
55 | 默认值为:
56 |
57 | ```
58 | x1 = 0.4
59 | y1 = 0.0
60 | x2 = 0.1
61 | y2 = 1.0
62 | ```
63 |
64 | iOS
65 |
66 | ```objective-c
67 | CGFloat right = [[UIScreen mainScreen] bounds].size.width - 80 - 20;
68 | GMCModel *model = [GMCModel modelWithKeyPath:@"position.x"
69 | duration:0.75
70 | delay:0
71 | curveType:GMCCurveTypeStandard
72 | customArgs:@{@"x1":@0.4,@"y1":@0.0,@"x2":@0.1,@"y2":@1.0}
73 | fromValue:[NSValue gmc_valueWithCGFloat:_animationView.center.x]
74 | toValue:[NSValue gmc_valueWithCGFloat:right]];
75 | __weak typeof(self) weakSelf = self;
76 | [_animationView.layer gmc_animateWithAnimationModels:@[model] completion:^(BOOL finished) {
77 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
78 | weakSelf.animationView.layer.frame = CGRectMake(80, 200, 40, 40);
79 | });
80 | }];
81 | ```
82 |
83 | Android
84 |
85 | ```java
86 | View animationView = findViewById(R.id.animation_view);
87 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
88 | animation.setFillAfter(true);
89 | animation.setDuration(700);
90 | animation.setInterpolator(new GaiaMotionCurveStandardInterpolator(0.4, 0.0, 0.1, 1.0));
91 | animationView.startAnimation(animation);
92 | ```
93 |
94 |
--------------------------------------------------------------------------------
/examples/Android/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 | local.properties
16 |
--------------------------------------------------------------------------------
/examples/Android/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/examples/Android/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.application'
3 | }
4 |
5 | android {
6 | compileSdk 32
7 |
8 | defaultConfig {
9 | applicationId "com.gaia.demo"
10 | minSdk 21
11 | targetSdk 32
12 | versionCode 1
13 | versionName "1.0"
14 |
15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
16 | }
17 |
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 | compileOptions {
25 | sourceCompatibility JavaVersion.VERSION_1_8
26 | targetCompatibility JavaVersion.VERSION_1_8
27 | }
28 | }
29 |
30 | dependencies {
31 | implementation fileTree(dir:'libs', includes: ['*.aar'])
32 | implementation 'androidx.appcompat:appcompat:1.4.0'
33 | implementation 'com.google.android.material:material:1.4.0'
34 | implementation 'androidx.constraintlayout:constraintlayout:2.1.2'
35 | testImplementation 'junit:junit:4.+'
36 | androidTestImplementation 'androidx.test.ext:junit:1.1.3'
37 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
38 | }
--------------------------------------------------------------------------------
/examples/Android/app/libs/gaia-motion-curve-0.1.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alibaba/gaia-motion-curve/84f3567dd2725efb9e4dd459c3e303591eafcbfd/examples/Android/app/libs/gaia-motion-curve-0.1.aar
--------------------------------------------------------------------------------
/examples/Android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/examples/Android/app/src/androidTest/java/com/gaia/demo/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.gaia.demo;
2 |
3 | import android.content.Context;
4 |
5 | import androidx.test.platform.app.InstrumentationRegistry;
6 | import androidx.test.ext.junit.runners.AndroidJUnit4;
7 |
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 |
11 | import static org.junit.Assert.*;
12 |
13 | /**
14 | * Instrumented test, which will execute on an Android device.
15 | *
16 | * @see Testing documentation
17 | */
18 | @RunWith(AndroidJUnit4.class)
19 | public class ExampleInstrumentedTest {
20 | @Test
21 | public void useAppContext() {
22 | // Context of the app under test.
23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
24 | assertEquals("com.gaia.demo", appContext.getPackageName());
25 | }
26 | }
--------------------------------------------------------------------------------
/examples/Android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
15 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/examples/Android/app/src/main/java/com/gaia/demo/AnimationActivity.java:
--------------------------------------------------------------------------------
1 | package com.gaia.demo;
2 |
3 | import androidx.appcompat.app.AppCompatActivity;
4 |
5 | import android.animation.ArgbEvaluator;
6 | import android.animation.ValueAnimator;
7 | import android.content.Intent;
8 | import android.os.Bundle;
9 | import android.view.View;
10 | import android.view.animation.AlphaAnimation;
11 | import android.view.animation.Animation;
12 | import android.view.animation.AnimationSet;
13 | import android.view.animation.Interpolator;
14 | import android.view.animation.RotateAnimation;
15 | import android.view.animation.ScaleAnimation;
16 | import android.view.animation.TranslateAnimation;
17 | import android.widget.Button;
18 |
19 | import com.gaia.MotionCurve.*;
20 |
21 | public class AnimationActivity extends AppCompatActivity {
22 |
23 | @Override
24 | protected void onCreate(Bundle savedInstanceState) {
25 | super.onCreate(savedInstanceState);
26 | setContentView(R.layout.activity_animation);
27 |
28 | Intent intent = getIntent();
29 | String curveType = intent.getStringExtra("curveType");
30 |
31 | Button positionButton = (Button) findViewById(R.id.animation_position);
32 | positionButton.setOnClickListener(new View.OnClickListener() {
33 | @Override
34 | public void onClick(View view) {
35 | View animationView = findViewById(R.id.animation_view);
36 | TranslateAnimation animation = new TranslateAnimation(0, 700, 0, 0);
37 | animation.setFillAfter(true);
38 | animation.setDuration(700);
39 | try {
40 | animation.setInterpolator((Interpolator)Class.forName("com.gaia.MotionCurve."+curveType).newInstance());
41 | animationView.startAnimation(animation);
42 | } catch (IllegalAccessException e) {
43 | e.printStackTrace();
44 | } catch (InstantiationException e) {
45 | e.printStackTrace();
46 | } catch (ClassNotFoundException e) {
47 | e.printStackTrace();
48 | }
49 | }
50 | });
51 |
52 | Button opacityButton = (Button) findViewById(R.id.animation_opacity);
53 | opacityButton.setOnClickListener(new View.OnClickListener() {
54 | @Override
55 | public void onClick(View view) {
56 | View animationView = findViewById(R.id.animation_view);
57 | AlphaAnimation animation = new AlphaAnimation(1, 0);
58 | animation.setFillAfter(true);
59 | animation.setDuration(700);
60 | try {
61 | animation.setInterpolator((Interpolator)Class.forName("com.gaia.MotionCurve."+curveType).newInstance());
62 | animationView.startAnimation(animation);
63 | } catch (IllegalAccessException e) {
64 | e.printStackTrace();
65 | } catch (InstantiationException e) {
66 | e.printStackTrace();
67 | } catch (ClassNotFoundException e) {
68 | e.printStackTrace();
69 | }
70 | }
71 | });
72 |
73 | Button colorButton = (Button) findViewById(R.id.animation_color);
74 | colorButton.setOnClickListener(new View.OnClickListener() {
75 | @Override
76 | public void onClick(View view) {
77 | View animationView = findViewById(R.id.animation_view);
78 |
79 | int colorFrom = getResources().getColor(R.color.black);
80 | int colorTo = getResources().getColor(R.color.red);
81 | ValueAnimator animation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
82 | animation.setDuration(700);
83 | try {
84 | animation.setInterpolator((Interpolator)Class.forName("com.gaia.MotionCurve."+curveType).newInstance());
85 | animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
86 |
87 | @Override
88 | public void onAnimationUpdate(ValueAnimator animator) {
89 | animationView.setBackgroundColor((int) animator.getAnimatedValue());
90 | }
91 |
92 | });
93 | animation.start();
94 | } catch (IllegalAccessException e) {
95 | e.printStackTrace();
96 | } catch (InstantiationException e) {
97 | e.printStackTrace();
98 | } catch (ClassNotFoundException e) {
99 | e.printStackTrace();
100 | }
101 | }
102 | });
103 |
104 | Button scaleButton = (Button) findViewById(R.id.animation_scale);
105 | scaleButton.setOnClickListener(new View.OnClickListener() {
106 | @Override
107 | public void onClick(View view) {
108 | View animationView = findViewById(R.id.animation_view);
109 | ScaleAnimation animation = new ScaleAnimation(1,2,1, 2, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,0.5f);
110 | animation.setFillAfter(true);
111 | animation.setDuration(700);
112 | try {
113 | animation.setInterpolator((Interpolator)Class.forName("com.gaia.MotionCurve."+curveType).newInstance());
114 | animationView.startAnimation(animation);
115 | } catch (IllegalAccessException e) {
116 | e.printStackTrace();
117 | } catch (InstantiationException e) {
118 | e.printStackTrace();
119 | } catch (ClassNotFoundException e) {
120 | e.printStackTrace();
121 | }
122 | }
123 | });
124 |
125 | Button rotationButton = (Button) findViewById(R.id.animation_rotation);
126 | rotationButton.setOnClickListener(new View.OnClickListener() {
127 | @Override
128 | public void onClick(View view) {
129 | View animationView = findViewById(R.id.animation_view);
130 | RotateAnimation animation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,0.5f);
131 | animation.setFillAfter(true);
132 | animation.setDuration(700);
133 | try {
134 | animation.setInterpolator((Interpolator)Class.forName("com.gaia.MotionCurve."+curveType).newInstance());
135 | animationView.startAnimation(animation);
136 | } catch (IllegalAccessException e) {
137 | e.printStackTrace();
138 | } catch (InstantiationException e) {
139 | e.printStackTrace();
140 | } catch (ClassNotFoundException e) {
141 | e.printStackTrace();
142 | }
143 | }
144 | });
145 |
146 | Button combButton = (Button) findViewById(R.id.animation_combination);
147 | combButton.setOnClickListener(new View.OnClickListener() {
148 | @Override
149 | public void onClick(View view) {
150 | View animationView = findViewById(R.id.animation_view);
151 | AnimationSet animationSet = new AnimationSet(false);
152 |
153 | RotateAnimation rotateAnimation= new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,0.5f);
154 | animationSet.addAnimation(rotateAnimation);
155 |
156 | ScaleAnimation scaleAnimation = new ScaleAnimation(1,2,1, 2, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,0.5f);
157 | animationSet.addAnimation(scaleAnimation);
158 |
159 | animationSet.setDuration(700);
160 | try {
161 | animationSet.setInterpolator((Interpolator)Class.forName("com.gaia.MotionCurve."+curveType).newInstance());
162 | animationView.startAnimation(animationSet);
163 | } catch (IllegalAccessException e) {
164 | e.printStackTrace();
165 | } catch (InstantiationException e) {
166 | e.printStackTrace();
167 | } catch (ClassNotFoundException e) {
168 | e.printStackTrace();
169 | }
170 | }
171 | });
172 | }
173 | }
--------------------------------------------------------------------------------
/examples/Android/app/src/main/java/com/gaia/demo/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.gaia.demo;
2 |
3 | import androidx.appcompat.app.AppCompatActivity;
4 |
5 | import android.content.Intent;
6 | import android.os.Bundle;
7 | import android.view.View;
8 | import android.widget.AdapterView;
9 | import android.widget.ArrayAdapter;
10 | import android.widget.ListView;
11 |
12 |
13 | public class MainActivity extends AppCompatActivity {
14 |
15 | String[] curveTitles = {"线性曲线(Linear)","加速曲线(Accelerate)","减速曲线(Decelerate)",
16 | "标准曲线(Standard)","预期曲线(Anticipate)","过度曲线(Overshoot)",
17 | "弹性曲线(Spring)","弹跳曲线(Bounce)","余弦曲线(Cosine)"};
18 |
19 | String[] curveTypes = {"GaiaMotionCurveLinearInterpolator","GaiaMotionCurveAccelerateInterpolator","GaiaMotionCurveDecelerateInterpolator",
20 | "GaiaMotionCurveStandardInterpolator","GaiaMotionCurveAnticipateInterpolator","GaiaMotionCurveOvershootInterpolator",
21 | "GaiaMotionCurveSpringInterpolator","GaiaMotionCurveBounceInterpolator","GaiaMotionCurveCosineInterpolator"};
22 |
23 | @Override
24 | protected void onCreate(Bundle savedInstanceState) {
25 | super.onCreate(savedInstanceState);
26 | setContentView(R.layout.activity_main);
27 |
28 | ArrayAdapter adapter = new ArrayAdapter(this,
29 | R.layout.activity_listview, curveTitles);
30 |
31 | ListView listView = (ListView) findViewById(R.id.gaia_motion_curve_list);
32 | listView.setAdapter(adapter);
33 |
34 | listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
35 | @Override
36 | public void onItemClick(AdapterView> adapterView, View view, int i, long l) {
37 | Intent intent = new Intent();
38 | intent.setClass(MainActivity.this, AnimationActivity.class);
39 | intent.putExtra("curveType", curveTypes[i]);
40 | startActivity(intent);
41 | }
42 | });
43 | }
44 | }
--------------------------------------------------------------------------------
/examples/Android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/examples/Android/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/examples/Android/app/src/main/res/layout/activity_animation.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
18 |
19 |
20 |
26 |
34 |
42 |
43 |
44 |
50 |
58 |
66 |
67 |
68 |
74 |
82 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/examples/Android/app/src/main/res/layout/activity_listview.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/examples/Android/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/examples/Android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/examples/Android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/examples/Android/app/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alibaba/gaia-motion-curve/84f3567dd2725efb9e4dd459c3e303591eafcbfd/examples/Android/app/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/examples/Android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alibaba/gaia-motion-curve/84f3567dd2725efb9e4dd459c3e303591eafcbfd/examples/Android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/examples/Android/app/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alibaba/gaia-motion-curve/84f3567dd2725efb9e4dd459c3e303591eafcbfd/examples/Android/app/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/examples/Android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alibaba/gaia-motion-curve/84f3567dd2725efb9e4dd459c3e303591eafcbfd/examples/Android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/examples/Android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alibaba/gaia-motion-curve/84f3567dd2725efb9e4dd459c3e303591eafcbfd/examples/Android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/examples/Android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alibaba/gaia-motion-curve/84f3567dd2725efb9e4dd459c3e303591eafcbfd/examples/Android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/examples/Android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alibaba/gaia-motion-curve/84f3567dd2725efb9e4dd459c3e303591eafcbfd/examples/Android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/examples/Android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alibaba/gaia-motion-curve/84f3567dd2725efb9e4dd459c3e303591eafcbfd/examples/Android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/examples/Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alibaba/gaia-motion-curve/84f3567dd2725efb9e4dd459c3e303591eafcbfd/examples/Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/examples/Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alibaba/gaia-motion-curve/84f3567dd2725efb9e4dd459c3e303591eafcbfd/examples/Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/examples/Android/app/src/main/res/values-night/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/examples/Android/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFBB86FC
4 | #FF6200EE
5 | #FF3700B3
6 | #FF03DAC5
7 | #FF018786
8 | #FF000000
9 | #FFFFFFFF
10 | #0000FF
11 | #FF0000
12 |
--------------------------------------------------------------------------------
/examples/Android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Demo
3 |
--------------------------------------------------------------------------------
/examples/Android/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/examples/Android/app/src/test/java/com/gaia/demo/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.gaia.demo;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/examples/Android/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | buildscript {
3 | repositories {
4 | google()
5 | mavenCentral()
6 | }
7 | dependencies {
8 | classpath "com.android.tools.build:gradle:7.0.4"
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | task clean(type: Delete) {
16 | delete rootProject.buildDir
17 | }
--------------------------------------------------------------------------------
/examples/Android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app"s APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
--------------------------------------------------------------------------------
/examples/Android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alibaba/gaia-motion-curve/84f3567dd2725efb9e4dd459c3e303591eafcbfd/examples/Android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/examples/Android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Jan 06 16:17:00 CST 2022
2 | distributionBase=GRADLE_USER_HOME
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
4 | distributionPath=wrapper/dists
5 | zipStorePath=wrapper/dists
6 | zipStoreBase=GRADLE_USER_HOME
7 |
--------------------------------------------------------------------------------
/examples/Android/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | #
4 | # Copyright 2015 the original author or authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | ##
21 | ## Gradle start up script for UN*X
22 | ##
23 | ##############################################################################
24 |
25 | # Attempt to set APP_HOME
26 | # Resolve links: $0 may be a link
27 | PRG="$0"
28 | # Need this for relative symlinks.
29 | while [ -h "$PRG" ] ; do
30 | ls=`ls -ld "$PRG"`
31 | link=`expr "$ls" : '.*-> \(.*\)$'`
32 | if expr "$link" : '/.*' > /dev/null; then
33 | PRG="$link"
34 | else
35 | PRG=`dirname "$PRG"`"/$link"
36 | fi
37 | done
38 | SAVED="`pwd`"
39 | cd "`dirname \"$PRG\"`/" >/dev/null
40 | APP_HOME="`pwd -P`"
41 | cd "$SAVED" >/dev/null
42 |
43 | APP_NAME="Gradle"
44 | APP_BASE_NAME=`basename "$0"`
45 |
46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
48 |
49 | # Use the maximum available, or set MAX_FD != -1 to use that value.
50 | MAX_FD="maximum"
51 |
52 | warn () {
53 | echo "$*"
54 | }
55 |
56 | die () {
57 | echo
58 | echo "$*"
59 | echo
60 | exit 1
61 | }
62 |
63 | # OS specific support (must be 'true' or 'false').
64 | cygwin=false
65 | msys=false
66 | darwin=false
67 | nonstop=false
68 | case "`uname`" in
69 | CYGWIN* )
70 | cygwin=true
71 | ;;
72 | Darwin* )
73 | darwin=true
74 | ;;
75 | MINGW* )
76 | msys=true
77 | ;;
78 | NONSTOP* )
79 | nonstop=true
80 | ;;
81 | esac
82 |
83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84 |
85 |
86 | # Determine the Java command to use to start the JVM.
87 | if [ -n "$JAVA_HOME" ] ; then
88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
89 | # IBM's JDK on AIX uses strange locations for the executables
90 | JAVACMD="$JAVA_HOME/jre/sh/java"
91 | else
92 | JAVACMD="$JAVA_HOME/bin/java"
93 | fi
94 | if [ ! -x "$JAVACMD" ] ; then
95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
96 |
97 | Please set the JAVA_HOME variable in your environment to match the
98 | location of your Java installation."
99 | fi
100 | else
101 | JAVACMD="java"
102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
103 |
104 | Please set the JAVA_HOME variable in your environment to match the
105 | location of your Java installation."
106 | fi
107 |
108 | # Increase the maximum file descriptors if we can.
109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
110 | MAX_FD_LIMIT=`ulimit -H -n`
111 | if [ $? -eq 0 ] ; then
112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
113 | MAX_FD="$MAX_FD_LIMIT"
114 | fi
115 | ulimit -n $MAX_FD
116 | if [ $? -ne 0 ] ; then
117 | warn "Could not set maximum file descriptor limit: $MAX_FD"
118 | fi
119 | else
120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
121 | fi
122 | fi
123 |
124 | # For Darwin, add options to specify how the application appears in the dock
125 | if $darwin; then
126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
127 | fi
128 |
129 | # For Cygwin or MSYS, switch paths to Windows format before running java
130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
133 |
134 | JAVACMD=`cygpath --unix "$JAVACMD"`
135 |
136 | # We build the pattern for arguments to be converted via cygpath
137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
138 | SEP=""
139 | for dir in $ROOTDIRSRAW ; do
140 | ROOTDIRS="$ROOTDIRS$SEP$dir"
141 | SEP="|"
142 | done
143 | OURCYGPATTERN="(^($ROOTDIRS))"
144 | # Add a user-defined pattern to the cygpath arguments
145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
147 | fi
148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
149 | i=0
150 | for arg in "$@" ; do
151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
153 |
154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
156 | else
157 | eval `echo args$i`="\"$arg\""
158 | fi
159 | i=`expr $i + 1`
160 | done
161 | case $i in
162 | 0) set -- ;;
163 | 1) set -- "$args0" ;;
164 | 2) set -- "$args0" "$args1" ;;
165 | 3) set -- "$args0" "$args1" "$args2" ;;
166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
172 | esac
173 | fi
174 |
175 | # Escape application args
176 | save () {
177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
178 | echo " "
179 | }
180 | APP_ARGS=`save "$@"`
181 |
182 | # Collect all arguments for the java command, following the shell quoting and substitution rules
183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
184 |
185 | exec "$JAVACMD" "$@"
186 |
--------------------------------------------------------------------------------
/examples/Android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/examples/Android/settings.gradle:
--------------------------------------------------------------------------------
1 | dependencyResolutionManagement {
2 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
3 | repositories {
4 | google()
5 | mavenCentral()
6 | jcenter() // Warning: this repository is going to shut down soon
7 | }
8 | }
9 | rootProject.name = "Demo"
10 | include ':app'
11 |
--------------------------------------------------------------------------------
/examples/iOS/GaiaMotionCurveDemo/AnimationViewController.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Alibaba Group Holding Ltd.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #import
16 | #import
17 |
18 | NS_ASSUME_NONNULL_BEGIN
19 |
20 | @interface AnimationViewController : UIViewController
21 |
22 | @property(nonatomic, assign) GMCCurveType curveType;
23 |
24 | @end
25 |
26 | NS_ASSUME_NONNULL_END
27 |
--------------------------------------------------------------------------------
/examples/iOS/GaiaMotionCurveDemo/AppDelegate.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Alibaba Group Holding Ltd.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #import
16 |
17 | @interface AppDelegate : UIResponder
18 |
19 | @property(strong, nonatomic) UIWindow *window;
20 | @property(strong, nonatomic) UINavigationController *navController;
21 |
22 | @end
23 |
24 |
--------------------------------------------------------------------------------
/examples/iOS/GaiaMotionCurveDemo/AppDelegate.m:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Alibaba Group Holding Ltd.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #import "AppDelegate.h"
16 | #import "ViewController.h"
17 |
18 | @interface AppDelegate ()
19 |
20 | @end
21 |
22 | @implementation AppDelegate
23 |
24 |
25 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
26 | // Override point for customization after application launch.
27 |
28 |
29 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
30 |
31 | self.window.backgroundColor = [UIColor whiteColor];
32 |
33 |
34 | ViewController *home = [[ViewController alloc] init];
35 | _navController = [[UINavigationController alloc] initWithRootViewController:home];
36 |
37 | [self.window setRootViewController:_navController];
38 |
39 | [self.window makeKeyAndVisible];
40 |
41 | return YES;
42 | }
43 |
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/examples/iOS/GaiaMotionCurveDemo/Assets.xcassets/AppIcon.appiconset/111.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alibaba/gaia-motion-curve/84f3567dd2725efb9e4dd459c3e303591eafcbfd/examples/iOS/GaiaMotionCurveDemo/Assets.xcassets/AppIcon.appiconset/111.png
--------------------------------------------------------------------------------
/examples/iOS/GaiaMotionCurveDemo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images": [
3 | {
4 | "idiom": "iphone",
5 | "scale": "2x",
6 | "size": "20x20"
7 | },
8 | {
9 | "idiom": "iphone",
10 | "scale": "3x",
11 | "size": "20x20"
12 | },
13 | {
14 | "idiom": "iphone",
15 | "scale": "2x",
16 | "size": "29x29"
17 | },
18 | {
19 | "idiom": "iphone",
20 | "scale": "3x",
21 | "size": "29x29"
22 | },
23 | {
24 | "idiom": "iphone",
25 | "scale": "2x",
26 | "size": "40x40"
27 | },
28 | {
29 | "idiom": "iphone",
30 | "scale": "3x",
31 | "size": "40x40"
32 | },
33 | {
34 | "filename": "Ico1n.png",
35 | "idiom": "iphone",
36 | "scale": "2x",
37 | "size": "60x60"
38 | },
39 | {
40 | "filename": "111.png",
41 | "idiom": "iphone",
42 | "scale": "3x",
43 | "size": "60x60"
44 | },
45 | {
46 | "idiom": "ipad",
47 | "scale": "1x",
48 | "size": "20x20"
49 | },
50 | {
51 | "idiom": "ipad",
52 | "scale": "2x",
53 | "size": "20x20"
54 | },
55 | {
56 | "idiom": "ipad",
57 | "scale": "1x",
58 | "size": "29x29"
59 | },
60 | {
61 | "idiom": "ipad",
62 | "scale": "2x",
63 | "size": "29x29"
64 | },
65 | {
66 | "idiom": "ipad",
67 | "scale": "1x",
68 | "size": "40x40"
69 | },
70 | {
71 | "idiom": "ipad",
72 | "scale": "2x",
73 | "size": "40x40"
74 | },
75 | {
76 | "idiom": "ipad",
77 | "scale": "1x",
78 | "size": "76x76"
79 | },
80 | {
81 | "idiom": "ipad",
82 | "scale": "2x",
83 | "size": "76x76"
84 | },
85 | {
86 | "idiom": "ipad",
87 | "scale": "2x",
88 | "size": "83.5x83.5"
89 | },
90 | {
91 | "idiom": "ios-marketing",
92 | "scale": "1x",
93 | "size": "1024x1024"
94 | }
95 | ],
96 | "info": {
97 | "author": "xcode",
98 | "version": 1
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/examples/iOS/GaiaMotionCurveDemo/Assets.xcassets/AppIcon.appiconset/Ico1n.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alibaba/gaia-motion-curve/84f3567dd2725efb9e4dd459c3e303591eafcbfd/examples/iOS/GaiaMotionCurveDemo/Assets.xcassets/AppIcon.appiconset/Ico1n.png
--------------------------------------------------------------------------------
/examples/iOS/GaiaMotionCurveDemo/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info": {
3 | "author": "xcode",
4 | "version": 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/examples/iOS/GaiaMotionCurveDemo/Assets.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images": [
3 | {
4 | "extent": "full-screen",
5 | "idiom": "iphone",
6 | "minimum-system-version": "12.0",
7 | "orientation": "portrait",
8 | "scale": "3x",
9 | "subtype": "2688h"
10 | },
11 | {
12 | "extent": "full-screen",
13 | "idiom": "iphone",
14 | "minimum-system-version": "12.0",
15 | "orientation": "landscape",
16 | "scale": "3x",
17 | "subtype": "2688h"
18 | },
19 | {
20 | "extent": "full-screen",
21 | "idiom": "iphone",
22 | "minimum-system-version": "12.0",
23 | "orientation": "portrait",
24 | "scale": "2x",
25 | "subtype": "1792h"
26 | },
27 | {
28 | "extent": "full-screen",
29 | "idiom": "iphone",
30 | "minimum-system-version": "12.0",
31 | "orientation": "landscape",
32 | "scale": "2x",
33 | "subtype": "1792h"
34 | },
35 | {
36 | "extent": "full-screen",
37 | "idiom": "iphone",
38 | "minimum-system-version": "11.0",
39 | "orientation": "portrait",
40 | "scale": "3x",
41 | "subtype": "2436h"
42 | },
43 | {
44 | "extent": "full-screen",
45 | "idiom": "iphone",
46 | "minimum-system-version": "11.0",
47 | "orientation": "landscape",
48 | "scale": "3x",
49 | "subtype": "2436h"
50 | },
51 | {
52 | "extent": "full-screen",
53 | "idiom": "iphone",
54 | "minimum-system-version": "8.0",
55 | "orientation": "portrait",
56 | "scale": "3x",
57 | "subtype": "736h"
58 | },
59 | {
60 | "extent": "full-screen",
61 | "idiom": "iphone",
62 | "minimum-system-version": "8.0",
63 | "orientation": "landscape",
64 | "scale": "3x",
65 | "subtype": "736h"
66 | },
67 | {
68 | "extent": "full-screen",
69 | "filename": "画板@2x.png",
70 | "idiom": "iphone",
71 | "minimum-system-version": "8.0",
72 | "orientation": "portrait",
73 | "scale": "2x",
74 | "subtype": "667h"
75 | },
76 | {
77 | "extent": "full-screen",
78 | "idiom": "iphone",
79 | "minimum-system-version": "7.0",
80 | "orientation": "portrait",
81 | "scale": "2x"
82 | },
83 | {
84 | "extent": "full-screen",
85 | "idiom": "iphone",
86 | "minimum-system-version": "7.0",
87 | "orientation": "portrait",
88 | "scale": "2x",
89 | "subtype": "retina4"
90 | },
91 | {
92 | "extent": "full-screen",
93 | "idiom": "iphone",
94 | "orientation": "portrait",
95 | "scale": "1x"
96 | },
97 | {
98 | "extent": "full-screen",
99 | "idiom": "iphone",
100 | "orientation": "portrait",
101 | "scale": "2x"
102 | },
103 | {
104 | "extent": "full-screen",
105 | "idiom": "iphone",
106 | "orientation": "portrait",
107 | "scale": "2x",
108 | "subtype": "retina4"
109 | }
110 | ],
111 | "info": {
112 | "author": "xcode",
113 | "version": 1
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/examples/iOS/GaiaMotionCurveDemo/Assets.xcassets/LaunchImage.launchimage/画板@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alibaba/gaia-motion-curve/84f3567dd2725efb9e4dd459c3e303591eafcbfd/examples/iOS/GaiaMotionCurveDemo/Assets.xcassets/LaunchImage.launchimage/画板@2x.png
--------------------------------------------------------------------------------
/examples/iOS/GaiaMotionCurveDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchImage
25 | UIRequiredDeviceCapabilities
26 |
27 | armv7
28 |
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/examples/iOS/GaiaMotionCurveDemo/ViewController.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Alibaba Group Holding Ltd.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #import
16 |
17 | @interface ViewController : UIViewController
18 |
19 |
20 | @end
21 |
22 |
--------------------------------------------------------------------------------
/examples/iOS/GaiaMotionCurveDemo/ViewController.m:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Alibaba Group Holding Ltd.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #import "ViewController.h"
16 | #import "AnimationViewController.h"
17 |
18 | @interface ViewController ()
19 |
20 | @property(nonatomic, strong) UITableView *tableView;
21 | @property(nonatomic, strong) NSArray *dataArray;
22 | @property(nonatomic, strong) NSArray *curveTypeArray;
23 |
24 | @end
25 |
26 | @implementation ViewController
27 |
28 | - (void)viewDidLoad {
29 | [super viewDidLoad];
30 | // Do any additional setup after loading the view.
31 |
32 | _tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
33 | _tableView.delegate = self;
34 | _tableView.dataSource = self;
35 |
36 | self.title = @"动效曲线";
37 |
38 |
39 | _dataArray = @[@"线性曲线(Linear)", @"加速曲线(Accelerate)", @"减速曲线(Decelerate)", @"标准曲线(Standard)", @"预期曲线(Anticipate)", @"过度曲线(Overshoot)", @"弹性曲线(Spring)", @"弹跳曲线(Bounce)", @"余弦曲线(Cosine)"];
40 | _curveTypeArray = @[@(GMCCurveTypeLinear), @(GMCCurveTypeAccelerate), @(GMCCurveTypeDecelerate), @(GMCCurveTypeStandard), @(GMCCurveTypeAnticipate), @(GMCCurveTypeOvershoot), @(GMCCurveTypeSpring), @(GMCCurveTypeBounce), @(GMCCurveTypeCosine)];
41 |
42 | [self.view addSubview:_tableView];
43 | }
44 |
45 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
46 | return _dataArray.count;
47 | }
48 |
49 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
50 | return 1;
51 | }
52 |
53 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
54 | static NSString *cellIdentifier = @"UITableViewCell";
55 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
56 | if (cell == nil) {
57 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier];
58 | }
59 | cell.textLabel.text = _dataArray[indexPath.section];
60 | cell.accessoryType = UITableViewRowAnimationRight;
61 | return cell;
62 | }
63 |
64 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
65 | [tableView deselectRowAtIndexPath:indexPath animated:NO];
66 | AnimationViewController *controller = [[AnimationViewController alloc] initWithNibName:nil bundle:nil];
67 | controller.curveType = [_curveTypeArray[indexPath.section] integerValue];
68 | controller.title = _dataArray[indexPath.section];
69 | [self.navigationController pushViewController:controller animated:YES];
70 | }
71 |
72 | @end
73 |
--------------------------------------------------------------------------------
/examples/iOS/GaiaMotionCurveDemo/main.m:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Alibaba Group Holding Ltd.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #import
16 | #import "AppDelegate.h"
17 |
18 | int main(int argc, char *argv[]) {
19 | NSString *appDelegateClassName;
20 | @autoreleasepool {
21 | // Setup code that might create autoreleased objects goes here.
22 | appDelegateClassName = NSStringFromClass([AppDelegate class]);
23 | }
24 | return UIApplicationMain(argc, argv, nil, appDelegateClassName);
25 | }
26 |
--------------------------------------------------------------------------------
/examples/iOS/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment the next line to define a global platform for your project
2 | # platform :ios, '9.0'
3 | source 'https://github.com/CocoaPods/Specs.git'
4 |
5 | target 'GaiaMotionCurveDemo' do
6 | # Comment the next line if you don't want to use dynamic frameworks
7 | use_frameworks!
8 |
9 | pod "GaiaMotionCurve", "0.1.0"
10 |
11 | end
12 |
--------------------------------------------------------------------------------
/examples/iOS/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - GaiaMotionCurve (0.1.0)
3 |
4 | DEPENDENCIES:
5 | - GaiaMotionCurve (= 0.1.0)
6 |
7 | SPEC REPOS:
8 | https://github.com/CocoaPods/Specs.git:
9 | - GaiaMotionCurve
10 |
11 | SPEC CHECKSUMS:
12 | GaiaMotionCurve: ece6f75d77f6aa8df28804416da467db64d224be
13 |
14 | PODFILE CHECKSUM: f1f14cba75d0390a6e6710446f6090cd2ea1de10
15 |
16 | COCOAPODS: 1.11.2
17 |
--------------------------------------------------------------------------------
/iOS/GaiaMotionCurve.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 |
3 | s.name = "GaiaMotionCurve"
4 | s.version = "0.1.1"
5 | s.summary = "a library to solve the problems of high cost of developing dynamic effects and inconsistent effects and design expectations"
6 | s.license = { :type => 'Apache License, Version 2.0' }
7 | s.homepage = "https://github.com/alibaba/gaia-motion-curve"
8 |
9 | s.author = { "ronghui.zrh" => "ronghui.zrh@alibaba-inc.com" }
10 | s.platform = :ios, "9.0"
11 | s.source = { :git => "https://github.com/alibaba/gaia-motion-curve.git", :tag => s.version }
12 |
13 |
14 | s.source_files = 'iOS/GaiaMotionCurve/**/*.{h,m,mm,c}'
15 | s.xcconfig = { "ENABLE_BITCODE" => "NO" }
16 | s.requires_arc = true
17 | end
18 |
--------------------------------------------------------------------------------
/iOS/GaiaMotionCurve/CALayer+GaiaMotionCurve.h:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2022, Alibaba Group Holding Limited;
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #import
16 | #import "GMCModel.h"
17 | #import "NSValue+GMCCGFloat.h"
18 | #import "NSValue+GMCUIColor.h"
19 |
20 | NS_ASSUME_NONNULL_BEGIN
21 |
22 | @interface CALayer (GaiaMotionCurve)
23 |
24 | /**
25 | when finished,will auto set toValue to layer,do not need set in completion block again
26 | @param models animation models array
27 | @param completion finished block
28 | @return animation unique id
29 | */
30 | - (NSString *)gmc_animateWithGMCModels:(NSArray *)models
31 | completion:(GMCCompletionBlock)completion;
32 |
33 |
34 | //serial animation
35 | - (NSString *)gmc_serialAnimationWithGMCModels:(NSArray *)models
36 | completion:(GMCCompletionBlock)completion;
37 |
38 | /**
39 | cancel animation with animationID
40 | @param animationID animation unique id
41 | */
42 | - (void)gmc_cancelAnimationWithID:(NSString *)animationID;
43 |
44 | // cancel all animations
45 | - (void)gmc_cancelAllAnimations;
46 |
47 |
48 | @property(nonatomic, strong) NSMutableDictionary *gmc_animationKeys;
49 |
50 |
51 | @end
52 |
53 | NS_ASSUME_NONNULL_END
54 |
--------------------------------------------------------------------------------
/iOS/GaiaMotionCurve/GMCDefines.h:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2022, Alibaba Group Holding Limited;
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #ifndef GMCDefines_h
16 | #define GMCDefines_h
17 |
18 | #import
19 |
20 | typedef NS_ENUM(NSInteger, GMCCurveType) {
21 | GMCCurveTypeLinear,
22 | GMCCurveTypeCosine,
23 | GMCCurveTypeAccelerate,
24 | GMCCurveTypeDecelerate,
25 | GMCCurveTypeStandard,
26 | GMCCurveTypeCubicBezier = GMCCurveTypeStandard,
27 | GMCCurveTypeAnticipate,
28 | GMCCurveTypeOvershoot,
29 | GMCCurveTypeBounce,
30 | GMCCurveTypeSpring,
31 | };
32 |
33 | typedef void (^GMCCompletionBlock)(BOOL finished);
34 |
35 | #define GMCWeakSelf(type) __weak typeof(type) weak##type = type;
36 | #define GMCStrongSelf(type) __strong typeof(type) type = weak##type;
37 |
38 | #endif /* GMCDefines_h */
39 |
--------------------------------------------------------------------------------
/iOS/GaiaMotionCurve/GMCFunctions.h:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2022, Alibaba Group Holding Limited;
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 |
16 | #import
17 | #import
18 |
19 |
20 | #ifndef GMCFunctions_h
21 | #define GMCFunctions_h
22 |
23 | CGFloat gmc_linear_curve(CGFloat p);
24 |
25 | CGFloat gmc_cosine_curve(CGFloat p, CGFloat d, CGFloat c);
26 |
27 | CGFloat gmc_decelerate_curve(CGFloat p, CGFloat x1, CGFloat y1, CGFloat x2,
28 | CGFloat y2);
29 |
30 | CGFloat gmc_accelerate_curve(CGFloat p, CGFloat x1, CGFloat y1, CGFloat x2,
31 | CGFloat y2);
32 |
33 | CGFloat gmc_standard_curve(CGFloat p, CGFloat x1, CGFloat y1, CGFloat x2,
34 | CGFloat y2);
35 |
36 | CGFloat gmc_anticipate_curve(CGFloat p, CGFloat d, CGFloat x1, CGFloat y1,
37 | CGFloat x2, CGFloat y2, CGFloat x3, CGFloat y3,
38 | CGFloat x4, CGFloat y4);
39 |
40 | CGFloat gmc_overshoot_curve(CGFloat p, CGFloat d, CGFloat x1, CGFloat y1,
41 | CGFloat x2, CGFloat y2, CGFloat x3, CGFloat y3,
42 | CGFloat x4, CGFloat y4);
43 |
44 | CGFloat gmc_bounce_curve(CGFloat p, CGFloat v, CGFloat d);
45 |
46 | CGFloat gmc_spring_motion_curve(CGFloat p, CGFloat m, CGFloat s, CGFloat d,
47 | CGFloat iv);
48 |
49 | CGFloat gmc_spring_rk4_motion_curve(CGFloat p, CGFloat *lastValue,
50 | CGFloat t, CGFloat f,
51 | CGFloat *v);
52 |
53 | #endif /* GMCFunctions_h */
54 |
--------------------------------------------------------------------------------
/iOS/GaiaMotionCurve/GMCFunctions.m:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2022, Alibaba Group Holding Limited;
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #import "GMCFunctions.h"
16 |
17 | CGFloat gmc_linear_curve(CGFloat p) {
18 | return p;
19 | }
20 |
21 | CGFloat gmc_cosine_curve(CGFloat p, CGFloat d, CGFloat c) {
22 | return d * 0.5 * (1 - cos(p * 2 * c * M_PI));
23 | }
24 |
25 | CGFloat gmc_decelerate_curve(CGFloat p, CGFloat x1, CGFloat y1, CGFloat x2,
26 | CGFloat y2) {
27 | return gmc_standard_curve(p, x1, y1, x2, y2);
28 | }
29 |
30 | CGFloat gmc_accelerate_curve(CGFloat p, CGFloat x1, CGFloat y1, CGFloat x2,
31 | CGFloat y2) {
32 | return gmc_standard_curve(p, x1, y1, x2, y2);
33 | }
34 |
35 | CGFloat gmc_standard_curve(CGFloat p, CGFloat x1, CGFloat y1, CGFloat x2,
36 | CGFloat y2) {
37 | CGFloat x = p;
38 | CGFloat z;
39 | CGFloat ax, ay, bx, by, cx, cy;
40 | for (int i = 1; i < 14; i++) {
41 | cx = 3.0f * x1;
42 | bx = 3.0f * (x2 - x1) - cx;
43 | ax = 1.0f - cx - bx;
44 | CGFloat b = x * (cx + x * (bx + x * ax));
45 | z = b - p;
46 | if (fabs(z) < 1e-3) {
47 | break;
48 | }
49 | CGFloat d = cx + x * (2.0f * bx + 3.0f * ax * x);
50 | x -= z / d;
51 | }
52 | cy = 3.0f * y1;
53 | by = 3.0f * (y2 - y1) - cy;
54 | ay = 1.0f - cy - by;
55 | return x * (cy + x * (by + x * ay));
56 | }
57 |
58 | CGFloat gmc_anticipate_curve(CGFloat p, CGFloat d, CGFloat x1, CGFloat y1, CGFloat x2,
59 | CGFloat y2, CGFloat x3, CGFloat y3, CGFloat x4,
60 | CGFloat y4) {
61 | // Anticipate (0.33,0,0.67,1 )time:0.3 (0.33,0,0.2,1 )
62 | if (p <= 0.3f) {
63 | return -d * gmc_standard_curve(p * 3.33, x1, y1, x2, y2);
64 | } else {
65 | return -d * gmc_standard_curve(0.3 * 3.33, x1, y1, x2, y2) + (1 + d) * gmc_standard_curve((p - 0.3) * 1.42, x3, y3, x4, y4);
66 | }
67 | }
68 |
69 | CGFloat gmc_bounce_curve(CGFloat p, CGFloat v, CGFloat d) {
70 | CGFloat tp = p;
71 | CGFloat b = 2.75 * v;
72 | if (tp < (1 / b)) {
73 | return pow(b, 2) * tp * tp;
74 | } else if (tp < (2 / b)) {
75 | return pow(b * d, 2) * (tp - 1.5 / b) * (tp - 1.5 / b) + (1 - pow(b * d, 2) * (1 / b - 1.5 / b) * (1 / b - 1.5 / b));
76 | } else if (tp < (2.5 / b)) {
77 | return pow(b * d, 2) * (tp - 2.25 / b) * (tp - 2.25 / b) + (1 - pow(b * d, 2) * (2 / b - 2.25 / b) * (2 / b - 2.25 / b));
78 | } else {
79 | return MIN(1.0f, pow(b * d, 2) * (tp - 2.625 / b) * (tp - 2.625 / b) + (1 - pow(b * d, 2) * (2.5 / b - 2.625 / b) * (2.5 / b - 2.625 / b)));
80 | }
81 | }
82 |
83 | CGFloat gmc_overshoot_curve(CGFloat p, CGFloat d, CGFloat x1, CGFloat y1, CGFloat x2,
84 | CGFloat y2, CGFloat x3, CGFloat y3, CGFloat x4,
85 | CGFloat y4) {
86 | //Overshoot (0.33,0,0.3,1 )time:0.5 (0.33,0,0.5,1 )
87 | if (p <= 0.5f) {
88 | return d * gmc_standard_curve(p * 2, x1, y1, x2, y2);
89 | } else {
90 | return d * gmc_standard_curve(0.5 * 2, x1, y1, x2, y2) - (d - 1) * gmc_standard_curve((p - 0.5) * 2, x3, y3, x4, y4);
91 | }
92 | }
93 |
94 | CGFloat gmc_spring_motion_curve(CGFloat p, CGFloat m, CGFloat s, CGFloat d,
95 | CGFloat iv) {
96 | CGFloat m_w0 = sqrt(s / m);
97 | CGFloat m_zeta = d / (2.0f * sqrt(s * m));
98 | CGFloat m_wd;
99 | CGFloat m_A;
100 | CGFloat m_B;
101 | if (m_zeta < 1.0f) {
102 | m_wd = m_w0 * sqrt(1.0f - m_zeta * m_zeta);
103 | m_A = 1.0f;
104 | m_B = (m_zeta * m_w0 + -iv) / m_wd;
105 | } else {
106 | m_wd = 0.0f;
107 | m_A = 1.0f;
108 | m_B = -iv + m_w0;
109 | }
110 | CGFloat t;
111 | if (m_zeta < 1.0f) {
112 | t = exp(-p * m_zeta * m_w0) * (m_A * cos(m_wd * p) + m_B * sin(m_wd * p));
113 | } else {
114 | t = (m_A + m_B * p) * exp(-p * m_w0);
115 | }
116 | return 1.0f - t;
117 | }
118 |
119 | typedef struct {
120 | CGFloat x;
121 | CGFloat v;
122 | CGFloat tension;
123 | CGFloat friction;
124 | } GMCSpringState;
125 |
126 | typedef struct {
127 | CGFloat dx;
128 | CGFloat dv;
129 | } GMCSpringDerivative;
130 |
131 | CGFloat normalizeSpringValue(CGFloat value) {
132 | if (isnan(value)) {
133 | return 0;
134 | } else if (isinf(value)) {
135 | return 0;
136 | } else {
137 | return value;
138 | }
139 | }
140 |
141 | CGFloat springAccelerationForState(GMCSpringState state) {
142 | return -state.tension * state.x - state.friction * state.v;
143 | }
144 |
145 | GMCSpringDerivative springEvaluateState(GMCSpringState initialState) {
146 | GMCSpringDerivative output;
147 | output.dx = initialState.v;
148 | output.dv = springAccelerationForState(initialState);
149 | return output;
150 | }
151 |
152 | GMCSpringDerivative springEvaluateStateWithDerivative(GMCSpringState initialState, CGFloat dt, GMCSpringDerivative derivative) {
153 |
154 | GMCSpringState state;
155 | state.x = initialState.x + derivative.dx * dt;
156 | state.v = initialState.v + derivative.dv * dt;
157 | state.tension = initialState.tension;
158 | state.friction = initialState.friction;
159 |
160 | GMCSpringDerivative output;
161 | output.dx = state.v;
162 | output.dv = springAccelerationForState(state);
163 |
164 | return output;
165 | }
166 |
167 | GMCSpringState springIntegrateState(GMCSpringState state, CGFloat speed) {
168 | GMCSpringDerivative a = springEvaluateState(state);
169 | GMCSpringDerivative b = springEvaluateStateWithDerivative(state, speed * 0.5, a);
170 | GMCSpringDerivative c = springEvaluateStateWithDerivative(state, speed * 0.5, b);
171 | GMCSpringDerivative d = springEvaluateStateWithDerivative(state, speed, c);
172 |
173 | CGFloat tx = (a.dx + 2.0 * (b.dx + c.dx) + d.dx);
174 | CGFloat ty = (a.dv + 2.0 * (b.dv + c.dv) + d.dv);
175 |
176 | CGFloat dxdt = 1.0 / 6.0 * tx;
177 | CGFloat dvdt = 1.0 / 6.0 * ty;
178 |
179 | GMCSpringState output = state;
180 |
181 | output.x = state.x + dxdt * speed;
182 | output.v = state.v + dvdt * speed;
183 |
184 | return output;
185 | }
186 |
187 | CGFloat gmc_spring_rk4_motion_curve(CGFloat p, CGFloat *lastValue, CGFloat t, CGFloat f, CGFloat *v) {
188 | CGFloat result;
189 | if (p == 0.0f) {
190 | result = 0.0f;
191 | } else {
192 | GMCSpringState before;
193 | before.x = *lastValue - 1.0f;
194 | before.v = *v;
195 | before.tension = t;
196 | before.friction = f;
197 |
198 | GMCSpringState after = springIntegrateState(before, 1 / 60.0f);
199 | *lastValue = 1 + after.x;
200 | *v = after.v;
201 |
202 | *lastValue = normalizeSpringValue(*lastValue);
203 | *v = normalizeSpringValue(*v);
204 |
205 | result = *lastValue;
206 | }
207 | return result;
208 | }
209 |
--------------------------------------------------------------------------------
/iOS/GaiaMotionCurve/GMCHelper.h:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2022, Alibaba Group Holding Limited;
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 |
16 | #import
17 | #import
18 |
19 | @class GMCModel;
20 |
21 | NS_ASSUME_NONNULL_BEGIN
22 |
23 | @interface GMCHelper : NSObject
24 |
25 |
26 | + (NSArray *)valuesByCurveModel:(GMCModel *)model;
27 |
28 | /*
29 | count > 1
30 | */
31 | + (NSArray *)valuesByCurveModel:(GMCModel *)model valueCount:(NSInteger)count;
32 |
33 |
34 | /*
35 | 0 < percent <= 1
36 | */
37 | + (NSValue *)valueByCurveModel:(GMCModel *)model progressPercent:(CGFloat)percent;
38 |
39 |
40 | @end
41 |
42 | NS_ASSUME_NONNULL_END
43 |
--------------------------------------------------------------------------------
/iOS/GaiaMotionCurve/GMCModel+Internal.h:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2022, Alibaba Group Holding Limited;
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 |
16 | #import "GMCModel.h"
17 |
18 | NS_ASSUME_NONNULL_BEGIN
19 |
20 | @interface GMCBaseArgsModel : NSObject
21 |
22 | @end
23 |
24 | @interface GMCStandardArgsModel : GMCBaseArgsModel
25 |
26 | @property(nonatomic, assign) CGFloat x1;
27 | @property(nonatomic, assign) CGFloat y1;
28 | @property(nonatomic, assign) CGFloat x2;
29 | @property(nonatomic, assign) CGFloat y2;
30 |
31 | @end
32 |
33 | @interface GMCAccelerateArgsModel : GMCStandardArgsModel
34 |
35 | @end
36 |
37 | @interface GMCDecelerateArgsModel : GMCStandardArgsModel
38 |
39 | @end
40 |
41 | @interface GMCAnticipateArgsModel : GMCBaseArgsModel
42 |
43 | @property(nonatomic, assign) CGFloat d;
44 | @property(nonatomic, assign) CGFloat x1;
45 | @property(nonatomic, assign) CGFloat y1;
46 | @property(nonatomic, assign) CGFloat x2;
47 | @property(nonatomic, assign) CGFloat y2;
48 | @property(nonatomic, assign) CGFloat x3;
49 | @property(nonatomic, assign) CGFloat y3;
50 | @property(nonatomic, assign) CGFloat x4;
51 | @property(nonatomic, assign) CGFloat y4;
52 |
53 | @end
54 |
55 | @interface GMCOvershootArgsModel : GMCAnticipateArgsModel
56 |
57 | @end
58 |
59 | @interface GMCBounceArgsModel : GMCBaseArgsModel
60 |
61 | @property(nonatomic, assign) CGFloat v;
62 | @property(nonatomic, assign) CGFloat d;
63 |
64 | @end
65 |
66 | @interface GMCDefaultSpringArgsModel : GMCBaseArgsModel
67 |
68 | @property(nonatomic, assign) CGFloat mass;
69 | @property(nonatomic, assign) CGFloat stiffness;
70 | @property(nonatomic, assign) CGFloat damping;
71 | @property(nonatomic, assign) CGFloat velocity;
72 |
73 | @end
74 |
75 | @interface GMCRK4SpringArgsModel : GMCBaseArgsModel
76 |
77 | @property(nonatomic, assign) CGFloat tension;
78 | @property(nonatomic, assign) CGFloat friction;
79 | @property(nonatomic, assign) CGFloat velocity;
80 |
81 | @end
82 |
83 | @interface GMCCosineArgsModel : GMCBaseArgsModel
84 |
85 | @property(nonatomic, assign) CGFloat d;
86 | @property(nonatomic, assign) CGFloat c;
87 |
88 | @end
89 |
90 |
91 | @interface GMCModel (Internal)
92 |
93 | @property(nonatomic, strong) GMCBaseArgsModel *argsModel;
94 |
95 | + (GMCModel *)modelWithKeyPath:(NSString *)keyPath
96 | duration:(CFTimeInterval)duration
97 | delay:(CFTimeInterval)delay
98 | curveType:(GMCCurveType)curveType
99 | argsModel:(nullable GMCBaseArgsModel *)argsModel
100 | fromValue:(NSValue *)fromValue
101 | toValue:(NSValue *)toValue;
102 |
103 | @end
104 |
105 | NS_ASSUME_NONNULL_END
106 |
--------------------------------------------------------------------------------
/iOS/GaiaMotionCurve/GMCModel+Internal.m:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2022, Alibaba Group Holding Limited;
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #import "GMCModel+Internal.h"
16 | #import
17 |
18 | @implementation GMCBaseArgsModel
19 | @end
20 |
21 | @implementation GMCStandardArgsModel
22 | @end
23 |
24 | @implementation GMCAccelerateArgsModel
25 | @end
26 |
27 | @implementation GMCDecelerateArgsModel
28 | @end
29 |
30 | @implementation GMCAnticipateArgsModel
31 | @end
32 |
33 | @implementation GMCOvershootArgsModel
34 | @end
35 |
36 | @implementation GMCBounceArgsModel
37 | @end
38 |
39 | @implementation GMCDefaultSpringArgsModel
40 | @end
41 |
42 | @implementation GMCRK4SpringArgsModel
43 | @end
44 |
45 | @implementation GMCCosineArgsModel
46 | @end
47 |
48 |
49 | @implementation GMCModel (Internal)
50 |
51 | static NSString *kGMCModelArgsModelKey = @"kGMCModelArgsModelKey";
52 |
53 | - (void)setArgsModel:(GMCBaseArgsModel *)argsModel {
54 | objc_setAssociatedObject(self, &kGMCModelArgsModelKey, argsModel,
55 | OBJC_ASSOCIATION_RETAIN);
56 | }
57 |
58 | - (GMCBaseArgsModel *)argsModel {
59 | return objc_getAssociatedObject(self, &kGMCModelArgsModelKey);
60 | }
61 |
62 | + (GMCModel *)modelWithKeyPath:(NSString *)keyPath
63 | duration:(CFTimeInterval)duration
64 | delay:(CFTimeInterval)delay
65 | curveType:(GMCCurveType)curveType
66 | argsModel:(nullable GMCBaseArgsModel *)argsModel
67 | fromValue:(NSValue *)fromValue
68 | toValue:(NSValue *)toValue {
69 | GMCModel *model = [GMCModel modelWithKeyPath:keyPath
70 | duration:duration
71 | delay:delay
72 | curveType:curveType
73 | fromValue:fromValue
74 | toValue:toValue];
75 | model.argsModel = argsModel;
76 | return model;
77 | }
78 |
79 | @end
80 |
--------------------------------------------------------------------------------
/iOS/GaiaMotionCurve/GMCModel.h:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2022, Alibaba Group Holding Limited;
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 |
16 | #import
17 | #import
18 | #import "GMCDefines.h"
19 | #import "NSValue+GMCCGFloat.h"
20 | #import "NSValue+GMCUIColor.h"
21 |
22 | NS_ASSUME_NONNULL_BEGIN
23 |
24 | @interface GMCModel : NSObject
25 |
26 | //default 0
27 | @property(nonatomic, assign) NSInteger repeatCount;
28 |
29 | //default NO
30 | @property(nonatomic, assign) BOOL autoReverse;
31 |
32 | //animation key path
33 | @property(nonatomic, strong) NSString *keyPath;
34 |
35 | //second
36 | @property(nonatomic, assign) CFTimeInterval duration;
37 |
38 | //second
39 | @property(nonatomic, assign) CFTimeInterval delay;
40 |
41 | //motion curve type
42 | @property(nonatomic, assign) GMCCurveType curveType;
43 |
44 | @property(nonatomic, strong) NSValue *fromValue;
45 |
46 | @property(nonatomic, strong) NSValue *toValue;
47 |
48 |
49 | + (GMCModel *)modelWithKeyPath:(NSString *)keyPath
50 | duration:(CFTimeInterval)duration
51 | delay:(CFTimeInterval)delay
52 | curveType:(GMCCurveType)curveType
53 | fromValue:(NSValue *)fromValue
54 | toValue:(NSValue *)toValue;
55 |
56 |
57 | + (GMCModel *)modelWithKeyPath:(NSString *)keyPath
58 | duration:(CFTimeInterval)duration
59 | delay:(CFTimeInterval)delay
60 | curveType:(GMCCurveType)curveType
61 | customArgs:(nullable NSDictionary *)customArgs
62 | fromValue:(NSValue *)fromValue
63 | toValue:(NSValue *)toValue;
64 |
65 |
66 | + (GMCModel *)modelWithKeyPath:(NSString *)keyPath
67 | duration:(CFTimeInterval)duration
68 | delay:(CFTimeInterval)delay
69 | repeatCount:(NSInteger)repeatCount
70 | autoReverse:(BOOL)autoReverse
71 | curveType:(GMCCurveType)curveType
72 | fromValue:(NSValue *)fromValue
73 | toValue:(NSValue *)toValue;
74 |
75 |
76 | + (GMCModel *)modelWithKeyPath:(NSString *)keyPath
77 | duration:(CFTimeInterval)duration
78 | delay:(CFTimeInterval)delay
79 | repeatCount:(NSInteger)repeatCount
80 | autoReverse:(BOOL)autoReverse
81 | curveType:(GMCCurveType)curveType
82 | customArgs:(nullable NSDictionary *)customArgs
83 | fromValue:(NSValue *)fromValue
84 | toValue:(NSValue *)toValue;
85 |
86 | @end
87 |
88 | NS_ASSUME_NONNULL_END
89 |
--------------------------------------------------------------------------------
/iOS/GaiaMotionCurve/GMCModel.m:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2022, Alibaba Group Holding Limited;
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 |
16 | #import "GMCModel.h"
17 | #import "GMCModel+Internal.h"
18 |
19 | @implementation GMCModel
20 |
21 | + (GMCModel *)modelWithKeyPath:(NSString *)keyPath
22 | duration:(CFTimeInterval)duration
23 | delay:(CFTimeInterval)delay
24 | curveType:(GMCCurveType)curveType
25 | fromValue:(NSValue *)fromValue
26 | toValue:(NSValue *)toValue {
27 | return [GMCModel modelWithKeyPath:keyPath
28 | duration:duration
29 | delay:delay
30 | curveType:curveType
31 | customArgs:nil
32 | fromValue:fromValue
33 | toValue:toValue];
34 | }
35 |
36 | + (GMCModel *)modelWithKeyPath:(NSString *)keyPath
37 | duration:(CFTimeInterval)duration
38 | delay:(CFTimeInterval)delay
39 | curveType:(GMCCurveType)curveType
40 | customArgs:(nullable NSDictionary *)customArgs
41 | fromValue:(NSValue *)fromValue
42 | toValue:(NSValue *)toValue {
43 | return [GMCModel modelWithKeyPath:keyPath
44 | duration:duration
45 | delay:delay
46 | repeatCount:0
47 | autoReverse:NO
48 | curveType:curveType
49 | customArgs:customArgs
50 | fromValue:fromValue
51 | toValue:toValue];
52 |
53 | }
54 |
55 |
56 | + (GMCModel *)modelWithKeyPath:(NSString *)keyPath
57 | duration:(CFTimeInterval)duration
58 | delay:(CFTimeInterval)delay
59 | repeatCount:(NSInteger)repeatCount
60 | autoReverse:(BOOL)autoReverse
61 | curveType:(GMCCurveType)curveType
62 | fromValue:(NSValue *)fromValue
63 | toValue:(NSValue *)toValue {
64 | return [GMCModel modelWithKeyPath:keyPath
65 | duration:duration
66 | delay:delay
67 | repeatCount:repeatCount
68 | autoReverse:autoReverse
69 | curveType:curveType
70 | customArgs:nil
71 | fromValue:fromValue
72 | toValue:toValue];
73 | }
74 |
75 |
76 | + (GMCModel *)modelWithKeyPath:(NSString *)keyPath
77 | duration:(CFTimeInterval)duration
78 | delay:(CFTimeInterval)delay
79 | repeatCount:(NSInteger)repeatCount
80 | autoReverse:(BOOL)autoReverse
81 | curveType:(GMCCurveType)curveType
82 | customArgs:(nullable NSDictionary *)customArgs
83 | fromValue:(NSValue *)fromValue
84 | toValue:(NSValue *)toValue {
85 | GMCModel *model = [[GMCModel alloc] init];
86 | model.keyPath = keyPath;
87 | model.duration = duration;
88 | model.delay = delay;
89 | model.repeatCount = repeatCount;
90 | model.autoReverse = autoReverse;
91 | model.curveType = curveType;
92 | model.fromValue = fromValue;
93 | model.toValue = toValue;
94 | if (curveType == GMCCurveTypeCosine) {
95 | GMCCosineArgsModel *argsModel = [[GMCCosineArgsModel alloc] init];
96 | argsModel.d = customArgs[@"d"] != nil ? [customArgs[@"d"] floatValue] : 1.0f;
97 | argsModel.c = customArgs[@"c"] != nil ? [customArgs[@"c"] floatValue] : 1.0f;
98 | model.argsModel = argsModel;
99 | } else if (curveType == GMCCurveTypeBounce) {
100 | GMCBounceArgsModel *argsModel = [[GMCBounceArgsModel alloc] init];
101 | argsModel.v = customArgs[@"v"] != nil ? [customArgs[@"v"] floatValue] : 1.0f;
102 | argsModel.d = customArgs[@"d"] != nil ? [customArgs[@"d"] floatValue] : 1.0f;
103 | model.argsModel = argsModel;
104 | } else if (curveType == GMCCurveTypeAccelerate) {
105 | GMCAccelerateArgsModel *argsModel = [[GMCAccelerateArgsModel alloc] init];
106 | argsModel.x1 = customArgs[@"x1"] != nil ? [customArgs[@"x1"] floatValue] : 0.4f;
107 | argsModel.y1 = customArgs[@"y1"] != nil ? [customArgs[@"y1"] floatValue] : 0.0f;
108 | argsModel.x2 = customArgs[@"x2"] != nil ? [customArgs[@"x2"] floatValue] : 1.0f;
109 | argsModel.y2 = customArgs[@"y2"] != nil ? [customArgs[@"y2"] floatValue] : 1.0f;
110 | model.argsModel = argsModel;
111 | } else if (curveType == GMCCurveTypeDecelerate) {
112 | GMCDecelerateArgsModel *argsModel = [[GMCDecelerateArgsModel alloc] init];
113 | argsModel.x1 = customArgs[@"x1"] != nil ? [customArgs[@"x1"] floatValue] : 0.0f;
114 | argsModel.y1 = customArgs[@"y1"] != nil ? [customArgs[@"y1"] floatValue] : 0.0f;
115 | argsModel.x2 = customArgs[@"x2"] != nil ? [customArgs[@"x2"] floatValue] : 0.1f;
116 | argsModel.y2 = customArgs[@"y2"] != nil ? [customArgs[@"y2"] floatValue] : 1.0f;
117 | model.argsModel = argsModel;
118 | } else if (curveType == GMCCurveTypeStandard) {
119 | GMCStandardArgsModel *argsModel = [[GMCStandardArgsModel alloc] init];
120 | argsModel.x1 = customArgs[@"x1"] != nil ? [customArgs[@"x1"] floatValue] : 0.4f;
121 | argsModel.y1 = customArgs[@"y1"] != nil ? [customArgs[@"y1"] floatValue] : 0.0f;
122 | argsModel.x2 = customArgs[@"x2"] != nil ? [customArgs[@"x2"] floatValue] : 0.1f;
123 | argsModel.y2 = customArgs[@"y2"] != nil ? [customArgs[@"y2"] floatValue] : 1.0f;
124 | model.argsModel = argsModel;
125 | } else if (curveType == GMCCurveTypeOvershoot) {
126 | GMCOvershootArgsModel *argsModel = [[GMCOvershootArgsModel alloc] init];
127 | argsModel.d = customArgs[@"d"] != nil ? [customArgs[@"d"] floatValue] : 1.2f;
128 | argsModel.x1 = customArgs[@"x1"] != nil ? [customArgs[@"x1"] floatValue] : 0.33f;
129 | argsModel.y1 = customArgs[@"y1"] != nil ? [customArgs[@"y1"] floatValue] : 0.0f;
130 | argsModel.x2 = customArgs[@"x2"] != nil ? [customArgs[@"x2"] floatValue] : 0.3f;
131 | argsModel.y2 = customArgs[@"y2"] != nil ? [customArgs[@"y2"] floatValue] : 1.0f;
132 | argsModel.x3 = customArgs[@"x3"] != nil ? [customArgs[@"x3"] floatValue] : 0.33f;
133 | argsModel.y3 = customArgs[@"y3"] != nil ? [customArgs[@"y3"] floatValue] : 0.0f;
134 | argsModel.x4 = customArgs[@"x4"] != nil ? [customArgs[@"x4"] floatValue] : 0.5f;
135 | argsModel.y4 = customArgs[@"y4"] != nil ? [customArgs[@"y4"] floatValue] : 1.0f;
136 | model.argsModel = argsModel;
137 | } else if (curveType == GMCCurveTypeAnticipate) {
138 | GMCAnticipateArgsModel *argsModel = [[GMCAnticipateArgsModel alloc] init];
139 | argsModel.d = customArgs[@"d"] != nil ? [customArgs[@"d"] floatValue] : 0.2f;
140 | argsModel.x1 = customArgs[@"x1"] != nil ? [customArgs[@"x1"] floatValue] : 0.33f;
141 | argsModel.y1 = customArgs[@"y1"] != nil ? [customArgs[@"y1"] floatValue] : 0.0f;
142 | argsModel.x2 = customArgs[@"x2"] != nil ? [customArgs[@"x2"] floatValue] : 0.67f;
143 | argsModel.y2 = customArgs[@"y2"] != nil ? [customArgs[@"y2"] floatValue] : 1.0f;
144 | argsModel.x3 = customArgs[@"x3"] != nil ? [customArgs[@"x3"] floatValue] : 0.33f;
145 | argsModel.y3 = customArgs[@"y3"] != nil ? [customArgs[@"y3"] floatValue] : 0.0f;
146 | argsModel.x4 = customArgs[@"x4"] != nil ? [customArgs[@"x4"] floatValue] : 0.2f;
147 | argsModel.y4 = customArgs[@"y4"] != nil ? [customArgs[@"y4"] floatValue] : 1.0f;
148 | model.argsModel = argsModel;
149 | } else if (curveType == GMCCurveTypeSpring) {
150 | if (customArgs[@"m"] != nil || customArgs[@"s"] != nil || customArgs[@"d"] != nil || customArgs[@"iv"] != nil) {
151 | GMCDefaultSpringArgsModel *argsModel = [[GMCDefaultSpringArgsModel alloc] init];
152 | argsModel.mass = customArgs[@"m"] != nil ? [customArgs[@"m"] floatValue] : 0.7f;
153 | argsModel.stiffness = customArgs[@"s"] != nil ? [customArgs[@"s"] floatValue] : 380.0f;
154 | argsModel.damping = customArgs[@"d"] != nil ? [customArgs[@"d"] floatValue] : 10.0f;
155 | argsModel.velocity = customArgs[@"iv"] != nil ? [customArgs[@"iv"] floatValue] : -2.0f;
156 | model.argsModel = argsModel;
157 | } else {
158 | GMCRK4SpringArgsModel *argsModel = [[GMCRK4SpringArgsModel alloc] init];
159 | argsModel.tension = customArgs[@"t"] != nil ? [customArgs[@"t"] floatValue] : 533.0f;
160 | argsModel.friction = customArgs[@"f"] != nil ? [customArgs[@"f"] floatValue] : 14.0f;
161 | argsModel.velocity = customArgs[@"v"] != nil ? [customArgs[@"v"] floatValue] : -2.0f;
162 | model.argsModel = argsModel;
163 | }
164 | }
165 | return model;
166 | }
167 |
168 |
169 | @end
170 |
--------------------------------------------------------------------------------
/iOS/GaiaMotionCurve/GaiaMotionCurve.h:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2022, Alibaba Group Holding Limited;
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #import
16 |
17 | //! Project version number for GaiaMotionCurve.
18 | FOUNDATION_EXPORT double GaiaMotionCurveVersionNumber;
19 |
20 | //! Project version string for GaiaMotionCurve.
21 | FOUNDATION_EXPORT const unsigned char GaiaMotionCurveVersionString[];
22 |
23 | // In this header, you should import all the public headers of your framework using statements like #import
24 |
25 |
26 | #import
27 | #import
28 | #import
29 | #import
30 | #import
31 | #import
32 | #import
--------------------------------------------------------------------------------
/iOS/GaiaMotionCurve/NSValue+GMCCGFloat.h:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2022, Alibaba Group Holding Limited;
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #import
16 | #import
17 |
18 | NS_ASSUME_NONNULL_BEGIN
19 |
20 | @interface NSValue (GMCCGFloat)
21 |
22 | - (CGFloat)gmc_CGFloatValue;
23 |
24 | + (NSValue *)gmc_valueWithCGFloat:(CGFloat)floatValue;
25 |
26 |
27 | @end
28 |
29 | NS_ASSUME_NONNULL_END
30 |
--------------------------------------------------------------------------------
/iOS/GaiaMotionCurve/NSValue+GMCCGFloat.m:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2022, Alibaba Group Holding Limited;
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 |
16 | #import "NSValue+GMCCGFloat.h"
17 |
18 | @implementation NSValue (GMCCGFloat)
19 |
20 | - (CGFloat)gmc_CGFloatValue {
21 | CGFloat floatValue;
22 | [self getValue:&floatValue];
23 | return floatValue;
24 | }
25 |
26 | + (NSValue *)gmc_valueWithCGFloat:(CGFloat)floatValue {
27 | NSValue *returnValue = [NSValue valueWithBytes:&floatValue
28 | objCType:@encode(CGFloat)];
29 | return returnValue;
30 | }
31 |
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/iOS/GaiaMotionCurve/NSValue+GMCUIColor.h:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2022, Alibaba Group Holding Limited;
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 |
16 | #import
17 | #import
18 |
19 | @class UIColor;
20 |
21 | NS_ASSUME_NONNULL_BEGIN
22 |
23 | @interface NSValue (GMCUIColor)
24 |
25 |
26 | - (CGColorRef)gmc_CGColorValue;
27 |
28 | + (NSValue *)gmc_valueWithCGColor:(CGColorRef)color;
29 |
30 | @end
31 |
32 | NS_ASSUME_NONNULL_END
33 |
--------------------------------------------------------------------------------
/iOS/GaiaMotionCurve/NSValue+GMCUIColor.m:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2022, Alibaba Group Holding Limited;
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 |
16 | #import "NSValue+GMCUIColor.h"
17 |
18 | @implementation NSValue (GMCUIColor)
19 |
20 | + (NSValue *)gmc_valueWithCGColor:(CGColorRef)color {
21 | return [NSValue valueWithBytes:&color objCType:@encode(CGColorRef)];
22 | }
23 |
24 | - (CGColorRef)gmc_CGColorValue {
25 | CGColorRef color;
26 | [self getValue:&color];
27 | return color;
28 | }
29 |
30 | @end
31 |
--------------------------------------------------------------------------------
/iOS/GaiaMotionCurveTests/GaiaMotionCurveTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // GaiaMotionCurveTests.m
3 | // GaiaMotionCurveTests
4 | //
5 | // Created by 周荣慧 on 2022/1/4.
6 | //
7 |
8 | #import
9 |
10 | @interface GaiaMotionCurveTests : XCTestCase
11 |
12 | @end
13 |
14 | @implementation GaiaMotionCurveTests
15 |
16 | - (void)setUp {
17 | // Put setup code here. This method is called before the invocation of each test method in the class.
18 | }
19 |
20 | - (void)tearDown {
21 | // Put teardown code here. This method is called after the invocation of each test method in the class.
22 | }
23 |
24 | - (void)testExample {
25 | // This is an example of a functional test case.
26 | // Use XCTAssert and related functions to verify your tests produce the correct results.
27 | }
28 |
29 | - (void)testPerformanceExample {
30 | // This is an example of a performance test case.
31 | [self measureBlock:^{
32 | // Put the code you want to measure the time of here.
33 | }];
34 | }
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/iOS/Podfile:
--------------------------------------------------------------------------------
1 |
2 | target 'GaiaMotionCurve' do
3 | platform :ios, '9.0'
4 | # Uncomment the next line if you're using Swift or would like to use dynamic frameworks
5 | # use_frameworks!
6 |
7 | end
8 |
--------------------------------------------------------------------------------