From 68e8f4046763ed1b61dd63738b814f36e081cef3 Mon Sep 17 00:00:00 2001 From: Fernando Rojo Date: Mon, 26 Sep 2022 15:42:28 -0400 Subject: [PATCH 1/4] transitions in variants & dynamic animations --- examples/with-expo/src/Easing.tsx | 2 ++ examples/with-expo/src/Moti.NewTransition.tsx | 33 +++++++++++++++++++ packages/moti/src/core/types.ts | 16 ++++++--- packages/moti/src/core/use-motify.ts | 33 +++++++++++++++---- 4 files changed, 73 insertions(+), 11 deletions(-) create mode 100644 examples/with-expo/src/Easing.tsx create mode 100644 examples/with-expo/src/Moti.NewTransition.tsx diff --git a/examples/with-expo/src/Easing.tsx b/examples/with-expo/src/Easing.tsx new file mode 100644 index 0000000..953ae0d --- /dev/null +++ b/examples/with-expo/src/Easing.tsx @@ -0,0 +1,2 @@ +import { Easing } from 'react-native' +import * as Reanimated from 'react-native-reanimated' diff --git a/examples/with-expo/src/Moti.NewTransition.tsx b/examples/with-expo/src/Moti.NewTransition.tsx new file mode 100644 index 0000000..5cc87d6 --- /dev/null +++ b/examples/with-expo/src/Moti.NewTransition.tsx @@ -0,0 +1,33 @@ +import { useAnimationState, useDynamicAnimation } from 'moti' +import React from 'react' + +export function App() { + const state = useAnimationState({ + from: { + transition: { + type: 'timing', + }, + }, + }) + const state2 = useDynamicAnimation(() => ({ + scale: 0.5, + transition: { + type: 'timing', + }, + })) + + const toggleTransition = () => { + state.transitionTo('from') + } + + const animateTo = () => { + state2.animateTo({ + opacity: 1, + transition: { + type: 'timing', + }, + }) + } + + return <> +} diff --git a/packages/moti/src/core/types.ts b/packages/moti/src/core/types.ts index 93a4fb2..ee57ff8 100644 --- a/packages/moti/src/core/types.ts +++ b/packages/moti/src/core/types.ts @@ -326,14 +326,15 @@ export type Variants< // in component usage, it will extract these from the style prop ideally AnimateType = ImageStyle & TextStyle & ViewStyle, // edit the style props to remove transform array, flattening it - AnimateWithTransitions = StyleValueWithReplacedTransforms, + AnimateWithTransformsAndTransition = StyleValueWithReplacedTransforms & + WithTransition, // allow the style values to be arrays for sequences, where values are primitives or objects with configs - Animate = StyleValueWithSequenceArrays + Animate = StyleValueWithSequenceArrays > = { [key in keyof V]?: Animate } & { to?: Animate - from?: AnimateWithTransitions + from?: AnimateWithTransformsAndTransition } export type UseAnimationState = { @@ -409,6 +410,10 @@ export type UseAnimationStateConfig< to?: ToKey } +export type WithTransition = { + transition?: MotiTransition +} + /** * Used for `useDynamicAnimation` */ @@ -419,9 +424,10 @@ export type DynamicStyleProp< AnimateType = ImageStyle & ViewStyle & TextStyle, // edit the style props to remove transform array, flattening it // AnimateWithTransitions = Omit & Partial, - AnimateWithTransitions = StyleValueWithReplacedTransforms + AnimateWithTransforms = StyleValueWithReplacedTransforms // allow the style values to be arrays for sequences, where values are primitives or objects with configs -> = NonNullable> +> = NonNullable> & + WithTransition export type UseDynamicAnimationState = { /** diff --git a/packages/moti/src/core/use-motify.ts b/packages/moti/src/core/use-motify.ts index a117e11..01660c4 100644 --- a/packages/moti/src/core/use-motify.ts +++ b/packages/moti/src/core/use-motify.ts @@ -17,6 +17,7 @@ import type { WithSpringConfig, WithTimingConfig, } from 'react-native-reanimated' + import { PackageName } from './constants/package-name' import type { MotiProps, @@ -24,6 +25,7 @@ import type { SequenceItem, Transforms, TransitionConfig, + WithTransition, } from './types' const debug = (...args: any[]) => { @@ -199,7 +201,6 @@ function animationConfig( 'velocityFactor', ] for (const configKey of configKeys) { - // is this necessary ^ don't think so...? const styleSpecificConfig = transition?.[key]?.[configKey] const transitionConfigForKey = transition?.[configKey] @@ -224,7 +225,7 @@ const getSequenceArray = ( sequenceKey: string, sequenceArray: SequenceItem[], delayMs: number | undefined, - config: {}, + config: object, animation: (...props: any) => any, callback: (completed: boolean, value?: any) => void ) => { @@ -321,7 +322,7 @@ export function useMotify({ // initializing here fixes reanimated object.__defineProperty bug(?) transform: [] as TransformsStyle['transform'], } - const variantStyle: Animate = state?.__state?.value || {} + const variantStyle: Animate & WithTransition = state?.__state?.value || {} let animateStyle: Animate @@ -368,7 +369,7 @@ export function useMotify({ for (const key in exitStyle || {}) { const disabledExitStyles = { position: true, - zIndex: true + zIndex: true, } if (!disabledExitStyles[key]) { exitingStyleProps[key] = true @@ -382,6 +383,12 @@ export function useMotify({ } else { transition = transitionProp } + + // let the state prop drive transitions too + if (variantStyle.transition) { + transition = Object.assign({}, transition, variantStyle.transition) + } + if (isExiting && exitTransitionProp) { let exitTransition: MotiTransition | undefined if (exitTransitionProp && 'value' in exitTransitionProp) { @@ -457,7 +464,14 @@ export function useMotify({ if (Array.isArray(transformValue)) { // we have a sequence in this transform... - const sequence = getSequenceArray(transformKey, transformValue, delayMs, config, animation, callback) + const sequence = getSequenceArray( + transformKey, + transformValue, + delayMs, + config, + animation, + callback + ) if (sequence.length) { let finalValue = withSequence(sequence[0], ...sequence.slice(1)) @@ -494,7 +508,14 @@ export function useMotify({ } else if (Array.isArray(value)) { // we have a sequence - const sequence = getSequenceArray(key, value, delayMs, config, animation, callback) + const sequence = getSequenceArray( + key, + value, + delayMs, + config, + animation, + callback + ) let finalValue = withSequence(sequence[0], ...sequence.slice(1)) if (shouldRepeat) { finalValue = withRepeat(finalValue, repeatCount, repeatReverse) From 1f6602639e80731a308acf74ee1787001f63df9e Mon Sep 17 00:00:00 2001 From: Fernando Rojo Date: Tue, 27 Sep 2022 11:54:48 -0400 Subject: [PATCH 2/4] oops --- packages/moti/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/moti/package.json b/packages/moti/package.json index fbc7b03..0256a2d 100644 --- a/packages/moti/package.json +++ b/packages/moti/package.json @@ -1,7 +1,7 @@ { "name": "moti", "private": false, - "version": "0.0.19", + "version": "0.19.0", "keywords": [ "react-native", "ios", From cd7af3e0dd72910101e1dc84ef9c1d6d3d14571b Mon Sep 17 00:00:00 2001 From: Fernando Rojo Date: Tue, 27 Sep 2022 11:58:49 -0400 Subject: [PATCH 3/4] v20 --- packages/moti/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/moti/package.json b/packages/moti/package.json index 0256a2d..d94d5e8 100644 --- a/packages/moti/package.json +++ b/packages/moti/package.json @@ -1,7 +1,7 @@ { "name": "moti", "private": false, - "version": "0.19.0", + "version": "0.20.0", "keywords": [ "react-native", "ios", From dc6fde28646e11482dffe1d00ef3e3e96da69c78 Mon Sep 17 00:00:00 2001 From: Fernando Rojo Date: Mon, 14 Nov 2022 16:00:25 -0500 Subject: [PATCH 4/4] Delete publish.yml --- .github/workflows/publish.yml | 31 ------------------------------- 1 file changed, 31 deletions(-) delete mode 100644 .github/workflows/publish.yml diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index eb433f0..0000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,31 +0,0 @@ -# This is a basic workflow to help you get started with Actions - -name: Publish to npm - -# Controls when the action will run. -on: [push, pull_request] -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - # This workflow contains a single job called "build" - build: - # The type of runner that the job will run on - runs-on: ubuntu-latest - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - - name: Checkout - uses: actions/checkout@v2 - - run: git fetch --unshallow --tags - - name: restore lerna - uses: actions/cache@v2 - with: - path: | - node_modules - */*/node_modules - key: ${{ runner.os }}-${{ hashFiles('**/yarn.lock') }} - - run: yarn install - - run: yarn prepare - # - run: yarn auto shipit - # env: - # GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # NPM_TOKEN: ${{ secrets.NPM_TOKEN }}