add interpolation
This commit is contained in:
@@ -94,6 +94,9 @@ module.exports = {
|
||||
"min": 0,
|
||||
"max": 1
|
||||
}
|
||||
},
|
||||
"style.night": {
|
||||
"fill-color": "blue"
|
||||
}
|
||||
}, {
|
||||
"id": "borders",
|
||||
|
||||
@@ -34,6 +34,10 @@ public:
|
||||
void add(ClassID class_id, timestamp begin, timestamp end, const PropertyValue &value) {
|
||||
properties.emplace_back(class_id, begin, end, value);
|
||||
}
|
||||
|
||||
bool hasTransitions() const {
|
||||
return properties.size() > 1;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -43,6 +43,8 @@ public:
|
||||
// of applied classes.
|
||||
void updateClasses();
|
||||
|
||||
bool hasTransitions() const;
|
||||
|
||||
public:
|
||||
std::shared_ptr<Sprite> sprite;
|
||||
std::shared_ptr<StyleLayerGroup> layers;
|
||||
|
||||
@@ -42,6 +42,8 @@ public:
|
||||
void setClasses(const std::vector<std::string> &class_names, timestamp now,
|
||||
const PropertyTransition &defaultTransition);
|
||||
|
||||
bool hasTransitions() const;
|
||||
|
||||
private:
|
||||
// Applies all properties from a class, if they haven't been applied already.
|
||||
void applyClassProperties(ClassID class_id, std::set<PropertyKey> &already_applied,
|
||||
|
||||
@@ -13,6 +13,7 @@ public:
|
||||
const PropertyTransition &defaultTransition);
|
||||
void updateProperties(float z, timestamp t);
|
||||
|
||||
bool hasTransitions() const;
|
||||
public:
|
||||
std::vector<std::shared_ptr<StyleLayer>> layers;
|
||||
};
|
||||
|
||||
@@ -495,7 +495,7 @@ void Map::render() {
|
||||
#endif
|
||||
|
||||
// Schedule another rerender when we definitely need a next frame.
|
||||
if (transform.needsTransition()) {
|
||||
if (transform.needsTransition() || style->hasTransitions()) {
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <llmr/style/style_parser.hpp>
|
||||
#include <llmr/style/style_bucket.hpp>
|
||||
#include <llmr/util/constants.hpp>
|
||||
#include <llmr/util/time.hpp>
|
||||
#include <csscolorparser/csscolorparser.hpp>
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
@@ -55,7 +56,7 @@ void Style::updateProperties(float z, timestamp t) {
|
||||
}
|
||||
|
||||
void Style::setDefaultTransitionDuration(uint16_t duration_milliseconds) {
|
||||
defaultTransition.duration = duration_milliseconds;
|
||||
defaultTransition.duration = duration_milliseconds * 1_millisecond;
|
||||
}
|
||||
|
||||
const std::vector<std::string> &Style::getAppliedClasses() const {
|
||||
@@ -81,6 +82,16 @@ void Style::updateClasses() {
|
||||
}
|
||||
}
|
||||
|
||||
bool Style::hasTransitions() const {
|
||||
if (layers) {
|
||||
if (layers->hasTransitions()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Style::loadJSON(const uint8_t *const data) {
|
||||
uv::writelock lock(mtx);
|
||||
|
||||
|
||||
@@ -181,6 +181,25 @@ private:
|
||||
const float z;
|
||||
};
|
||||
|
||||
inline float interpolate(const float a, const float b, const float t) {
|
||||
return (1.0f - t) * a + t * b;
|
||||
}
|
||||
|
||||
inline Color interpolate(const Color &a, const Color &b, const float t) {
|
||||
const float rt = 1.0f - t;
|
||||
return Color {{
|
||||
rt * a[0] + t * b[0],
|
||||
rt * a[1] + t * b[1],
|
||||
rt * a[2] + t * b[2],
|
||||
rt * a[3] + t * b[3]
|
||||
}};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T interpolate(const T a, const T b, const float t) {
|
||||
return t >= 0.5 ? b : a;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void StyleLayer::applyStyleProperty(PropertyKey key, T &target, const float z, const timestamp t) {
|
||||
auto it = appliedStyle.find(key);
|
||||
@@ -189,15 +208,15 @@ void StyleLayer::applyStyleProperty(PropertyKey key, T &target, const float z, c
|
||||
// Iterate through all properties that we need to apply in order.
|
||||
const PropertyEvaluator<T> evaluator(z);
|
||||
for (AppliedClassProperty &property : applied.properties) {
|
||||
if (property.end >= t) {
|
||||
if (t >= property.end) {
|
||||
// We overwrite the current property with the new value.
|
||||
target = util::apply_visitor(evaluator, property.value);
|
||||
} else if (property.begin <= t) {
|
||||
} else if (t >= property.begin) {
|
||||
// We overwrite the current property partially with the new value.
|
||||
float progress = float(t - property.begin) / float(property.end - property.begin);
|
||||
target = util::apply_visitor(evaluator, property.value);
|
||||
// target = (1.0f - progress) * target + (progress) *
|
||||
// evaluateProperty(property.value, target, z);
|
||||
target = interpolate(target, util::apply_visitor(evaluator, property.value), progress);
|
||||
} else {
|
||||
// Do not apply this property because its transition hasn't begun yet.
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -268,5 +287,13 @@ void StyleLayer::updateProperties(float z, const timestamp t) {
|
||||
}
|
||||
}
|
||||
|
||||
bool StyleLayer::hasTransitions() const {
|
||||
for (const std::pair<PropertyKey, AppliedClassProperties> &pair : appliedStyle) {
|
||||
if (pair.second.hasTransitions()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
#include <llmr/style/style_layer_group.hpp>
|
||||
|
||||
namespace llmr {
|
||||
@@ -19,4 +20,16 @@ void StyleLayerGroup::updateProperties(float z, timestamp t) {
|
||||
}
|
||||
}
|
||||
|
||||
bool StyleLayerGroup::hasTransitions() const {
|
||||
for (const std::shared_ptr<const StyleLayer> &layer: layers) {
|
||||
if (layer) {
|
||||
if (layer->hasTransitions()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user