Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ export const svgPropertiesRoutes = {
name: 'Stroke',
Component: svgAnimatedProperties.common.Stroke,
},
Transforms: {
name: 'Transforms',
Component: svgAnimatedProperties.common.Transforms,
},
},
},
} satisfies Routes;
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import Animated, { type CSSAnimationKeyframes } from 'react-native-reanimated';
import { Rect, type RectProps, Svg } from 'react-native-svg';

import { ExamplesScreen } from '@/apps/css/components';
import { colors } from '@/theme';

const AnimatedRect = Animated.createAnimatedComponent(Rect);

export default function TransformsExample() {
return (
<ExamplesScreen<{ keyframes: CSSAnimationKeyframes<RectProps> }, RectProps>
buildAnimation={({ keyframes }) => ({
animationName: keyframes,
animationDirection: 'alternate',
animationDuration: '1s',
animationIterationCount: 'infinite',
animationTimingFunction: 'linear',
})}
renderExample={({ animation }) => (
<Svg height={100} width={100}>
<AnimatedRect
animatedProps={animation}
fill={colors.primary}
height={60}
transform={[1, 0, 0, 1, 19.16096416682005, 0]}
width={60}
x={20}
y={20}
/>
</Svg>
)}
sections={[
{
examples: [
{
keyframes: {
from: {
transform: [{ translateX: 0 }],
},
to: {
transform: [{ translateX: 20 }],
},
},
title: 'Opacity',
},
],
title: 'Opacity',
},
]}
/>
);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import FillAndColor from './FillAndColor';
import Stroke from './Stroke';
import Transforms from './Transforms';

export default {
FillAndColor,
Stroke,
Transforms,
};
2 changes: 1 addition & 1 deletion apps/fabric-example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3187,7 +3187,7 @@ SPEC CHECKSUMS:
RNCClipboard: 4b58c780f63676367640f23c8e114e9bd0cf86ac
RNCMaskedView: 5ef8c95cbab95334a32763b72896a7b7d07e6299
RNGestureHandler: f1dd7f92a0faa2868a919ab53bb9d66eb4ebfcf5
RNReanimated: 3b47c33660454c6f9700b463e92daa282030866a
RNReanimated: 4b3866c617506e8b5dc5a6fef5eb61f93ac0d1c0
RNScreens: 6ced6ae8a526512a6eef6e28c2286e1fc2d378c3
RNSVG: 287504b73fa0e90a605225aa9f852a86d5461e84
RNWorklets: 991f94e4fa31fc20853e74d5d987426f8580cb0d
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#include <reanimated/CSS/InterpolatorRegistry.h>

#include <reanimated/CSS/common/transforms/TransformMatrix2D.h>
#include <reanimated/Tools/FeatureFlags.h>

#include <reanimated/CSS/interpolation/InterpolatorFactory.h>

#include <reanimated/CSS/common/values/CSSAngle.h>
#include <reanimated/CSS/common/values/CSSBoolean.h>
#include <reanimated/CSS/common/values/CSSColor.h>
Expand All @@ -9,21 +13,20 @@
#include <reanimated/CSS/common/values/CSSLength.h>
#include <reanimated/CSS/common/values/CSSNumber.h>
#include <reanimated/CSS/common/values/CSSValue.h>

#include <reanimated/CSS/common/transforms/TransformMatrix2D.h>
#include <reanimated/CSS/common/values/complex/CSSBoxShadow.h>

#include <reanimated/CSS/svg/values/SVGLength.h>
#include <reanimated/CSS/svg/values/SVGStrokeDashArray.h>

#include <reanimated/CSS/interpolation/InterpolatorFactory.h>
#include <reanimated/CSS/interpolation/transforms/operations/matrix.h>
#include <reanimated/CSS/interpolation/transforms/operations/perspective.h>
#include <reanimated/CSS/interpolation/transforms/operations/rotate.h>
#include <reanimated/CSS/interpolation/transforms/operations/scale.h>
#include <reanimated/CSS/interpolation/transforms/operations/skew.h>
#include <reanimated/CSS/interpolation/transforms/operations/translate.h>

#include <reanimated/CSS/svg/interpolation/InterpolatorFactory.h>

#include <reanimated/CSS/svg/values/SVGLength.h>
#include <reanimated/CSS/svg/values/SVGStrokeDashArray.h>

#include <vector>

namespace reanimated::css {
Expand Down Expand Up @@ -303,23 +306,26 @@ const InterpolatorFactoriesRecord SVG_CLIP_INTERPOLATORS = {
};

const InterpolatorFactoriesRecord SVG_TRANSFORM_INTERPOLATORS = {
{"translateX", value<SVGLength>(0)},
{"translateY", value<SVGLength>(0)},
{"originX", value<SVGLength>(0)},
{"originY", value<SVGLength>(0)},
{"scaleX", value<CSSDouble>(1)},
{"scaleY", value<CSSDouble>(1)},
{"skewX", value<CSSAngle>(0)},
{"skewY", value<CSSAngle>(0)},
{"rotation", value<CSSAngle>(0)},
};
{"matrix",
svg::transforms(
{{"rotate", transformOp<RotateOperation>("0deg")},
{"rotateZ", transformOp<RotateZOperation>("0deg")},
{"scale", transformOp<ScaleOperation>(1)},
{"scaleX", transformOp<ScaleXOperation>(1)},
{"scaleY", transformOp<ScaleYOperation>(1)},
{"translateX",
transformOp<TranslateXOperation>(0, {RelativeTo::Self, "width"})},
{"translateY",
transformOp<TranslateYOperation>(0, {RelativeTo::Self, "height"})},
{"skewX", transformOp<SkewXOperation>("0deg")},
{"skewY", transformOp<SkewYOperation>("0deg")},
{"matrix", transformOp<MatrixOperation>(TransformMatrix2D())}})}};

const InterpolatorFactoriesRecord SVG_COMMON_INTERPOLATORS =
mergeInterpolators({
SVG_COLOR_INTERPOLATORS,
SVG_FILL_INTERPOLATORS,
SVG_STROKE_INTERPOLATORS,
});
const InterpolatorFactoriesRecord SVG_COMMON_INTERPOLATORS = mergeInterpolators(
{SVG_COLOR_INTERPOLATORS,
SVG_FILL_INTERPOLATORS,
SVG_STROKE_INTERPOLATORS,
SVG_TRANSFORM_INTERPOLATORS});

const InterpolatorFactoriesRecord SVG_CIRCLE_INTERPOLATORS = mergeInterpolators(
{SVG_COMMON_INTERPOLATORS,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,18 @@ void TransformsStyleInterpolator::updateKeyframesFromStyleChange(
parseTransformOperations(newStyleValue).value_or(TransformOperations{})));
}

folly::dynamic TransformsStyleInterpolator::convertOperationsToDynamic(
const TransformOperations &operations) const {
auto result = folly::dynamic::array();
result.reserve(operations.size());

for (const auto &operation : operations) {
result.push_back(operation->toDynamic());
}

return result;
}

std::optional<TransformOperations>
TransformsStyleInterpolator::parseTransformOperations(
jsi::Runtime &rt,
Expand Down Expand Up @@ -395,16 +407,4 @@ folly::dynamic TransformsStyleInterpolator::interpolateOperations(
return convertOperationsToDynamic(result);
}

folly::dynamic TransformsStyleInterpolator::convertOperationsToDynamic(
const TransformOperations &operations) {
auto result = folly::dynamic::array();
result.reserve(operations.size());

for (const auto &operation : operations) {
result.push_back(operation->toDynamic());
}

return result;
}

} // namespace reanimated::css
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

#include <reanimated/CSS/interpolation/PropertyInterpolator.h>
#include <reanimated/CSS/interpolation/transforms/TransformOperationInterpolator.h>
#include <reanimated/CSS/interpolation/transforms/operations/matrix.h>
#include <reanimated/CSS/utils/keyframes.h>

#include <memory>
Expand All @@ -23,7 +22,7 @@ struct TransformKeyframe {
const std::optional<TransformOperations> toOperations;
};

class TransformsStyleInterpolator final : public PropertyInterpolator {
class TransformsStyleInterpolator : public PropertyInterpolator {
public:
TransformsStyleInterpolator(
const PropertyPath &propertyPath,
Expand Down Expand Up @@ -52,6 +51,10 @@ class TransformsStyleInterpolator final : public PropertyInterpolator {
const folly::dynamic &newStyleValue,
const folly::dynamic &lastUpdateValue) override;

protected:
virtual folly::dynamic convertOperationsToDynamic(
const TransformOperations &operations) const;

private:
const std::shared_ptr<TransformOperationInterpolators> interpolators_;
static const TransformOperations defaultStyleValue_;
Expand Down Expand Up @@ -85,14 +88,12 @@ class TransformsStyleInterpolator final : public PropertyInterpolator {
const std::shared_ptr<KeyframeProgressProvider> &progressProvider) const;
TransformOperations getFallbackValue(
const std::shared_ptr<const ShadowNode> &shadowNode) const;
folly::dynamic interpolateOperations(
virtual folly::dynamic interpolateOperations(
const std::shared_ptr<const ShadowNode> &shadowNode,
double keyframeProgress,
const TransformOperations &fromOperations,
const TransformOperations &toOperations) const;

static folly::dynamic convertOperationsToDynamic(
const TransformOperations &operations);
TransformInterpolationContext createUpdateContext(
const std::shared_ptr<const ShadowNode> &shadowNode) const;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace reanimated::css {

TransformMatrix3D matrixFromOperations3D(TransformOperations &operations) {
TransformMatrix3D matrixFromOperations3D(const TransformOperations &operations) {
TransformMatrix3D result;
for (int i = static_cast<int>(operations.size()) - 1; i >= 0; i--) {
result *=
Expand All @@ -16,7 +16,7 @@ TransformMatrix3D matrixFromOperations3D(TransformOperations &operations) {
return result;
}

TransformMatrix2D matrixFromOperations2D(TransformOperations &operations) {
TransformMatrix2D matrixFromOperations2D(const TransformOperations &operations) {
TransformMatrix2D result;
for (int i = static_cast<int>(operations.size()) - 1; i >= 0; i--) {
result *=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ using MatrixOperationValue =
* Multiplies all operations in the vector to a single 3D matrix
* @param operations - the vector of operations that can be represented in 3D
*/
TransformMatrix3D matrixFromOperations3D(TransformOperations &operations);
TransformMatrix3D matrixFromOperations3D(const TransformOperations &operations);

/**
* Multiplies all operations in the vector to a single 2D matrix
* @param operations - the vector of operations that can be represented in 2D
*/
TransformMatrix2D matrixFromOperations2D(TransformOperations &operations);
TransformMatrix2D matrixFromOperations2D(const TransformOperations &operations);

struct MatrixOperation final : public TransformOperation {
const MatrixOperationValue value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@ void CSSAnimationsRegistry::updateViewAnimations(
const auto updates = animation->update(timestamp);
const auto newState = animation->getState(timestamp);

LOG(INFO) << "Animation: " << animation->getName()
<< " updates: " << updates;

if (newState == AnimationProgressState::Finished) {
// Revert changes applied during animation if there is no forwards fill
// mode
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#include <reanimated/CSS/svg/interpolation/InterpolatorFactory.h>

#include <reanimated/CSS/svg/interpolation/transforms/TransformsStyleInterpolator.h>

namespace reanimated::css::svg {

class TransformsInterpolatorFactory : public PropertyInterpolatorFactory {
public:
explicit TransformsInterpolatorFactory(
const std::shared_ptr<TransformOperationInterpolators> &interpolators)
: PropertyInterpolatorFactory(), interpolators_(interpolators) {}

const CSSValue &getDefaultValue() const override {
static EmptyTransformsValue emptyTransformsValue;
return emptyTransformsValue;
}

std::shared_ptr<PropertyInterpolator> create(
const PropertyPath &propertyPath,
const std::shared_ptr<ViewStylesRepository> &viewStylesRepository)
const override {
return std::make_shared<TransformsStyleInterpolator>(
propertyPath, interpolators_, viewStylesRepository);
}

private:
// Helper private type just for a default value
struct EmptyTransformsValue : public CSSValue {
folly::dynamic toDynamic() const override {
return folly::dynamic::array(0, 0, 0, 0, 0, 0);
}

std::string toString() const override {
return "0, 0, 0, 0, 0, 0";
}
};

const std::shared_ptr<TransformOperationInterpolators> interpolators_;
};

std::shared_ptr<PropertyInterpolatorFactory> transforms(
const std::unordered_map<
std::string,
std::shared_ptr<TransformInterpolator>> &interpolators) {
TransformOperationInterpolators result;
result.reserve(interpolators.size());
for (const auto &[property, interpolator] : interpolators) {
result.emplace(getTransformOperationType(property), interpolator);
}
return std::make_shared<TransformsInterpolatorFactory>(
std::make_shared<TransformOperationInterpolators>(std::move(result)));
}

} // namespace reanimated::css::svg
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#pragma once

#include <reanimated/CSS/interpolation/PropertyInterpolator.h>
#include <reanimated/CSS/interpolation/transforms/TransformOperationInterpolator.h>

#include <memory>

namespace reanimated::css::svg {

/**
* Transform interpolators
*/
std::shared_ptr<PropertyInterpolatorFactory> transforms(
const std::unordered_map<
std::string,
std::shared_ptr<TransformInterpolator>> &interpolators);

} // namespace reanimated::css::svg
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include <reanimated/CSS/svg/interpolation/transforms/TransformsStyleInterpolator.h>

namespace reanimated::css::svg {

TransformsStyleInterpolator::TransformsStyleInterpolator(
const PropertyPath &propertyPath,
const std::shared_ptr<TransformOperationInterpolators> &interpolators,
const std::shared_ptr<ViewStylesRepository> &viewStylesRepository)
: css::TransformsStyleInterpolator(
propertyPath,
interpolators,
viewStylesRepository) {}

folly::dynamic TransformsStyleInterpolator::convertOperationsToDynamic(
const TransformOperations &operations) const {
const auto matrix = matrixFromOperations2D(operations);
// SVGs expect a 6-element array with 2D transform values
return folly::dynamic::array(
matrix[0], matrix[1], matrix[3], matrix[4], matrix[6], matrix[7]);
}

} // namespace reanimated::css::svg
Loading
Loading