实现通过json文件构造Painting
parent
b3bbf6c1be
commit
b6e79ee6de
|
@ -206,11 +206,11 @@ bool LayerStyleContainer::dropStyle(const QString& styleName)
|
||||||
|
|
||||||
float LayerStyleContainer::boundingBoxAffectValue() const {
|
float LayerStyleContainer::boundingBoxAffectValue() const {
|
||||||
float maxLineWidth = 0;
|
float maxLineWidth = 0;
|
||||||
const auto strokeStyle = styles.at(StrokeElementLayerStyle::displayName());
|
const auto strokeStyle = styles.find(StrokeElementLayerStyle::displayName());
|
||||||
if (strokeStyle != nullptr)
|
if (strokeStyle != styles.end())
|
||||||
{
|
{
|
||||||
if (const auto strokeElementLayerStyle =
|
if (const auto strokeElementLayerStyle =
|
||||||
std::dynamic_pointer_cast<StrokeElementLayerStyle>(strokeStyle);
|
std::dynamic_pointer_cast<StrokeElementLayerStyle>(strokeStyle->second);
|
||||||
strokeElementLayerStyle != nullptr)
|
strokeElementLayerStyle != nullptr)
|
||||||
{
|
{
|
||||||
const auto& leftStyleStroke = strokeElementLayerStyle->strokePair.first;
|
const auto& leftStyleStroke = strokeElementLayerStyle->strokePair.first;
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
using Renderer::Painting;
|
using Renderer::Painting;
|
||||||
using Renderer::Element;
|
using Renderer::BaseElement;
|
||||||
using Renderer::ElementTransform;
|
using Renderer::ElementTransform;
|
||||||
using glm::bvec2;
|
using glm::bvec2;
|
||||||
using std::max;
|
using std::max;
|
||||||
|
@ -17,161 +17,124 @@ using std::queue;
|
||||||
const double PaintingUtil::pi = acos(-1);
|
const double PaintingUtil::pi = acos(-1);
|
||||||
|
|
||||||
struct LayerNode {
|
struct LayerNode {
|
||||||
LayerWrapper* nowLayer;
|
LayerWrapper* nowLayer;
|
||||||
QTransform transfrom;
|
QTransform transfrom;
|
||||||
bvec2 flip;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
QJsonObject PaintingUtil::readJsonFile(QString jsonFilePath) {
|
QJsonObject PaintingUtil::readJsonFile(QString jsonFilePath) {
|
||||||
QFile jsonFile(jsonFilePath);
|
QFile jsonFile(jsonFilePath);
|
||||||
jsonFile.open(QFile::ReadOnly);
|
qDebug() << jsonFilePath;
|
||||||
QByteArray fileContent = jsonFile.readAll().trimmed();
|
jsonFile.open(QFile::ReadOnly);
|
||||||
jsonFile.close();
|
QByteArray fileContent = jsonFile.readAll().trimmed();
|
||||||
QJsonParseError jError;
|
jsonFile.close();
|
||||||
QJsonDocument jsonDoc(QJsonDocument::fromJson(fileContent, &jError));
|
QJsonParseError jError;
|
||||||
return jsonDoc.object();
|
QJsonDocument jsonDoc(QJsonDocument::fromJson(fileContent, &jError));
|
||||||
|
return jsonDoc.object();
|
||||||
}
|
}
|
||||||
|
|
||||||
Painting PaintingUtil::transfromToPainting(QString jsonFilePath) {
|
Painting PaintingUtil::transfromToPainting(QString jsonFilePath) {
|
||||||
Painting painting;
|
Painting painting;
|
||||||
glm::bvec2 flip(0, 0);
|
glm::bvec2 flip(0, 0);
|
||||||
QJsonObject jsonObj = readJsonFile(jsonFilePath);
|
QJsonObject jsonObj = readJsonFile(jsonFilePath);
|
||||||
qDebug() << jsonObj;
|
qDebug() << jsonObj;
|
||||||
shared_ptr<ElementManager> elementManager = make_shared<ElementManager>(jsonObj, Renderer::ElementRenderer::instance());
|
shared_ptr<ElementManager> elementManager = make_shared<ElementManager>(jsonObj, Renderer::ElementRenderer::instance());
|
||||||
shared_ptr<LayerManager> layerManager = make_shared<LayerManager>(jsonObj, elementManager.get());
|
shared_ptr<LayerManager> layerManager = make_shared<LayerManager>(jsonObj, elementManager.get());
|
||||||
//qDebug() << elementManager->toJson();
|
//qDebug() << elementManager->toJson();
|
||||||
//qDebug() << layerManager->toJson();
|
//qDebug() << layerManager->toJson();
|
||||||
//qDebug() << ((SimpleElement*)((LeafLayerWrapper*)((FolderLayerWrapper*)((FolderLayerWrapper*)layerManager->getRoot())->children[0].get())->children[0].get())->wrappedElement)->painterPath;
|
//qDebug() << ((SimpleElement*)((LeafLayerWrapper*)((FolderLayerWrapper*)((FolderLayerWrapper*)layerManager->getRoot())->children[0].get())->children[0].get())->wrappedElement)->painterPath;
|
||||||
//qDebug() << ((LeafLayerWrapper*)((FolderLayerWrapper*)((FolderLayerWrapper*)layerManager->getRoot())->children[0].get())->children[0].get())->getCache().painterPath;
|
//qDebug() << ((LeafLayerWrapper*)((FolderLayerWrapper*)((FolderLayerWrapper*)layerManager->getRoot())->children[0].get())->children[0].get())->getCache().painterPath;
|
||||||
queue<LayerNode> layerQueue;
|
//qDebug() << elementManager->toJson();
|
||||||
LayerWrapper* root = layerManager->getRoot();
|
//qDebug() << layerManager->toJson();
|
||||||
root->getCache();
|
//qDebug() << ((SimpleElement*)((LeafLayerWrapper*)((FolderLayerWrapper*)((FolderLayerWrapper*)layerManager->getRoot())->children[0].get())->children[0].get())->wrappedElement)->painterPath;
|
||||||
layerQueue.push({ root, root->property.transform, flip });
|
//qDebug() << ((LeafLayerWrapper*)((FolderLayerWrapper*)((FolderLayerWrapper*)layerManager->getRoot())->children[0].get())->children[0].get())->getCache().painterPath;
|
||||||
while (!layerQueue.empty()) {
|
queue<LayerNode> layerQueue;
|
||||||
auto layerNode = layerQueue.front();
|
LayerWrapper* root = layerManager->getRoot();
|
||||||
layerQueue.pop();
|
root->getCache();
|
||||||
FolderLayerWrapper* nowLayer = handleLayerWrapper(layerNode.nowLayer, layerNode.transfrom, layerNode.flip, painting);
|
//double maxLineWidth = getMaxLineWidth(root);
|
||||||
if (nowLayer != nullptr) {
|
layerQueue.push({ root, root->property.transform });
|
||||||
for (auto sonLayer : nowLayer->children) {
|
while (!layerQueue.empty()) {
|
||||||
layerQueue.push({ sonLayer.get(), layerNode.transfrom, layerNode.flip});
|
auto layerNode = layerQueue.front();
|
||||||
}
|
layerQueue.pop();
|
||||||
}
|
FolderLayerWrapper* nowLayer = handleLayerWrapper(layerNode.nowLayer, layerNode.transfrom, painting);
|
||||||
}
|
if (nowLayer != nullptr) {
|
||||||
|
for (auto sonLayer : nowLayer->children) {
|
||||||
return painting;
|
layerQueue.push({ sonLayer.get(), layerNode.transfrom });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return painting;
|
||||||
}
|
}
|
||||||
|
|
||||||
FolderLayerWrapper* PaintingUtil::handleLayerWrapper(LayerWrapper* nowLayer, QTransform& transform, bvec2& flip, Painting& painting) {
|
FolderLayerWrapper* PaintingUtil::handleLayerWrapper(LayerWrapper* nowLayer, QTransform& transform, Painting& painting) {
|
||||||
LeafLayerWrapper* leafLayer = dynamic_cast<LeafLayerWrapper*>(nowLayer);
|
LeafLayerWrapper* leafLayer = dynamic_cast<LeafLayerWrapper*>(nowLayer);
|
||||||
flip ^= bvec2(nowLayer->property.flipHorizontally, nowLayer->property.flipVertically);
|
|
||||||
|
|
||||||
transform = nowLayer->property.transform * transform;
|
transform = nowLayer->property.transform * transform;
|
||||||
|
|
||||||
if (leafLayer != nullptr) {
|
if (leafLayer != nullptr) {
|
||||||
|
|
||||||
GroupElement* wrapperElement = dynamic_cast<GroupElement*>(leafLayer->wrappedElement);
|
GroupElement* wrapperElement = dynamic_cast<GroupElement*>(leafLayer->wrappedElement);
|
||||||
if (wrapperElement != nullptr) {
|
if (wrapperElement != nullptr) {
|
||||||
transform = wrapperElement->sourceLayer->property.transform * transform;
|
transform = wrapperElement->sourceLayer->property.transform * transform;
|
||||||
return wrapperElement->sourceLayer;
|
return wrapperElement->sourceLayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
PixelPath pixelPath = nowLayer->getCache();
|
PixelPath pixelPath = nowLayer->getCache();
|
||||||
QPainterPath painterPath = pixelPath.getPainterPath();
|
QPainterPath painterPath = pixelPath.getPainterPath();
|
||||||
QRectF bound = painterPath.boundingRect();
|
QRectF bound = painterPath.boundingRect();
|
||||||
//qDebug() << leafLayer<<"------" << painterPath;
|
//qDebug() << leafLayer<<"------" << painterPath;
|
||||||
//qDebug() << transform;
|
//qDebug() << transform;
|
||||||
Element element;
|
// transform to initial painterPath
|
||||||
ElementTransform elementTrans;
|
// transfrom to -1£¬ 1
|
||||||
element.ratio = bound.width() / bound.height();
|
QTransform trans;
|
||||||
// transform to initial painterPath
|
double maxLen = std::max(bound.width(), bound.height());
|
||||||
// transfrom to -1£¬ 1
|
qDebug() << maxLen << bound;
|
||||||
QTransform trans;
|
trans.scale(1 / maxLen, 1 / maxLen);
|
||||||
trans.scale(1 / bound.width(), 1 / bound.height());
|
trans.translate(-bound.center().x(), -bound.center().y());
|
||||||
trans.translate(-bound.center().x(), -bound.center().y());
|
|
||||||
|
|
||||||
qDebug() << trans.map(painterPath);
|
|
||||||
element.contour = std::make_shared<vector<vector<Renderer::Point> >>(PainterPathUtil::transformToLines(trans.map(painterPath)));
|
|
||||||
QSize screenSize = QSize(1024, 1024);
|
|
||||||
element.style = std::make_shared<Renderer::ElementStyleStrokeDemo>(0.06);
|
|
||||||
|
|
||||||
|
|
||||||
painterPath = transform.map(painterPath);
|
|
||||||
qDebug() << painterPath;
|
|
||||||
bound = painterPath.boundingRect();
|
|
||||||
qDebug() << bound;
|
|
||||||
|
|
||||||
// TODO ¸ÄÓþØÕó
|
painterPath = trans.map(painterPath);
|
||||||
|
shared_ptr<vector<vector<Renderer::Point> >> contour = std::make_shared<vector<vector<Renderer::Point> >>(PainterPathUtil::transformToLines(painterPath));
|
||||||
|
QSize screenSize = QSize(1024, 1024);
|
||||||
|
|
||||||
/* elementTrans.center = glm::vec2(
|
ElementTransform elementTransform;
|
||||||
(2 * bound.center().x() - screenSize.width()) / screenSize.width(),
|
transform = trans.inverted() * transform * QTransform::fromScale(2. / screenSize.width(), 2. / screenSize.height()) * QTransform::fromTranslate(-1, -1) * QTransform::fromScale(1, -1);
|
||||||
(2 * bound.center().y() - screenSize.height()) / screenSize.height()
|
|
||||||
);
|
auto baseStyles = leafLayer->styles.toBaseStyles();
|
||||||
qDebug() << elementTrans.center.x << elementTrans.center.y;
|
Renderer::BaseElement element;
|
||||||
decomposeTransform(transform, elementTrans.rotation, elementTrans.scale);
|
element.contour = contour;
|
||||||
elementTrans.scale = glm::vec2(
|
for (auto baseStyle : baseStyles) {
|
||||||
bound.width() * 2 / screenSize.width(),
|
double lineWidth = 0;
|
||||||
bound.height() * 2 / screenSize.height()
|
if (baseStyle.material->type() == Renderer::MaterialStyleType::kStroke) {
|
||||||
);
|
auto material = dynamic_cast<MaterialStyleStroke*>(baseStyle.material.get());
|
||||||
elementTrans.flip = glm::bvec2(
|
material->halfWidth = material->halfWidth / maxLen;
|
||||||
nowLayer->property.flipHorizontally,
|
lineWidth = material->halfWidth;
|
||||||
nowLayer->property.flipVertically
|
qDebug() << material->halfWidth;
|
||||||
);
|
}
|
||||||
qDebug() << elementTrans.scale.x << elementTrans.scale.y;
|
QRectF rect = painterPath.boundingRect();
|
||||||
painting.addElement(element, elementTrans);*/
|
rect.setX(-lineWidth + rect.x());
|
||||||
return nullptr;
|
rect.setY(-lineWidth + rect.y());
|
||||||
}
|
rect.setWidth(lineWidth * 2 + rect.width());
|
||||||
|
rect.setHeight(lineWidth * 2 + rect.height());
|
||||||
FolderLayerWrapper* folderLayer = dynamic_cast<FolderLayerWrapper*>(nowLayer);
|
QPainterPath path;
|
||||||
return folderLayer;
|
path.addRect(rect);
|
||||||
}
|
rect = transform.map(path).boundingRect();
|
||||||
void PaintingUtil::decomposeTransform(QTransform trans, float& angle, glm::vec2& scale) {
|
elementTransform.bound = glm::vec4(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height());
|
||||||
//qDebug() << trans;
|
qDebug() << elementTransform.bound.x << elementTransform.bound.y << elementTransform.bound.z << elementTransform.bound.z;
|
||||||
trans.setMatrix(
|
transform = transform.inverted();
|
||||||
trans.m11(), trans.m12(), trans.m13(),
|
elementTransform.transform = glm::mat3x2(
|
||||||
trans.m21(), trans.m22(), trans.m23(),
|
transform.m11(), transform.m12(), transform.m21(),
|
||||||
0, 0, 1);
|
transform.m22(), transform.m31(), transform.m32()
|
||||||
//qDebug() << trans.dx() << trans.dy();
|
);
|
||||||
int count = 0;
|
qDebug() << transform;
|
||||||
double norm = 0, n = 0;
|
elementTransform.zIndex = 0;
|
||||||
QTransform R = trans, Rit, Rnext;
|
|
||||||
do {
|
element.style = baseStyle.material;
|
||||||
++count;
|
painting.addElement(element, elementTransform);
|
||||||
Rit = R.transposed().inverted();
|
}
|
||||||
Rnext.setMatrix(
|
|
||||||
(R.m11() + Rit.m11()) / 2,
|
return nullptr;
|
||||||
(R.m12() + Rit.m12()) / 2,
|
}
|
||||||
(R.m13() + Rit.m13()) / 2,
|
|
||||||
(R.m21() + Rit.m21()) / 2,
|
FolderLayerWrapper* folderLayer = dynamic_cast<FolderLayerWrapper*>(nowLayer);
|
||||||
(R.m22() + Rit.m22()) / 2,
|
return folderLayer;
|
||||||
(R.m23() + Rit.m23()) / 2,
|
|
||||||
(R.m31() + Rit.m31()) / 2,
|
|
||||||
(R.m32() + Rit.m32()) / 2,
|
|
||||||
(R.m33() + Rit.m33()) / 2
|
|
||||||
);
|
|
||||||
norm = 0;
|
|
||||||
norm = max(norm,
|
|
||||||
fabs(R.m11() - Rnext.m11())
|
|
||||||
+ fabs(R.m12() - Rnext.m12())
|
|
||||||
+ fabs(R.m13() - Rnext.m13()));
|
|
||||||
norm = max(norm,
|
|
||||||
fabs(R.m21() - Rnext.m21())
|
|
||||||
+ fabs(R.m22() - Rnext.m22())
|
|
||||||
+ fabs(R.m23() - Rnext.m23()));
|
|
||||||
norm = max(norm,
|
|
||||||
fabs(R.m31() - Rnext.m31())
|
|
||||||
+ fabs(R.m32() - Rnext.m32())
|
|
||||||
+ fabs(R.m33() - Rnext.m33()));
|
|
||||||
R = Rnext;
|
|
||||||
} while (count < 100 && norm > 0.0001);
|
|
||||||
double cosValue = max(-1.0, min(R.m11(), 1.0));
|
|
||||||
double sinValue = max(-1.0, min(R.m12(), 1.0));
|
|
||||||
angle = acos(cosValue) * 180 / pi;
|
|
||||||
if (sinValue < 0) {
|
|
||||||
angle = 360 - angle;
|
|
||||||
}
|
|
||||||
qDebug() << angle;
|
|
||||||
//R = R.inverted() * trans;
|
|
||||||
//scale = glm::vec2(R.m11(), R.m22());
|
|
||||||
//qDebug() << scale.x << scale.y;
|
|
||||||
return;
|
|
||||||
}
|
}
|
|
@ -7,10 +7,9 @@ class PaintingUtil
|
||||||
private:
|
private:
|
||||||
static const double pi;
|
static const double pi;
|
||||||
static QJsonObject readJsonFile(QString jsonFilePath);
|
static QJsonObject readJsonFile(QString jsonFilePath);
|
||||||
static FolderLayerWrapper* handleLayerWrapper(LayerWrapper* nowLayer, QTransform& transform, glm::bvec2& flip, Renderer::Painting& painting);
|
static FolderLayerWrapper* handleLayerWrapper(LayerWrapper* nowLayer, QTransform& transform, Renderer::Painting& painting);
|
||||||
public:
|
//static double getMaxLineWidth(LayerWrapper* root);
|
||||||
|
public:
|
||||||
static Renderer::Painting transfromToPainting(QString jsonFilePath);
|
static Renderer::Painting transfromToPainting(QString jsonFilePath);
|
||||||
static void decomposeTransform(QTransform trans, float& angle, glm::vec2& scale);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -21,4 +21,9 @@ void ::FluentMenu::paintEvent(QPaintEvent* event)
|
||||||
painter.drawRoundedRect(QRectF(shadowRadius - i, shadowRadius - i, width() - (shadowRadius - i) * 2, height() - (shadowRadius - i) * 2), borderRadius + i, borderRadius + i);
|
painter.drawRoundedRect(QRectF(shadowRadius - i, shadowRadius - i, width() - (shadowRadius - i) * 2, height() - (shadowRadius - i) * 2), borderRadius + i, borderRadius + i);
|
||||||
}
|
}
|
||||||
QMenu::paintEvent(event);
|
QMenu::paintEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QAction* FluentMenu::exec(const QPoint& pos, QAction* at)
|
||||||
|
{
|
||||||
|
return QMenu::exec(parentWidget()->mapToGlobal(parentWidget()->mapFromGlobal(pos) + QPoint(-shadowRadius, -shadowRadius)), at);
|
||||||
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ class FluentMenu : public QMenu
|
||||||
public:
|
public:
|
||||||
explicit FluentMenu(QWidget* parent = nullptr);
|
explicit FluentMenu(QWidget* parent = nullptr);
|
||||||
void paintEvent(QPaintEvent* event) override;
|
void paintEvent(QPaintEvent* event) override;
|
||||||
|
QAction* exec(const QPoint& pos, QAction* at = nullptr);
|
||||||
int shadowRadius = 16;
|
int shadowRadius = 16;
|
||||||
int borderRadius = 6;
|
int borderRadius = 6;
|
||||||
int itemBorderRadius = 4;
|
int itemBorderRadius = 4;
|
||||||
|
|
|
@ -244,8 +244,9 @@ GLuint Renderer::Model::loadPainting(std::string path)
|
||||||
return iter->second;
|
return iter->second;
|
||||||
|
|
||||||
Painting painting;
|
Painting painting;
|
||||||
|
path = "../test.json";
|
||||||
if (auto file = QFileInfo(QString(path.c_str())); file.isFile())
|
if (auto file = QFileInfo(QString(path.c_str())); file.isFile())
|
||||||
painting = PaintingUtil::transfromToPainting(file.path());
|
painting = PaintingUtil::transfromToPainting(file.filePath());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qDebug() << path.c_str() << "Not Found, Using Default Painting";
|
qDebug() << path.c_str() << "Not Found, Using Default Painting";
|
||||||
|
|
|
@ -20,12 +20,12 @@ QVector4D BvhTree::Union(QVector4D a, QVector4D b) {
|
||||||
|
|
||||||
QVector4D BvhTree::merge(BvhPtr lp, BvhPtr rp) {
|
QVector4D BvhTree::merge(BvhPtr lp, BvhPtr rp) {
|
||||||
QVector4D a = lp->bound, b = rp->bound;
|
QVector4D a = lp->bound, b = rp->bound;
|
||||||
if (lp->isLeaf) {
|
/*if (lp->isLeaf) {
|
||||||
a = BvhTreeData::boundWithRotation(a, lp->getRightSon());
|
a = BvhTreeData::boundWithRotation(a, lp->getRightSon());
|
||||||
}
|
}
|
||||||
if (rp->isLeaf) {
|
if (rp->isLeaf) {
|
||||||
b = BvhTreeData::boundWithRotation(b, rp->getRightSon());
|
b = BvhTreeData::boundWithRotation(b, rp->getRightSon());
|
||||||
}
|
}*/
|
||||||
return Union(a, b);
|
return Union(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ Renderer::RendererWidget::RendererWidget(QWidget* parent)
|
||||||
ui.openButton->setChecked(false);
|
ui.openButton->setChecked(false);
|
||||||
});
|
});
|
||||||
QObject::connect(ui.openButton, &QPushButton::clicked, [&, menu]() {
|
QObject::connect(ui.openButton, &QPushButton::clicked, [&, menu]() {
|
||||||
menu->exec(ui.openButton->mapToGlobal(QPoint(-menu->shadowRadius, ui.openButton->height() - menu->shadowRadius)));
|
menu->exec(ui.openButton->mapToGlobal(QPoint(0, ui.openButton->height())));
|
||||||
});
|
});
|
||||||
|
|
||||||
QObject::connect(ui.horizontalSlider, &QSlider::valueChanged,
|
QObject::connect(ui.horizontalSlider, &QSlider::valueChanged,
|
||||||
|
|
|
@ -0,0 +1,131 @@
|
||||||
|
{
|
||||||
|
"background-color": "#ffffff",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"include": "../svg/2.svg"
|
||||||
|
},
|
||||||
|
"name": "ababa",
|
||||||
|
"type": "svg-file"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"reference-layer": "0.0"
|
||||||
|
},
|
||||||
|
"name": "ababa-group",
|
||||||
|
"type": "group"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"include": "../svg/0.svg"
|
||||||
|
},
|
||||||
|
"name": "ababa2",
|
||||||
|
"type": "svg-file"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"height": 1080,
|
||||||
|
"project-name": "样例1",
|
||||||
|
"root-layer": {
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"element": 0,
|
||||||
|
"is-folder": false,
|
||||||
|
"name": "Leaf1",
|
||||||
|
"styles": [
|
||||||
|
{
|
||||||
|
"enableEachSideIndependent": false,
|
||||||
|
"left": "AAAAQAEAIZwAf///qqr//w==",
|
||||||
|
"right": "AADgQAAACJw=",
|
||||||
|
"type": "stroke"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"transform": {
|
||||||
|
"offset": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"rotation": 0,
|
||||||
|
"scale": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"element": 0,
|
||||||
|
"is-folder": false,
|
||||||
|
"name": "Leaf2",
|
||||||
|
"styles": [
|
||||||
|
{
|
||||||
|
"enableEachSideIndependent": false,
|
||||||
|
"left": "AAAAQAEAIZwAf////1UA/w==",
|
||||||
|
"right": "AADgQAAACJw=",
|
||||||
|
"type": "stroke"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"transform": {
|
||||||
|
"offset": {
|
||||||
|
"x": 150,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"rotation": 0,
|
||||||
|
"scale": {
|
||||||
|
"x": 1.5,
|
||||||
|
"y": 1.5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"is-folder": true,
|
||||||
|
"name": "GroupFolderExample",
|
||||||
|
"referenced-by": 1,
|
||||||
|
"transform": {
|
||||||
|
"offset": {
|
||||||
|
"x": 50,
|
||||||
|
"y": 50
|
||||||
|
},
|
||||||
|
"rotation": 0,
|
||||||
|
"scale": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"element": 1,
|
||||||
|
"is-folder": false,
|
||||||
|
"name": "ReferencingGroupLayer",
|
||||||
|
"styles": [
|
||||||
|
],
|
||||||
|
"transform": {
|
||||||
|
"offset": {
|
||||||
|
"x": 100,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"rotation": 45,
|
||||||
|
"scale": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"is-folder": true,
|
||||||
|
"name": "root",
|
||||||
|
"referenced-by": null,
|
||||||
|
"transform": {
|
||||||
|
"offset": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"rotation": 0,
|
||||||
|
"scale": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"width": 1080
|
||||||
|
}
|
Loading…
Reference in New Issue