lottie/expressions: support wiggle effect

usage: wiggle(freq, amp, octaves=1, amp_mult=.5, t=time)

issue: https://github.com/thorvg/thorvg/issues/1640
This commit is contained in:
Hermet Park 2025-03-27 22:27:17 +09:00 committed by Mira Grudzinska
parent 558a9991de
commit 96d4ab1590

View file

@ -68,6 +68,25 @@ static ExpContent* _expcontent(LottieExpression* exp, float frameNo, LottieObjec
} }
static float _rand()
{
return (float)(rand() % 10000001) * 0.0000001f;
}
static jerry_value_t _point2d(const Point& pt)
{
auto obj = jerry_object();
auto v1 = jerry_number(pt.x);
auto v2 = jerry_number(pt.y);
jerry_object_set_index(obj, 0, v1);
jerry_object_set_index(obj, 1, v2);
jerry_value_free(v1);
jerry_value_free(v2);
return obj;
}
static void contentFree(void *native_p, struct jerry_object_native_info_t *info_p) static void contentFree(void *native_p, struct jerry_object_native_info_t *info_p)
{ {
free(native_p); free(native_p);
@ -603,8 +622,7 @@ static jerry_value_t _length(const jerry_call_info_t* info, const jerry_value_t
static jerry_value_t _random(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) static jerry_value_t _random(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt)
{ {
auto val = (float)(rand() % 10000001); return jerry_number(_rand());
return jerry_number(val * 0.0000001f);
} }
@ -821,6 +839,32 @@ static jerry_value_t _speedAtTime(const jerry_call_info_t* info, const jerry_val
} }
static jerry_value_t _wiggle(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt)
{
auto data = static_cast<ExpContent*>(jerry_object_get_native_ptr(info->function, &freeCb));
auto freq = jerry_value_as_number(args[0]);
auto amp = jerry_value_as_number(args[1]);
auto octaves = (argsCnt > 2) ? jerry_value_as_int32(args[2]) : 1;
auto ampm = (argsCnt > 3) ? jerry_value_as_number(args[3]) : 5.0f;
auto time = (argsCnt > 4) ? jerry_value_as_number(args[4]) : data->exp->comp->timeAtFrame(data->frameNo);
Point result = {100.0f, 100.0f};
for (int o = 0; o < octaves; ++o) {
auto repeat = int(time * freq);
auto frac = (time * freq - float(repeat)) * 1.25f;
for (int i = 0; i < repeat; ++i) {
result.x += (_rand() * 2.0f - 1.0f) * amp * frac;
result.y += (_rand() * 2.0f - 1.0f) * amp * frac;
}
freq *= 2.0f;
amp *= ampm;
}
return _point2d(result);
}
static bool _loopOutCommon(LottieExpression* exp, const jerry_value_t args[], const jerry_length_t argsCnt) static bool _loopOutCommon(LottieExpression* exp, const jerry_value_t args[], const jerry_length_t argsCnt)
{ {
exp->loop.mode = LottieExpression::LoopMode::OutCycle; exp->loop.mode = LottieExpression::LoopMode::OutCycle;
@ -1044,7 +1088,11 @@ static void _buildProperty(float frameNo, jerry_value_t context, LottieExpressio
jerry_object_set_native_ptr(speedAtTime, nullptr, exp); jerry_object_set_native_ptr(speedAtTime, nullptr, exp);
jerry_value_free(speedAtTime); jerry_value_free(speedAtTime);
//wiggle(freq, amp, octaves=1, amp_mult=.5, t=time) auto wiggle = jerry_function_external(_wiggle);
jerry_object_set_sz(context, "wiggle", wiggle);
jerry_object_set_native_ptr(wiggle, &freeCb, _expcontent(exp, frameNo, exp->object));
jerry_value_free(wiggle);
//temporalWiggle(freq, amp, octaves=1, amp_mult=.5, t=time) //temporalWiggle(freq, amp, octaves=1, amp_mult=.5, t=time)
//smooth(width=.2, samples=5, t=time) //smooth(width=.2, samples=5, t=time)