}mDrawArea;
};
+using MarkerList = std::vector<std::tuple<std::string, int , int>>;
+/**
+ * @brief https://helpx.adobe.com/after-effects/using/layer-markers-composition-markers.html
+ * Markers exported form AE are used to describe a segmnet of an animation {comment/tag , startFrame, endFrame}
+ * Marker can be use to devide a resource in to separate animations by tagging the segment with comment string ,
+ * start frame and duration of that segment.
+ */
+
using LayerInfoList = std::vector<std::tuple<std::string, int , int>>;
class LOT_EXPORT Animation {
*/
const LOTLayerNode * renderTree(size_t frameNo, size_t width, size_t height) const;
+ /**
+ * @brief Returns Composition Markers.
+ *
+ *
+ * @return returns MarkerList of the Composition.
+ *
+ * @see MarkerList
+ * @internal
+ */
+ const MarkerList& markers() const;
+
/**
* @brief Returns Layer information{name, inFrame, outFrame} of all the child layers of the composition.
*
{
return mModel->layerInfoList();
}
+ const MarkerList &markers() const
+ {
+ return mModel->markers();
+ }
void setValue(const std::string &keypath, LOTVariant &&value);
void removeFilter(const std::string &keypath, Property prop);
return d->layerInfoList();
}
+const MarkerList &Animation::markers() const
+{
+ return d->markers();
+}
+
void Animation::setValue(Color_Type, Property prop, const std::string &keypath,
Color value)
{
std::unique_ptr<ExtraLayerData> mExtra{nullptr};
};
-using LayerInfo = std::tuple<std::string, int , int>;
+using Marker = std::tuple<std::string, int , int>;
+using LayerInfo = Marker;
class LOTCompositionData : public LOTData
{
public:
LOTCompositionData():LOTData(LOTData::Type::Composition){}
const std::vector<LayerInfo> &layerInfoList() const { return mLayerInfoList;}
+ const std::vector<Marker> &markers() const { return mMarkers;}
double duration() const {
return frameDuration() / frameRate(); // in second
}
std::shared_ptr<LOTAsset>> mAssets;
std::vector<LayerInfo> mLayerInfoList;
+ std::vector<Marker> mMarkers;
LOTModelStat mStats;
};
size_t endFrame() const {return mRoot->endFrame();}
size_t frameAtPos(double pos) const {return mRoot->frameAtPos(pos);}
const std::vector<LayerInfo> &layerInfoList() const { return mRoot->layerInfoList();}
+ const std::vector<Marker> &markers() const { return mRoot->markers();}
public:
std::shared_ptr<LOTCompositionData> mRoot;
};
return mComposition;
}
void parseComposition();
+ void parseMarkers();
+ void parseMarker();
void parseAssets(LOTCompositionData *comp);
std::shared_ptr<LOTAsset> parseAsset();
void parseLayers(LOTCompositionData *comp);
parseAssets(comp);
} else if (0 == strcmp(key, "layers")) {
parseLayers(comp);
+ } else if (0 == strcmp(key, "markers")) {
+ parseMarkers();
} else {
#ifdef DEBUG_PARSER
vWarning << "Composition Attribute Skipped : " << key;
mComposition = sharedComposition;
}
+void LottieParserImpl::parseMarker()
+{
+ RAPIDJSON_ASSERT(PeekType() == kObjectType);
+ EnterObject();
+ std::string comment;
+ int timeframe{0};
+ int duration{0};
+ while (const char *key = NextObjectKey()) {
+ if (0 == strcmp(key, "cm")) {
+ RAPIDJSON_ASSERT(PeekType() == kStringType);
+ comment = std::string(GetString());
+ } else if (0 == strcmp(key, "tm")) {
+ RAPIDJSON_ASSERT(PeekType() == kNumberType);
+ timeframe = GetDouble();
+ } else if (0 == strcmp(key, "dr")) {
+ RAPIDJSON_ASSERT(PeekType() == kNumberType);
+ duration = GetDouble();
+
+ } else {
+#ifdef DEBUG_PARSER
+ vWarning << "Marker Attribute Skipped : " << key;
+#endif
+ Skip(key);
+ }
+ }
+ compRef->mMarkers.emplace_back(std::move(comment), timeframe, timeframe + duration);
+}
+
+void LottieParserImpl::parseMarkers()
+{
+ RAPIDJSON_ASSERT(PeekType() == kArrayType);
+ EnterArray();
+ while (NextArrayValue()) {
+ parseMarker();
+ }
+ // update the precomp layers with the actual layer object
+}
+
void LottieParserImpl::parseAssets(LOTCompositionData *composition)
{
RAPIDJSON_ASSERT(PeekType() == kArrayType);