rngine 0.11.0 → 0.11.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/typescript/src/nativeTypes.d.ts +8 -0
- package/lib/typescript/src/nativeTypes.d.ts.map +1 -1
- package/nitrogen/generated/shared/c++/Entity.hpp +19 -1
- package/nitrogen/generated/shared/c++/EntityUpdate.hpp +19 -1
- package/nitrogen/generated/shared/c++/ObjectFit.hpp +84 -0
- package/nitrogen/generated/shared/c++/Repeat.hpp +84 -0
- package/nitrogen/generated/shared/c++/Screen.hpp +19 -2
- package/nitrogen/generated/shared/c++/ScreenUpdate.hpp +19 -2
- package/package.json +1 -1
- package/shared/FitTransform.hpp +10 -0
- package/shared/GameLoop.cpp +13 -5
- package/shared/GameMethods.cpp +6 -0
- package/shared/GameRenderer.cpp +11 -4
- package/shared/utils/AssetUtils.cpp +240 -19
- package/shared/utils/AssetUtils.hpp +4 -1
- package/src/nativeTypes.ts +10 -0
|
@@ -20,6 +20,8 @@ interface Shaped {
|
|
|
20
20
|
/** Indicates whether the entity is a sensor. Sensors trigger collision events but don't react physically. */
|
|
21
21
|
isSensor?: boolean;
|
|
22
22
|
}
|
|
23
|
+
export type ObjectFit = 'fill' | 'contain' | 'cover' | 'none';
|
|
24
|
+
export type Repeat = 'no-repeat' | 'repeat' | 'repeat-x' | 'repeat-y';
|
|
23
25
|
interface Renderable {
|
|
24
26
|
/** Fill color as a hex string e.g. `'#00ff00'`. */
|
|
25
27
|
color?: string;
|
|
@@ -29,6 +31,12 @@ interface Renderable {
|
|
|
29
31
|
flipH?: boolean;
|
|
30
32
|
/** Whether to flip the rendered asset vertically. */
|
|
31
33
|
flipV?: boolean;
|
|
34
|
+
/** How the asset should be scaled to fit its target dimensions. Defaults to `'fill'`. */
|
|
35
|
+
objectFit?: ObjectFit;
|
|
36
|
+
/** Explicitly clips content that overflows the target dimensions. Defaults to `false`. */
|
|
37
|
+
clip?: boolean;
|
|
38
|
+
/** Repeating/tiling mode for the asset across target bounds. Defaults to `'no-repeat'`. */
|
|
39
|
+
repeat?: Repeat;
|
|
32
40
|
/** Animation progress between 0 and 1, automatically advanced each tick for Lottie assets. */
|
|
33
41
|
progress?: number;
|
|
34
42
|
/** Playback speed multiplier for Lottie assets (1 = normal speed). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nativeTypes.d.ts","sourceRoot":"","sources":["../../../src/nativeTypes.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"nativeTypes.d.ts","sourceRoot":"","sources":["../../../src/nativeTypes.ts"],"names":[],"mappings":"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"}
|
|
@@ -32,12 +32,18 @@
|
|
|
32
32
|
namespace margelo::nitro::rngine { struct Rect; }
|
|
33
33
|
// Forward declaration of `Circle` to properly resolve imports.
|
|
34
34
|
namespace margelo::nitro::rngine { struct Circle; }
|
|
35
|
+
// Forward declaration of `ObjectFit` to properly resolve imports.
|
|
36
|
+
namespace margelo::nitro::rngine { enum class ObjectFit; }
|
|
37
|
+
// Forward declaration of `Repeat` to properly resolve imports.
|
|
38
|
+
namespace margelo::nitro::rngine { enum class Repeat; }
|
|
35
39
|
|
|
36
40
|
#include <string>
|
|
37
41
|
#include "Rect.hpp"
|
|
38
42
|
#include "Circle.hpp"
|
|
39
43
|
#include <variant>
|
|
40
44
|
#include <optional>
|
|
45
|
+
#include "ObjectFit.hpp"
|
|
46
|
+
#include "Repeat.hpp"
|
|
41
47
|
|
|
42
48
|
namespace margelo::nitro::rngine {
|
|
43
49
|
|
|
@@ -55,6 +61,9 @@ namespace margelo::nitro::rngine {
|
|
|
55
61
|
std::optional<double> asset SWIFT_PRIVATE;
|
|
56
62
|
std::optional<bool> flipH SWIFT_PRIVATE;
|
|
57
63
|
std::optional<bool> flipV SWIFT_PRIVATE;
|
|
64
|
+
std::optional<ObjectFit> objectFit SWIFT_PRIVATE;
|
|
65
|
+
std::optional<bool> clip SWIFT_PRIVATE;
|
|
66
|
+
std::optional<Repeat> repeat SWIFT_PRIVATE;
|
|
58
67
|
std::optional<double> progress SWIFT_PRIVATE;
|
|
59
68
|
std::optional<double> speed SWIFT_PRIVATE;
|
|
60
69
|
std::optional<bool> loop SWIFT_PRIVATE;
|
|
@@ -66,7 +75,7 @@ namespace margelo::nitro::rngine {
|
|
|
66
75
|
|
|
67
76
|
public:
|
|
68
77
|
Entity() = default;
|
|
69
|
-
explicit Entity(std::string id, double px, double py, std::variant<Rect, Circle> shape, std::optional<bool> isSensor, std::optional<std::string> color, std::optional<double> asset, std::optional<bool> flipH, std::optional<bool> flipV, std::optional<double> progress, std::optional<double> speed, std::optional<bool> loop, std::optional<double> vx, std::optional<double> vy, std::optional<double> ax, std::optional<double> ay, std::optional<double> mass): id(id), px(px), py(py), shape(shape), isSensor(isSensor), color(color), asset(asset), flipH(flipH), flipV(flipV), progress(progress), speed(speed), loop(loop), vx(vx), vy(vy), ax(ax), ay(ay), mass(mass) {}
|
|
78
|
+
explicit Entity(std::string id, double px, double py, std::variant<Rect, Circle> shape, std::optional<bool> isSensor, std::optional<std::string> color, std::optional<double> asset, std::optional<bool> flipH, std::optional<bool> flipV, std::optional<ObjectFit> objectFit, std::optional<bool> clip, std::optional<Repeat> repeat, std::optional<double> progress, std::optional<double> speed, std::optional<bool> loop, std::optional<double> vx, std::optional<double> vy, std::optional<double> ax, std::optional<double> ay, std::optional<double> mass): id(id), px(px), py(py), shape(shape), isSensor(isSensor), color(color), asset(asset), flipH(flipH), flipV(flipV), objectFit(objectFit), clip(clip), repeat(repeat), progress(progress), speed(speed), loop(loop), vx(vx), vy(vy), ax(ax), ay(ay), mass(mass) {}
|
|
70
79
|
|
|
71
80
|
public:
|
|
72
81
|
friend bool operator==(const Entity& lhs, const Entity& rhs) = default;
|
|
@@ -91,6 +100,9 @@ namespace margelo::nitro {
|
|
|
91
100
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "asset"))),
|
|
92
101
|
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipH"))),
|
|
93
102
|
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipV"))),
|
|
103
|
+
JSIConverter<std::optional<margelo::nitro::rngine::ObjectFit>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "objectFit"))),
|
|
104
|
+
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "clip"))),
|
|
105
|
+
JSIConverter<std::optional<margelo::nitro::rngine::Repeat>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "repeat"))),
|
|
94
106
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "progress"))),
|
|
95
107
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "speed"))),
|
|
96
108
|
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "loop"))),
|
|
@@ -112,6 +124,9 @@ namespace margelo::nitro {
|
|
|
112
124
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "asset"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.asset));
|
|
113
125
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "flipH"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.flipH));
|
|
114
126
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "flipV"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.flipV));
|
|
127
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "objectFit"), JSIConverter<std::optional<margelo::nitro::rngine::ObjectFit>>::toJSI(runtime, arg.objectFit));
|
|
128
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "clip"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.clip));
|
|
129
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "repeat"), JSIConverter<std::optional<margelo::nitro::rngine::Repeat>>::toJSI(runtime, arg.repeat));
|
|
115
130
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "progress"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.progress));
|
|
116
131
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "speed"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.speed));
|
|
117
132
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "loop"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.loop));
|
|
@@ -139,6 +154,9 @@ namespace margelo::nitro {
|
|
|
139
154
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "asset")))) return false;
|
|
140
155
|
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipH")))) return false;
|
|
141
156
|
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipV")))) return false;
|
|
157
|
+
if (!JSIConverter<std::optional<margelo::nitro::rngine::ObjectFit>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "objectFit")))) return false;
|
|
158
|
+
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "clip")))) return false;
|
|
159
|
+
if (!JSIConverter<std::optional<margelo::nitro::rngine::Repeat>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "repeat")))) return false;
|
|
142
160
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "progress")))) return false;
|
|
143
161
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "speed")))) return false;
|
|
144
162
|
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "loop")))) return false;
|
|
@@ -32,12 +32,18 @@
|
|
|
32
32
|
namespace margelo::nitro::rngine { struct Rect; }
|
|
33
33
|
// Forward declaration of `Circle` to properly resolve imports.
|
|
34
34
|
namespace margelo::nitro::rngine { struct Circle; }
|
|
35
|
+
// Forward declaration of `ObjectFit` to properly resolve imports.
|
|
36
|
+
namespace margelo::nitro::rngine { enum class ObjectFit; }
|
|
37
|
+
// Forward declaration of `Repeat` to properly resolve imports.
|
|
38
|
+
namespace margelo::nitro::rngine { enum class Repeat; }
|
|
35
39
|
|
|
36
40
|
#include <string>
|
|
37
41
|
#include <optional>
|
|
38
42
|
#include "Rect.hpp"
|
|
39
43
|
#include "Circle.hpp"
|
|
40
44
|
#include <variant>
|
|
45
|
+
#include "ObjectFit.hpp"
|
|
46
|
+
#include "Repeat.hpp"
|
|
41
47
|
|
|
42
48
|
namespace margelo::nitro::rngine {
|
|
43
49
|
|
|
@@ -55,6 +61,9 @@ namespace margelo::nitro::rngine {
|
|
|
55
61
|
std::optional<double> asset SWIFT_PRIVATE;
|
|
56
62
|
std::optional<bool> flipH SWIFT_PRIVATE;
|
|
57
63
|
std::optional<bool> flipV SWIFT_PRIVATE;
|
|
64
|
+
std::optional<ObjectFit> objectFit SWIFT_PRIVATE;
|
|
65
|
+
std::optional<bool> clip SWIFT_PRIVATE;
|
|
66
|
+
std::optional<Repeat> repeat SWIFT_PRIVATE;
|
|
58
67
|
std::optional<double> progress SWIFT_PRIVATE;
|
|
59
68
|
std::optional<double> speed SWIFT_PRIVATE;
|
|
60
69
|
std::optional<bool> loop SWIFT_PRIVATE;
|
|
@@ -66,7 +75,7 @@ namespace margelo::nitro::rngine {
|
|
|
66
75
|
|
|
67
76
|
public:
|
|
68
77
|
EntityUpdate() = default;
|
|
69
|
-
explicit EntityUpdate(std::string id, std::optional<double> px, std::optional<double> py, std::optional<std::variant<Rect, Circle>> shape, std::optional<bool> isSensor, std::optional<std::string> color, std::optional<double> asset, std::optional<bool> flipH, std::optional<bool> flipV, std::optional<double> progress, std::optional<double> speed, std::optional<bool> loop, std::optional<double> vx, std::optional<double> vy, std::optional<double> ax, std::optional<double> ay, std::optional<double> mass): id(id), px(px), py(py), shape(shape), isSensor(isSensor), color(color), asset(asset), flipH(flipH), flipV(flipV), progress(progress), speed(speed), loop(loop), vx(vx), vy(vy), ax(ax), ay(ay), mass(mass) {}
|
|
78
|
+
explicit EntityUpdate(std::string id, std::optional<double> px, std::optional<double> py, std::optional<std::variant<Rect, Circle>> shape, std::optional<bool> isSensor, std::optional<std::string> color, std::optional<double> asset, std::optional<bool> flipH, std::optional<bool> flipV, std::optional<ObjectFit> objectFit, std::optional<bool> clip, std::optional<Repeat> repeat, std::optional<double> progress, std::optional<double> speed, std::optional<bool> loop, std::optional<double> vx, std::optional<double> vy, std::optional<double> ax, std::optional<double> ay, std::optional<double> mass): id(id), px(px), py(py), shape(shape), isSensor(isSensor), color(color), asset(asset), flipH(flipH), flipV(flipV), objectFit(objectFit), clip(clip), repeat(repeat), progress(progress), speed(speed), loop(loop), vx(vx), vy(vy), ax(ax), ay(ay), mass(mass) {}
|
|
70
79
|
|
|
71
80
|
public:
|
|
72
81
|
friend bool operator==(const EntityUpdate& lhs, const EntityUpdate& rhs) = default;
|
|
@@ -91,6 +100,9 @@ namespace margelo::nitro {
|
|
|
91
100
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "asset"))),
|
|
92
101
|
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipH"))),
|
|
93
102
|
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipV"))),
|
|
103
|
+
JSIConverter<std::optional<margelo::nitro::rngine::ObjectFit>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "objectFit"))),
|
|
104
|
+
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "clip"))),
|
|
105
|
+
JSIConverter<std::optional<margelo::nitro::rngine::Repeat>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "repeat"))),
|
|
94
106
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "progress"))),
|
|
95
107
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "speed"))),
|
|
96
108
|
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "loop"))),
|
|
@@ -112,6 +124,9 @@ namespace margelo::nitro {
|
|
|
112
124
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "asset"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.asset));
|
|
113
125
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "flipH"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.flipH));
|
|
114
126
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "flipV"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.flipV));
|
|
127
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "objectFit"), JSIConverter<std::optional<margelo::nitro::rngine::ObjectFit>>::toJSI(runtime, arg.objectFit));
|
|
128
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "clip"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.clip));
|
|
129
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "repeat"), JSIConverter<std::optional<margelo::nitro::rngine::Repeat>>::toJSI(runtime, arg.repeat));
|
|
115
130
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "progress"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.progress));
|
|
116
131
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "speed"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.speed));
|
|
117
132
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "loop"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.loop));
|
|
@@ -139,6 +154,9 @@ namespace margelo::nitro {
|
|
|
139
154
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "asset")))) return false;
|
|
140
155
|
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipH")))) return false;
|
|
141
156
|
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipV")))) return false;
|
|
157
|
+
if (!JSIConverter<std::optional<margelo::nitro::rngine::ObjectFit>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "objectFit")))) return false;
|
|
158
|
+
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "clip")))) return false;
|
|
159
|
+
if (!JSIConverter<std::optional<margelo::nitro::rngine::Repeat>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "repeat")))) return false;
|
|
142
160
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "progress")))) return false;
|
|
143
161
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "speed")))) return false;
|
|
144
162
|
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "loop")))) return false;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// ObjectFit.hpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#if __has_include(<NitroModules/NitroHash.hpp>)
|
|
11
|
+
#include <NitroModules/NitroHash.hpp>
|
|
12
|
+
#else
|
|
13
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
14
|
+
#endif
|
|
15
|
+
#if __has_include(<NitroModules/JSIConverter.hpp>)
|
|
16
|
+
#include <NitroModules/JSIConverter.hpp>
|
|
17
|
+
#else
|
|
18
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
19
|
+
#endif
|
|
20
|
+
#if __has_include(<NitroModules/NitroDefines.hpp>)
|
|
21
|
+
#include <NitroModules/NitroDefines.hpp>
|
|
22
|
+
#else
|
|
23
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
24
|
+
#endif
|
|
25
|
+
|
|
26
|
+
namespace margelo::nitro::rngine {
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* An enum which can be represented as a JavaScript union (ObjectFit).
|
|
30
|
+
*/
|
|
31
|
+
enum class ObjectFit {
|
|
32
|
+
FILL SWIFT_NAME(fill) = 0,
|
|
33
|
+
CONTAIN SWIFT_NAME(contain) = 1,
|
|
34
|
+
COVER SWIFT_NAME(cover) = 2,
|
|
35
|
+
NONE SWIFT_NAME(none) = 3,
|
|
36
|
+
} CLOSED_ENUM;
|
|
37
|
+
|
|
38
|
+
} // namespace margelo::nitro::rngine
|
|
39
|
+
|
|
40
|
+
namespace margelo::nitro {
|
|
41
|
+
|
|
42
|
+
// C++ ObjectFit <> JS ObjectFit (union)
|
|
43
|
+
template <>
|
|
44
|
+
struct JSIConverter<margelo::nitro::rngine::ObjectFit> final {
|
|
45
|
+
static inline margelo::nitro::rngine::ObjectFit fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
|
|
46
|
+
std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, arg);
|
|
47
|
+
switch (hashString(unionValue.c_str(), unionValue.size())) {
|
|
48
|
+
case hashString("fill"): return margelo::nitro::rngine::ObjectFit::FILL;
|
|
49
|
+
case hashString("contain"): return margelo::nitro::rngine::ObjectFit::CONTAIN;
|
|
50
|
+
case hashString("cover"): return margelo::nitro::rngine::ObjectFit::COVER;
|
|
51
|
+
case hashString("none"): return margelo::nitro::rngine::ObjectFit::NONE;
|
|
52
|
+
default: [[unlikely]]
|
|
53
|
+
throw std::invalid_argument("Cannot convert \"" + unionValue + "\" to enum ObjectFit - invalid value!");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
static inline jsi::Value toJSI(jsi::Runtime& runtime, margelo::nitro::rngine::ObjectFit arg) {
|
|
57
|
+
switch (arg) {
|
|
58
|
+
case margelo::nitro::rngine::ObjectFit::FILL: return JSIConverter<std::string>::toJSI(runtime, "fill");
|
|
59
|
+
case margelo::nitro::rngine::ObjectFit::CONTAIN: return JSIConverter<std::string>::toJSI(runtime, "contain");
|
|
60
|
+
case margelo::nitro::rngine::ObjectFit::COVER: return JSIConverter<std::string>::toJSI(runtime, "cover");
|
|
61
|
+
case margelo::nitro::rngine::ObjectFit::NONE: return JSIConverter<std::string>::toJSI(runtime, "none");
|
|
62
|
+
default: [[unlikely]]
|
|
63
|
+
throw std::invalid_argument("Cannot convert ObjectFit to JS - invalid value: "
|
|
64
|
+
+ std::to_string(static_cast<int>(arg)) + "!");
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
68
|
+
if (!value.isString()) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, value);
|
|
72
|
+
switch (hashString(unionValue.c_str(), unionValue.size())) {
|
|
73
|
+
case hashString("fill"):
|
|
74
|
+
case hashString("contain"):
|
|
75
|
+
case hashString("cover"):
|
|
76
|
+
case hashString("none"):
|
|
77
|
+
return true;
|
|
78
|
+
default:
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
} // namespace margelo::nitro
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// Repeat.hpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#if __has_include(<NitroModules/NitroHash.hpp>)
|
|
11
|
+
#include <NitroModules/NitroHash.hpp>
|
|
12
|
+
#else
|
|
13
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
14
|
+
#endif
|
|
15
|
+
#if __has_include(<NitroModules/JSIConverter.hpp>)
|
|
16
|
+
#include <NitroModules/JSIConverter.hpp>
|
|
17
|
+
#else
|
|
18
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
19
|
+
#endif
|
|
20
|
+
#if __has_include(<NitroModules/NitroDefines.hpp>)
|
|
21
|
+
#include <NitroModules/NitroDefines.hpp>
|
|
22
|
+
#else
|
|
23
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
24
|
+
#endif
|
|
25
|
+
|
|
26
|
+
namespace margelo::nitro::rngine {
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* An enum which can be represented as a JavaScript union (Repeat).
|
|
30
|
+
*/
|
|
31
|
+
enum class Repeat {
|
|
32
|
+
NO_REPEAT SWIFT_NAME(noRepeat) = 0,
|
|
33
|
+
REPEAT SWIFT_NAME(repeat) = 1,
|
|
34
|
+
REPEAT_X SWIFT_NAME(repeatX) = 2,
|
|
35
|
+
REPEAT_Y SWIFT_NAME(repeatY) = 3,
|
|
36
|
+
} CLOSED_ENUM;
|
|
37
|
+
|
|
38
|
+
} // namespace margelo::nitro::rngine
|
|
39
|
+
|
|
40
|
+
namespace margelo::nitro {
|
|
41
|
+
|
|
42
|
+
// C++ Repeat <> JS Repeat (union)
|
|
43
|
+
template <>
|
|
44
|
+
struct JSIConverter<margelo::nitro::rngine::Repeat> final {
|
|
45
|
+
static inline margelo::nitro::rngine::Repeat fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
|
|
46
|
+
std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, arg);
|
|
47
|
+
switch (hashString(unionValue.c_str(), unionValue.size())) {
|
|
48
|
+
case hashString("no-repeat"): return margelo::nitro::rngine::Repeat::NO_REPEAT;
|
|
49
|
+
case hashString("repeat"): return margelo::nitro::rngine::Repeat::REPEAT;
|
|
50
|
+
case hashString("repeat-x"): return margelo::nitro::rngine::Repeat::REPEAT_X;
|
|
51
|
+
case hashString("repeat-y"): return margelo::nitro::rngine::Repeat::REPEAT_Y;
|
|
52
|
+
default: [[unlikely]]
|
|
53
|
+
throw std::invalid_argument("Cannot convert \"" + unionValue + "\" to enum Repeat - invalid value!");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
static inline jsi::Value toJSI(jsi::Runtime& runtime, margelo::nitro::rngine::Repeat arg) {
|
|
57
|
+
switch (arg) {
|
|
58
|
+
case margelo::nitro::rngine::Repeat::NO_REPEAT: return JSIConverter<std::string>::toJSI(runtime, "no-repeat");
|
|
59
|
+
case margelo::nitro::rngine::Repeat::REPEAT: return JSIConverter<std::string>::toJSI(runtime, "repeat");
|
|
60
|
+
case margelo::nitro::rngine::Repeat::REPEAT_X: return JSIConverter<std::string>::toJSI(runtime, "repeat-x");
|
|
61
|
+
case margelo::nitro::rngine::Repeat::REPEAT_Y: return JSIConverter<std::string>::toJSI(runtime, "repeat-y");
|
|
62
|
+
default: [[unlikely]]
|
|
63
|
+
throw std::invalid_argument("Cannot convert Repeat to JS - invalid value: "
|
|
64
|
+
+ std::to_string(static_cast<int>(arg)) + "!");
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
68
|
+
if (!value.isString()) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, value);
|
|
72
|
+
switch (hashString(unionValue.c_str(), unionValue.size())) {
|
|
73
|
+
case hashString("no-repeat"):
|
|
74
|
+
case hashString("repeat"):
|
|
75
|
+
case hashString("repeat-x"):
|
|
76
|
+
case hashString("repeat-y"):
|
|
77
|
+
return true;
|
|
78
|
+
default:
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
} // namespace margelo::nitro
|
|
@@ -28,10 +28,15 @@
|
|
|
28
28
|
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
29
29
|
#endif
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
// Forward declaration of `ObjectFit` to properly resolve imports.
|
|
32
|
+
namespace margelo::nitro::rngine { enum class ObjectFit; }
|
|
33
|
+
// Forward declaration of `Repeat` to properly resolve imports.
|
|
34
|
+
namespace margelo::nitro::rngine { enum class Repeat; }
|
|
32
35
|
|
|
33
36
|
#include <string>
|
|
34
37
|
#include <optional>
|
|
38
|
+
#include "ObjectFit.hpp"
|
|
39
|
+
#include "Repeat.hpp"
|
|
35
40
|
|
|
36
41
|
namespace margelo::nitro::rngine {
|
|
37
42
|
|
|
@@ -48,13 +53,16 @@ namespace margelo::nitro::rngine {
|
|
|
48
53
|
std::optional<double> asset SWIFT_PRIVATE;
|
|
49
54
|
std::optional<bool> flipH SWIFT_PRIVATE;
|
|
50
55
|
std::optional<bool> flipV SWIFT_PRIVATE;
|
|
56
|
+
std::optional<ObjectFit> objectFit SWIFT_PRIVATE;
|
|
57
|
+
std::optional<bool> clip SWIFT_PRIVATE;
|
|
58
|
+
std::optional<Repeat> repeat SWIFT_PRIVATE;
|
|
51
59
|
std::optional<double> progress SWIFT_PRIVATE;
|
|
52
60
|
std::optional<double> speed SWIFT_PRIVATE;
|
|
53
61
|
std::optional<bool> loop SWIFT_PRIVATE;
|
|
54
62
|
|
|
55
63
|
public:
|
|
56
64
|
Screen() = default;
|
|
57
|
-
explicit Screen(double px, double py, double width, double height, std::optional<std::string> color, std::optional<double> asset, std::optional<bool> flipH, std::optional<bool> flipV, std::optional<double> progress, std::optional<double> speed, std::optional<bool> loop): px(px), py(py), width(width), height(height), color(color), asset(asset), flipH(flipH), flipV(flipV), progress(progress), speed(speed), loop(loop) {}
|
|
65
|
+
explicit Screen(double px, double py, double width, double height, std::optional<std::string> color, std::optional<double> asset, std::optional<bool> flipH, std::optional<bool> flipV, std::optional<ObjectFit> objectFit, std::optional<bool> clip, std::optional<Repeat> repeat, std::optional<double> progress, std::optional<double> speed, std::optional<bool> loop): px(px), py(py), width(width), height(height), color(color), asset(asset), flipH(flipH), flipV(flipV), objectFit(objectFit), clip(clip), repeat(repeat), progress(progress), speed(speed), loop(loop) {}
|
|
58
66
|
|
|
59
67
|
public:
|
|
60
68
|
friend bool operator==(const Screen& lhs, const Screen& rhs) = default;
|
|
@@ -78,6 +86,9 @@ namespace margelo::nitro {
|
|
|
78
86
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "asset"))),
|
|
79
87
|
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipH"))),
|
|
80
88
|
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipV"))),
|
|
89
|
+
JSIConverter<std::optional<margelo::nitro::rngine::ObjectFit>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "objectFit"))),
|
|
90
|
+
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "clip"))),
|
|
91
|
+
JSIConverter<std::optional<margelo::nitro::rngine::Repeat>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "repeat"))),
|
|
81
92
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "progress"))),
|
|
82
93
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "speed"))),
|
|
83
94
|
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "loop")))
|
|
@@ -93,6 +104,9 @@ namespace margelo::nitro {
|
|
|
93
104
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "asset"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.asset));
|
|
94
105
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "flipH"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.flipH));
|
|
95
106
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "flipV"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.flipV));
|
|
107
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "objectFit"), JSIConverter<std::optional<margelo::nitro::rngine::ObjectFit>>::toJSI(runtime, arg.objectFit));
|
|
108
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "clip"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.clip));
|
|
109
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "repeat"), JSIConverter<std::optional<margelo::nitro::rngine::Repeat>>::toJSI(runtime, arg.repeat));
|
|
96
110
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "progress"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.progress));
|
|
97
111
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "speed"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.speed));
|
|
98
112
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "loop"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.loop));
|
|
@@ -114,6 +128,9 @@ namespace margelo::nitro {
|
|
|
114
128
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "asset")))) return false;
|
|
115
129
|
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipH")))) return false;
|
|
116
130
|
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipV")))) return false;
|
|
131
|
+
if (!JSIConverter<std::optional<margelo::nitro::rngine::ObjectFit>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "objectFit")))) return false;
|
|
132
|
+
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "clip")))) return false;
|
|
133
|
+
if (!JSIConverter<std::optional<margelo::nitro::rngine::Repeat>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "repeat")))) return false;
|
|
117
134
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "progress")))) return false;
|
|
118
135
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "speed")))) return false;
|
|
119
136
|
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "loop")))) return false;
|
|
@@ -28,10 +28,15 @@
|
|
|
28
28
|
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
29
29
|
#endif
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
// Forward declaration of `ObjectFit` to properly resolve imports.
|
|
32
|
+
namespace margelo::nitro::rngine { enum class ObjectFit; }
|
|
33
|
+
// Forward declaration of `Repeat` to properly resolve imports.
|
|
34
|
+
namespace margelo::nitro::rngine { enum class Repeat; }
|
|
32
35
|
|
|
33
36
|
#include <optional>
|
|
34
37
|
#include <string>
|
|
38
|
+
#include "ObjectFit.hpp"
|
|
39
|
+
#include "Repeat.hpp"
|
|
35
40
|
|
|
36
41
|
namespace margelo::nitro::rngine {
|
|
37
42
|
|
|
@@ -48,13 +53,16 @@ namespace margelo::nitro::rngine {
|
|
|
48
53
|
std::optional<double> asset SWIFT_PRIVATE;
|
|
49
54
|
std::optional<bool> flipH SWIFT_PRIVATE;
|
|
50
55
|
std::optional<bool> flipV SWIFT_PRIVATE;
|
|
56
|
+
std::optional<ObjectFit> objectFit SWIFT_PRIVATE;
|
|
57
|
+
std::optional<bool> clip SWIFT_PRIVATE;
|
|
58
|
+
std::optional<Repeat> repeat SWIFT_PRIVATE;
|
|
51
59
|
std::optional<double> progress SWIFT_PRIVATE;
|
|
52
60
|
std::optional<double> speed SWIFT_PRIVATE;
|
|
53
61
|
std::optional<bool> loop SWIFT_PRIVATE;
|
|
54
62
|
|
|
55
63
|
public:
|
|
56
64
|
ScreenUpdate() = default;
|
|
57
|
-
explicit ScreenUpdate(std::optional<double> px, std::optional<double> py, std::optional<double> width, std::optional<double> height, std::optional<std::string> color, std::optional<double> asset, std::optional<bool> flipH, std::optional<bool> flipV, std::optional<double> progress, std::optional<double> speed, std::optional<bool> loop): px(px), py(py), width(width), height(height), color(color), asset(asset), flipH(flipH), flipV(flipV), progress(progress), speed(speed), loop(loop) {}
|
|
65
|
+
explicit ScreenUpdate(std::optional<double> px, std::optional<double> py, std::optional<double> width, std::optional<double> height, std::optional<std::string> color, std::optional<double> asset, std::optional<bool> flipH, std::optional<bool> flipV, std::optional<ObjectFit> objectFit, std::optional<bool> clip, std::optional<Repeat> repeat, std::optional<double> progress, std::optional<double> speed, std::optional<bool> loop): px(px), py(py), width(width), height(height), color(color), asset(asset), flipH(flipH), flipV(flipV), objectFit(objectFit), clip(clip), repeat(repeat), progress(progress), speed(speed), loop(loop) {}
|
|
58
66
|
|
|
59
67
|
public:
|
|
60
68
|
friend bool operator==(const ScreenUpdate& lhs, const ScreenUpdate& rhs) = default;
|
|
@@ -78,6 +86,9 @@ namespace margelo::nitro {
|
|
|
78
86
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "asset"))),
|
|
79
87
|
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipH"))),
|
|
80
88
|
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipV"))),
|
|
89
|
+
JSIConverter<std::optional<margelo::nitro::rngine::ObjectFit>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "objectFit"))),
|
|
90
|
+
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "clip"))),
|
|
91
|
+
JSIConverter<std::optional<margelo::nitro::rngine::Repeat>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "repeat"))),
|
|
81
92
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "progress"))),
|
|
82
93
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "speed"))),
|
|
83
94
|
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "loop")))
|
|
@@ -93,6 +104,9 @@ namespace margelo::nitro {
|
|
|
93
104
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "asset"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.asset));
|
|
94
105
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "flipH"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.flipH));
|
|
95
106
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "flipV"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.flipV));
|
|
107
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "objectFit"), JSIConverter<std::optional<margelo::nitro::rngine::ObjectFit>>::toJSI(runtime, arg.objectFit));
|
|
108
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "clip"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.clip));
|
|
109
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "repeat"), JSIConverter<std::optional<margelo::nitro::rngine::Repeat>>::toJSI(runtime, arg.repeat));
|
|
96
110
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "progress"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.progress));
|
|
97
111
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "speed"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.speed));
|
|
98
112
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "loop"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.loop));
|
|
@@ -114,6 +128,9 @@ namespace margelo::nitro {
|
|
|
114
128
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "asset")))) return false;
|
|
115
129
|
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipH")))) return false;
|
|
116
130
|
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipV")))) return false;
|
|
131
|
+
if (!JSIConverter<std::optional<margelo::nitro::rngine::ObjectFit>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "objectFit")))) return false;
|
|
132
|
+
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "clip")))) return false;
|
|
133
|
+
if (!JSIConverter<std::optional<margelo::nitro::rngine::Repeat>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "repeat")))) return false;
|
|
117
134
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "progress")))) return false;
|
|
118
135
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "speed")))) return false;
|
|
119
136
|
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "loop")))) return false;
|
package/package.json
CHANGED
package/shared/GameLoop.cpp
CHANGED
|
@@ -124,12 +124,20 @@ void GameLoop::runSystems() {
|
|
|
124
124
|
if (system.collisions.has_value()) {
|
|
125
125
|
for (const auto &pair : system.collisions.value()) {
|
|
126
126
|
for (const auto &c : _collisions) {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
bool matchesReverse =
|
|
130
|
-
entityIdMatches(c.a, pair.b) && entityIdMatches(c.b, pair.a);
|
|
131
|
-
if (matchesForward || matchesReverse) {
|
|
127
|
+
|
|
128
|
+
if (entityIdMatches(c.a, pair.a) && entityIdMatches(c.b, pair.b)) {
|
|
132
129
|
systemContext.collisions.push_back(c);
|
|
130
|
+
} else if (entityIdMatches(c.a, pair.b) &&
|
|
131
|
+
entityIdMatches(c.b, pair.a)) {
|
|
132
|
+
auto swappedCollision = c;
|
|
133
|
+
|
|
134
|
+
swappedCollision.a = c.b;
|
|
135
|
+
swappedCollision.b = c.a;
|
|
136
|
+
|
|
137
|
+
swappedCollision.nx = -c.nx;
|
|
138
|
+
swappedCollision.ny = -c.ny;
|
|
139
|
+
|
|
140
|
+
systemContext.collisions.push_back(swappedCollision);
|
|
133
141
|
}
|
|
134
142
|
}
|
|
135
143
|
}
|
package/shared/GameMethods.cpp
CHANGED
|
@@ -138,6 +138,9 @@ void GameMethods::updateEntities(
|
|
|
138
138
|
patch(entityUpdate.color, entity->color);
|
|
139
139
|
patch(entityUpdate.flipH, entity->flipH);
|
|
140
140
|
patch(entityUpdate.flipV, entity->flipV);
|
|
141
|
+
patch(entityUpdate.objectFit, entity->objectFit);
|
|
142
|
+
patch(entityUpdate.clip, entity->clip);
|
|
143
|
+
patch(entityUpdate.repeat, entity->repeat);
|
|
141
144
|
patch(entityUpdate.vx, entity->vx);
|
|
142
145
|
patch(entityUpdate.vy, entity->vy);
|
|
143
146
|
patch(entityUpdate.ax, entity->ax);
|
|
@@ -168,6 +171,9 @@ void GameMethods::updateScreen(const ScreenUpdate &screenUpdate) {
|
|
|
168
171
|
patch(screenUpdate.color, screen.color);
|
|
169
172
|
patch(screenUpdate.flipH, screen.flipH);
|
|
170
173
|
patch(screenUpdate.flipV, screen.flipV);
|
|
174
|
+
patch(screenUpdate.objectFit, screen.objectFit);
|
|
175
|
+
patch(screenUpdate.clip, screen.clip);
|
|
176
|
+
patch(screenUpdate.repeat, screen.repeat);
|
|
171
177
|
|
|
172
178
|
__android_log_print(ANDROID_LOG_INFO, "GameMethods",
|
|
173
179
|
"updateScreen: patched screen");
|
package/shared/GameRenderer.cpp
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
#include "GameRenderer.hpp"
|
|
2
2
|
#include "AssetUtils.hpp"
|
|
3
3
|
#include "ColorUtils.hpp"
|
|
4
|
+
#include "ObjectFit.hpp"
|
|
4
5
|
#include "Rect.hpp"
|
|
5
6
|
|
|
6
7
|
#include <android/log.h>
|
|
7
8
|
#include <android/native_window.h>
|
|
8
9
|
|
|
10
|
+
#include "Repeat.hpp"
|
|
9
11
|
#include "include/core/SkCanvas.h"
|
|
10
12
|
#include "include/core/SkColor.h"
|
|
11
13
|
#include "include/core/SkColorSpace.h"
|
|
@@ -174,10 +176,12 @@ void GameRenderer::render(const Screen &screen,
|
|
|
174
176
|
if (screen.asset.has_value() && screen.asset.value() != 0) {
|
|
175
177
|
SkAutoCanvasRestore restore(canvas, true);
|
|
176
178
|
canvas->translate(gameBounds.left(), gameBounds.top());
|
|
177
|
-
AssetUtils::drawAsset(
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
179
|
+
AssetUtils::drawAsset(
|
|
180
|
+
canvas, screen.asset.value(), virtualWidth, virtualHeight,
|
|
181
|
+
screen.flipH.value_or(false), screen.flipV.value_or(false),
|
|
182
|
+
screen.objectFit.value_or(ObjectFit::FILL), screen.clip.value_or(false),
|
|
183
|
+
screen.repeat.value_or(Repeat::NO_REPEAT),
|
|
184
|
+
screen.progress.value_or(0.0));
|
|
181
185
|
}
|
|
182
186
|
|
|
183
187
|
for (const auto &[id, entity] : entities) {
|
|
@@ -235,6 +239,9 @@ void GameRenderer::render(const Screen &screen,
|
|
|
235
239
|
AssetUtils::drawAsset(canvas, entity.asset.value(), width, height,
|
|
236
240
|
entity.flipH.value_or(false),
|
|
237
241
|
entity.flipV.value_or(false),
|
|
242
|
+
entity.objectFit.value_or(ObjectFit::FILL),
|
|
243
|
+
entity.clip.value_or(false),
|
|
244
|
+
entity.repeat.value_or(Repeat::NO_REPEAT),
|
|
238
245
|
entity.progress.value_or(0.0));
|
|
239
246
|
}
|
|
240
247
|
}
|
|
@@ -1,36 +1,260 @@
|
|
|
1
1
|
#include "AssetUtils.hpp"
|
|
2
|
+
#include "FitTransform.hpp"
|
|
2
3
|
#include "GameRenderer.hpp"
|
|
3
4
|
#include <variant>
|
|
4
5
|
|
|
5
6
|
namespace margelo::nitro::rngine::AssetUtils {
|
|
6
|
-
static
|
|
7
|
-
|
|
7
|
+
static FitTransform computeFitTransform(float srcW, float srcH,
|
|
8
|
+
float targetWidth, float targetHeight,
|
|
9
|
+
ObjectFit objectFit) {
|
|
10
|
+
FitTransform tf;
|
|
11
|
+
if (srcW <= 0.0f || srcH <= 0.0f || targetWidth <= 0.0f ||
|
|
12
|
+
targetHeight <= 0.0f) {
|
|
13
|
+
return tf;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
switch (objectFit) {
|
|
17
|
+
case ObjectFit::FILL: {
|
|
18
|
+
tf.scaleX = targetWidth / srcW;
|
|
19
|
+
tf.scaleY = targetHeight / srcH;
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
case ObjectFit::CONTAIN: {
|
|
24
|
+
float scale = std::min(targetWidth / srcW, targetHeight / srcH);
|
|
25
|
+
tf.scaleX = scale;
|
|
26
|
+
tf.scaleY = scale;
|
|
27
|
+
|
|
28
|
+
float drawW = srcW * scale;
|
|
29
|
+
float drawH = srcH * scale;
|
|
30
|
+
tf.translateX = (targetWidth - drawW) * 0.5f;
|
|
31
|
+
tf.translateY = (targetHeight - drawH) * 0.5f;
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
case ObjectFit::COVER: {
|
|
36
|
+
float scale = std::max(targetWidth / srcW, targetHeight / srcH);
|
|
37
|
+
tf.scaleX = scale;
|
|
38
|
+
tf.scaleY = scale;
|
|
39
|
+
|
|
40
|
+
float drawW = srcW * scale;
|
|
41
|
+
float drawH = srcH * scale;
|
|
42
|
+
tf.translateX = (targetWidth - drawW) * 0.5f;
|
|
43
|
+
tf.translateY = (targetHeight - drawH) * 0.5f;
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
case ObjectFit::NONE: {
|
|
48
|
+
tf.scaleX = 1.0f;
|
|
49
|
+
tf.scaleY = 1.0f;
|
|
50
|
+
tf.translateX = (targetWidth - srcW) * 0.5f;
|
|
51
|
+
tf.translateY = (targetHeight - srcH) * 0.5f;
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return tf;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static float computeCenteredTileStart(float targetSize, float tileSize) {
|
|
60
|
+
if (tileSize <= 0.0f)
|
|
61
|
+
return 0.0f;
|
|
62
|
+
float center = targetSize * 0.5f;
|
|
63
|
+
float offset = std::fmod(center, tileSize);
|
|
64
|
+
return offset - tileSize;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
static void drawSVG(SkCanvas *canvas, const sk_sp<SkSVGDOM> &svg,
|
|
68
|
+
float targetWidth, float targetHeight, ObjectFit objectFit,
|
|
69
|
+
bool clip, Repeat repeat) {
|
|
8
70
|
SkSize intrinsicSize = svg->containerSize();
|
|
9
71
|
if (intrinsicSize.isEmpty()) {
|
|
10
|
-
svg->setContainerSize(SkSize::Make(
|
|
11
|
-
intrinsicSize = SkSize::Make(
|
|
72
|
+
svg->setContainerSize(SkSize::Make(targetWidth, targetHeight));
|
|
73
|
+
intrinsicSize = SkSize::Make(targetWidth, targetHeight);
|
|
12
74
|
}
|
|
13
75
|
|
|
76
|
+
FitTransform tf =
|
|
77
|
+
computeFitTransform(intrinsicSize.width(), intrinsicSize.height(),
|
|
78
|
+
targetWidth, targetHeight, objectFit);
|
|
79
|
+
|
|
80
|
+
float tileW = intrinsicSize.width() * tf.scaleX;
|
|
81
|
+
float tileH = intrinsicSize.height() * tf.scaleY;
|
|
82
|
+
if (tileW <= 0.0f || tileH <= 0.0f)
|
|
83
|
+
return;
|
|
84
|
+
|
|
14
85
|
SkAutoCanvasRestore restore(canvas, true);
|
|
15
|
-
|
|
16
|
-
|
|
86
|
+
|
|
87
|
+
bool isRepeating = (repeat != Repeat::NO_REPEAT);
|
|
88
|
+
bool shouldClip = clip && (objectFit == ObjectFit::COVER ||
|
|
89
|
+
objectFit == ObjectFit::NONE || isRepeating);
|
|
90
|
+
|
|
91
|
+
if (shouldClip) {
|
|
92
|
+
canvas->clipRect(SkRect::MakeWH(targetWidth, targetHeight));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (!isRepeating) {
|
|
96
|
+
canvas->translate(tf.translateX, tf.translateY);
|
|
97
|
+
canvas->scale(tf.scaleX, tf.scaleY);
|
|
98
|
+
svg->render(canvas);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
float startX = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_X)
|
|
103
|
+
? computeCenteredTileStart(targetWidth, tileW)
|
|
104
|
+
: tf.translateX;
|
|
105
|
+
|
|
106
|
+
float startY = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_Y)
|
|
107
|
+
? computeCenteredTileStart(targetHeight, tileH)
|
|
108
|
+
: tf.translateY;
|
|
109
|
+
|
|
110
|
+
float endX = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_X)
|
|
111
|
+
? targetWidth
|
|
112
|
+
: (startX + tileW);
|
|
113
|
+
|
|
114
|
+
float endY = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_Y)
|
|
115
|
+
? targetHeight
|
|
116
|
+
: (startY + tileH);
|
|
117
|
+
|
|
118
|
+
for (float y = startY; y < endY; y += tileH) {
|
|
119
|
+
for (float x = startX; x < endX; x += tileW) {
|
|
120
|
+
SkAutoCanvasRestore tileRestore(canvas, true);
|
|
121
|
+
canvas->translate(x, y);
|
|
122
|
+
canvas->scale(tf.scaleX, tf.scaleY);
|
|
123
|
+
svg->render(canvas);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
17
126
|
}
|
|
18
127
|
|
|
19
128
|
static void drawRaster(SkCanvas *canvas, const sk_sp<SkImage> &raster,
|
|
20
|
-
float
|
|
129
|
+
float targetWidth, float targetHeight,
|
|
130
|
+
ObjectFit objectFit, bool clip, Repeat repeat) {
|
|
21
131
|
float intrinsicW = static_cast<float>(raster->width());
|
|
22
132
|
float intrinsicH = static_cast<float>(raster->height());
|
|
23
133
|
if (intrinsicW <= 0.0f || intrinsicH <= 0.0f)
|
|
24
134
|
return;
|
|
25
135
|
|
|
136
|
+
FitTransform tf = computeFitTransform(intrinsicW, intrinsicH, targetWidth,
|
|
137
|
+
targetHeight, objectFit);
|
|
138
|
+
|
|
26
139
|
SkAutoCanvasRestore restore(canvas, true);
|
|
27
|
-
|
|
140
|
+
|
|
141
|
+
bool isRepeating = (repeat != Repeat::NO_REPEAT);
|
|
142
|
+
bool shouldClip = clip && (objectFit == ObjectFit::COVER ||
|
|
143
|
+
objectFit == ObjectFit::NONE || isRepeating);
|
|
144
|
+
|
|
145
|
+
if (shouldClip) {
|
|
146
|
+
canvas->clipRect(SkRect::MakeWH(targetWidth, targetHeight));
|
|
147
|
+
}
|
|
148
|
+
|
|
28
149
|
SkSamplingOptions sampling(SkFilterMode::kLinear, SkMipmapMode::kLinear);
|
|
29
|
-
|
|
150
|
+
|
|
151
|
+
if (!isRepeating) {
|
|
152
|
+
canvas->translate(tf.translateX, tf.translateY);
|
|
153
|
+
canvas->scale(tf.scaleX, tf.scaleY);
|
|
154
|
+
canvas->drawImage(raster, 0.0f, 0.0f, sampling);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
SkTileMode tileX = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_X)
|
|
159
|
+
? SkTileMode::kRepeat
|
|
160
|
+
: SkTileMode::kClamp;
|
|
161
|
+
SkTileMode tileY = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_Y)
|
|
162
|
+
? SkTileMode::kRepeat
|
|
163
|
+
: SkTileMode::kClamp;
|
|
164
|
+
|
|
165
|
+
float tileW = intrinsicW * tf.scaleX;
|
|
166
|
+
float tileH = intrinsicH * tf.scaleY;
|
|
167
|
+
|
|
168
|
+
SkMatrix localMatrix = SkMatrix::Scale(tf.scaleX, tf.scaleY);
|
|
169
|
+
|
|
170
|
+
float offsetX = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_X)
|
|
171
|
+
? computeCenteredTileStart(targetWidth, tileW)
|
|
172
|
+
: tf.translateX;
|
|
173
|
+
float offsetY = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_Y)
|
|
174
|
+
? computeCenteredTileStart(targetHeight, tileH)
|
|
175
|
+
: tf.translateY;
|
|
176
|
+
|
|
177
|
+
localMatrix.postTranslate(offsetX, offsetY);
|
|
178
|
+
|
|
179
|
+
auto shader = raster->makeShader(tileX, tileY, sampling, localMatrix);
|
|
180
|
+
|
|
181
|
+
SkPaint paint;
|
|
182
|
+
paint.setShader(shader);
|
|
183
|
+
canvas->drawRect(SkRect::MakeWH(targetWidth, targetHeight), paint);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
static void drawLottie(SkCanvas *canvas,
|
|
187
|
+
const sk_sp<skottie::Animation> &lottie,
|
|
188
|
+
float targetWidth, float targetHeight,
|
|
189
|
+
ObjectFit objectFit, bool clip, Repeat repeat,
|
|
190
|
+
double progress) {
|
|
191
|
+
lottie->seek(progress);
|
|
192
|
+
|
|
193
|
+
SkSize intrinsicSize = lottie->size();
|
|
194
|
+
float intrinsicWidth = intrinsicSize.width();
|
|
195
|
+
float intrinsicHeight = intrinsicSize.height();
|
|
196
|
+
|
|
197
|
+
if (intrinsicWidth <= 0.0f || intrinsicHeight <= 0.0f)
|
|
198
|
+
return;
|
|
199
|
+
|
|
200
|
+
FitTransform tf = computeFitTransform(intrinsicWidth, intrinsicHeight,
|
|
201
|
+
targetWidth, targetHeight, objectFit);
|
|
202
|
+
|
|
203
|
+
float tileW = intrinsicWidth * tf.scaleX;
|
|
204
|
+
float tileH = intrinsicHeight * tf.scaleY;
|
|
205
|
+
if (tileW <= 0.0f || tileH <= 0.0f)
|
|
206
|
+
return;
|
|
207
|
+
|
|
208
|
+
SkAutoCanvasRestore restore(canvas, true);
|
|
209
|
+
|
|
210
|
+
bool isRepeating = (repeat != Repeat::NO_REPEAT);
|
|
211
|
+
bool shouldClip = clip && (objectFit == ObjectFit::COVER ||
|
|
212
|
+
objectFit == ObjectFit::NONE || isRepeating);
|
|
213
|
+
|
|
214
|
+
if (shouldClip) {
|
|
215
|
+
canvas->clipRect(SkRect::MakeWH(targetWidth, targetHeight));
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
SkRect dstBounds = SkRect::MakeWH(intrinsicWidth, intrinsicHeight);
|
|
219
|
+
|
|
220
|
+
if (!isRepeating) {
|
|
221
|
+
canvas->translate(tf.translateX, tf.translateY);
|
|
222
|
+
canvas->scale(tf.scaleX, tf.scaleY);
|
|
223
|
+
lottie->render(canvas, &dstBounds);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
float startX = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_X)
|
|
228
|
+
? computeCenteredTileStart(targetWidth, tileW)
|
|
229
|
+
: tf.translateX;
|
|
230
|
+
float startY = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_Y)
|
|
231
|
+
? computeCenteredTileStart(targetHeight, tileH)
|
|
232
|
+
: tf.translateY;
|
|
233
|
+
|
|
234
|
+
float endX = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_X)
|
|
235
|
+
? targetWidth
|
|
236
|
+
: (startX + tileW);
|
|
237
|
+
float endY = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_Y)
|
|
238
|
+
? targetHeight
|
|
239
|
+
: (startY + tileH);
|
|
240
|
+
|
|
241
|
+
for (float y = startY; y < endY; y += tileH) {
|
|
242
|
+
for (float x = startX; x < endX; x += tileW) {
|
|
243
|
+
SkAutoCanvasRestore tileRestore(canvas, true);
|
|
244
|
+
canvas->translate(x, y);
|
|
245
|
+
canvas->scale(tf.scaleX, tf.scaleY);
|
|
246
|
+
lottie->render(canvas, &dstBounds);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
30
249
|
}
|
|
31
250
|
|
|
32
251
|
void drawAsset(SkCanvas *canvas, double asset, float targetWidth,
|
|
33
|
-
float targetHeight, bool flipH, bool flipV,
|
|
252
|
+
float targetHeight, bool flipH, bool flipV, ObjectFit objectFit,
|
|
253
|
+
bool clip, Repeat repeat, double progress) {
|
|
254
|
+
if (asset == 0) {
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
|
|
34
258
|
SkAutoCanvasRestore restoreGuard(canvas, true);
|
|
35
259
|
|
|
36
260
|
if (flipH || flipV) {
|
|
@@ -39,10 +263,6 @@ void drawAsset(SkCanvas *canvas, double asset, float targetWidth,
|
|
|
39
263
|
canvas->translate(-targetWidth * 0.5f, -targetHeight * 0.5f);
|
|
40
264
|
}
|
|
41
265
|
|
|
42
|
-
if (asset == 0) {
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
266
|
auto &gameRenderer = GameRenderer::getInstance();
|
|
47
267
|
|
|
48
268
|
if (asset > 0) {
|
|
@@ -53,9 +273,11 @@ void drawAsset(SkCanvas *canvas, double asset, float targetWidth,
|
|
|
53
273
|
[&](const auto &image) {
|
|
54
274
|
using T = std::decay_t<decltype(image)>;
|
|
55
275
|
if constexpr (std::is_same_v<T, sk_sp<SkSVGDOM>>) {
|
|
56
|
-
drawSVG(canvas, image, targetWidth, targetHeight
|
|
276
|
+
drawSVG(canvas, image, targetWidth, targetHeight, objectFit, clip,
|
|
277
|
+
repeat);
|
|
57
278
|
} else {
|
|
58
|
-
drawRaster(canvas, image, targetWidth, targetHeight
|
|
279
|
+
drawRaster(canvas, image, targetWidth, targetHeight, objectFit,
|
|
280
|
+
clip, repeat);
|
|
59
281
|
}
|
|
60
282
|
},
|
|
61
283
|
imageIt->second);
|
|
@@ -66,9 +288,8 @@ void drawAsset(SkCanvas *canvas, double asset, float targetWidth,
|
|
|
66
288
|
auto &lottieCache = gameRenderer.getLottieCacheInternal();
|
|
67
289
|
auto lottieIt = lottieCache.find(asset);
|
|
68
290
|
if (lottieIt != lottieCache.end() && lottieIt->second) {
|
|
69
|
-
lottieIt->second
|
|
70
|
-
|
|
71
|
-
lottieIt->second->render(canvas, &dstBounds);
|
|
291
|
+
drawLottie(canvas, lottieIt->second, targetWidth, targetHeight, objectFit,
|
|
292
|
+
clip, repeat, progress);
|
|
72
293
|
}
|
|
73
294
|
}
|
|
74
295
|
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
#pragma once
|
|
2
|
+
#include "ObjectFit.hpp"
|
|
3
|
+
#include "Repeat.hpp"
|
|
2
4
|
#include "include/core/SkCanvas.h"
|
|
3
5
|
#include "modules/svg/include/SkSVGDOM.h"
|
|
4
6
|
|
|
5
7
|
namespace margelo::nitro::rngine::AssetUtils {
|
|
6
8
|
void drawAsset(SkCanvas *canvas, double asset, float targetWidth,
|
|
7
|
-
float targetHeight, bool flipH, bool flipV,
|
|
9
|
+
float targetHeight, bool flipH, bool flipV, ObjectFit objectFit,
|
|
10
|
+
bool clip, Repeat repeat, double progress);
|
|
8
11
|
void updateProgress(std::optional<double> &progress,
|
|
9
12
|
const std::optional<double> &speed,
|
|
10
13
|
const std::optional<bool> &loop, const double asset,
|
package/src/nativeTypes.ts
CHANGED
|
@@ -24,6 +24,10 @@ interface Shaped {
|
|
|
24
24
|
isSensor?: boolean;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
export type ObjectFit = 'fill' | 'contain' | 'cover' | 'none';
|
|
28
|
+
|
|
29
|
+
export type Repeat = 'no-repeat' | 'repeat' | 'repeat-x' | 'repeat-y';
|
|
30
|
+
|
|
27
31
|
interface Renderable {
|
|
28
32
|
/** Fill color as a hex string e.g. `'#00ff00'`. */
|
|
29
33
|
color?: string;
|
|
@@ -33,6 +37,12 @@ interface Renderable {
|
|
|
33
37
|
flipH?: boolean;
|
|
34
38
|
/** Whether to flip the rendered asset vertically. */
|
|
35
39
|
flipV?: boolean;
|
|
40
|
+
/** How the asset should be scaled to fit its target dimensions. Defaults to `'fill'`. */
|
|
41
|
+
objectFit?: ObjectFit;
|
|
42
|
+
/** Explicitly clips content that overflows the target dimensions. Defaults to `false`. */
|
|
43
|
+
clip?: boolean;
|
|
44
|
+
/** Repeating/tiling mode for the asset across target bounds. Defaults to `'no-repeat'`. */
|
|
45
|
+
repeat?: Repeat;
|
|
36
46
|
/** Animation progress between 0 and 1, automatically advanced each tick for Lottie assets. */
|
|
37
47
|
progress?: number;
|
|
38
48
|
/** Playback speed multiplier for Lottie assets (1 = normal speed). */
|