Поиск шаблона или формулы для преобразования точек пути формы Sketch (формат json) в путь svg

Я пытаюсь найти шаблон для преобразования точек формы эскиза (формат json) в путь svg, поскольку мы знаем, что файлы эскизов - это просто zip-файлы, распаковав, вы получите файлы json. вот примеры кодов json

{
    "_class": "triangle",
    "do_objectID": "BE50CDBE-491C-4402-98EA-71E9C7B9F61B",
    "booleanOperation": -1,
    "frame": {
        "_class": "rect",
        "do_objectID": "0B39EF6D-9AD4-409B-85FA-D09B2B8A0692",
        "constrainProportions": false,
        "height": 56.86153846153846,
        "width": 66,
        "x": 0,
        "y": 0
    },
    "isFixedToViewport": false,
    "isFlippedHorizontal": false,
    "isFlippedVertical": false,
    "isLocked": false,
    "isVisible": true,
    "layerListExpandedType": 1,
    "name": "Triangle",
    "nameIsFixed": false,
    "resizingConstraint": 63,
    "resizingType": 0,
    "rotation": 0,
    "shouldBreakMaskChain": false,
    "userInfo": {
        "com.animaapp.stc-sketch-plugin": {
            "kModelPropertiesKey": {}
        }
    },
    "clippingMaskMode": 0,
    "hasClippingMask": false,
    "edited": false,
    "isClosed": true,
    "pointRadiusBehaviour": 1,
    "points": [
        {
            "_class": "curvePoint",
            "cornerRadius": 0,
            "curveFrom": "{0.49999999999999944, 0}",
            "curveMode": 1,
            "curveTo": "{0.49999999999999944, 0}",
            "hasCurveFrom": false,
            "hasCurveTo": false,
            "point": "{0.49999999999999944, 0}"
        },
        {
            "_class": "curvePoint",
            "cornerRadius": 0,
            "curveFrom": "{0.99999999999999889, 1}",
            "curveMode": 1,
            "curveTo": "{0.99999999999999889, 1}",
            "hasCurveFrom": false,
            "hasCurveTo": false,
            "point": "{0.99999999999999889, 1}"
        },
        {
            "_class": "curvePoint",
            "cornerRadius": 0,
            "curveFrom": "{0, 1}",
            "curveMode": 1,
            "curveTo": "{0, 1}",
            "hasCurveFrom": false,
            "hasCurveTo": false,
            "point": "{0, 1}"
        }
    ],
    "isEquilateral": false
}

это дает треугольник с его кодом пути svg

<polygon id="Triangle" points="33 0 66 56.8615385 0 56.8615385"></polygon>

насколько я понимаю, getting 33(x value) делается следующим образом, поскольку начало координат выше находится в 0,0 (frame->x, frame->y), я думал, что для получения его фактического положения нужно взять frame->width (поскольку ширина соответствует оси x), что равно 66 times first x point in points, which is 0.49999999999999944, в результате получается (32.99999999 approx 33), и first y point принимает frame->height(56.86153846153846 times the first y point in points which is 0) в результате до первой точки будет 33 0

вторая точка такая же, чтобы получить x, требуется frame->width(66) раз second x point in points which is 0.99999999, в результате чего получается 66, то же самое с его corresponding y (56.86153846153846 times 1) which is 56.86153846153846, в результате чего вторая точка будет 66 56.86153846153846, то же самое происходит с третьей точкой..

Начинает путаться, если числа frame->x и frame->y больше 0

учти это..

{
    "_class": "triangle",
    "do_objectID": "BB3FB5DE-F0A8-4AAD-8009-14F908023F19",
    "booleanOperation": -1,
    "frame": {
        "_class": "rect",
        "do_objectID": "316A9A7C-D0BF-4D71-BC65-1A0301846F20",
        "constrainProportions": true,
        "height": 32.49230769230769,
        "width": 37.56923076923076,
        "x": 14.21538461538461,
        "y": 22.33846153846153
    },
    "isFixedToViewport": false,
    "isFlippedHorizontal": false,
    "isFlippedVertical": false,
    "isLocked": false,
    "isVisible": true,
    "layerListExpandedType": 1,
    "name": "Triangle",
    "nameIsFixed": false,
    "resizingConstraint": 63,
    "resizingType": 0,
    "rotation": -180,
    "shouldBreakMaskChain": false,
    "userInfo": {
        "com.animaapp.stc-sketch-plugin": {
            "kModelPropertiesKey": {
                "constraints": {
                    "scaleFactor": 1,
                    "model_version": 0.1,
                    "aspectRatio": {
                        "multiplier": 37.56923,
                        "enabled": 1,
                        "model_version": 0.1,
                        "modelID": "constraint_dd3b6146-988c-411d-94e1-cb5ec2a60bc8",
                        "model_class": "ADModelConstraint",
                        "constant": 32.49231
                    },
                    "modelID": "viewConstraints_7f13ceae-6706-4965-b3af-3cde627fd97c",
                    "model_class": "ADModelViewConstraints",
                    "automatic": 1
                }
            }
        }
    },
    "clippingMaskMode": 0,
    "hasClippingMask": false,
    "edited": false,
    "isClosed": true,
    "pointRadiusBehaviour": 1,
    "points": [
        {
            "_class": "curvePoint",
            "cornerRadius": 0,
            "curveFrom": "{0.4999999999999995, 0}",
            "curveMode": 1,
            "curveTo": "{0.4999999999999995, 0}",
            "hasCurveFrom": false,
            "hasCurveTo": false,
            "point": "{0.4999999999999995, 0}"
        },
        {
            "_class": "curvePoint",
            "cornerRadius": 0,
            "curveFrom": "{0.999999999999999, 1.0000000000000009}",
            "curveMode": 1,
            "curveTo": "{0.999999999999999, 1.0000000000000009}",
            "hasCurveFrom": false,
            "hasCurveTo": false,
            "point": "{0.999999999999999, 1.0000000000000009}"
        },
        {
            "_class": "curvePoint",
            "cornerRadius": 0,
            "curveFrom": "{0, 1.0000000000000009}",
            "curveMode": 1,
            "curveTo": "{0, 1.0000000000000009}",
            "hasCurveFrom": false,
            "hasCurveTo": false,
            "point": "{0, 1.0000000000000009}"
        }
    ],
    "isEquilateral": false
}

его соответствующий путь svg

<polygon id="Triangle" transform="translate(33.000000, 38.584615) rotate(180.000000) translate(-33.000000, -38.584615) " points="33 22.3384615 51.7846154 54.8307692 14.2153846 54.8307692"></polygon>

Теперь, если я сделаю свою математику, как указано выше, я не получу points="33 22.3384615 51.7846154 54.8307692 14.2153846 54.8307692", как показано выше в коде svg. Это только для треугольника, если это пользовательский контур формы, такой как значок facebook, это сильно сбивает с толку! Образец эскиза логотипа,

Эскиз значка Facebook

соответствующий код Sketch json выглядит следующим образом.

{
    "_class": "group",
    "do_objectID": "4AA67C64-14B8-433F-8569-9BF7BAEC2914",
    "booleanOperation": -1,
    "frame": {
        "_class": "rect",
        "do_objectID": "1FB80667-369B-4F79-9D8E-76ABD9065B12",
        "constrainProportions": true,
        "height": 50,
        "width": 50,
        "x": 0,
        "y": 0
    },
    "isFixedToViewport": false,
    "isFlippedHorizontal": false,
    "isFlippedVertical": false,
    "isLocked": false,
    "isVisible": true,
    "layerListExpandedType": 0,
    "name": "Facebook",
    "nameIsFixed": true,
    "resizingConstraint": 63,
    "resizingType": 0,
    "rotation": 0,
    "shouldBreakMaskChain": false,
    "userInfo": {
        "com.animaapp.stc-sketch-plugin": {
            "kModelPropertiesKey": {
                "constraints": {
                    "scaleFactor": 1,
                    "model_version": 0.1,
                    "aspectRatio": {
                        "constant": 50,
                        "enabled": 1,
                        "multiplier": 50,
                        "modelID": "constraint_c03c7307-1fe6-4ded-9d49-e35c2e25c117",
                        "model_class": "ADModelConstraint",
                        "model_version": 0.1
                    },
                    "modelID": "viewConstraints_b34c9514-3166-464d-a3dd-f968c4f6144b",
                    "model_class": "ADModelViewConstraints",
                    "automatic": 1
                }
            }
        }
    },
    "clippingMaskMode": 0,
    "hasClippingMask": false,
    "hasClickThrough": false,
    "layers": [
        {
            "_class": "oval",
            "do_objectID": "DA55B46C-1069-46DC-AAD6-78DCC03F4B3C",
            "booleanOperation": -1,
            "frame": {
                "_class": "rect",
                "do_objectID": "58627B0B-C1B7-4C33-BF5C-2B0F6F0DBC8E",
                "constrainProportions": true,
                "height": 50,
                "width": 50,
                "x": 0,
                "y": 0
            },
            "isFixedToViewport": false,
            "isFlippedHorizontal": false,
            "isFlippedVertical": false,
            "isLocked": false,
            "isVisible": true,
            "layerListExpandedType": 0,
            "name": "Oval",
            "nameIsFixed": false,
            "resizingConstraint": 63,
            "resizingType": 0,
            "rotation": 0,
            "shouldBreakMaskChain": false,
            "userInfo": {
                "com.animaapp.stc-sketch-plugin": {
                    "kModelPropertiesKey": {
                        "constraints": {
                            "scaleFactor": 1,
                            "model_version": 0.1,
                            "aspectRatio": {
                                "constant": 32,
                                "enabled": 1,
                                "multiplier": 32,
                                "modelID": "constraint_5868769e-cc0b-4eec-a4af-d965ce1b6520",
                                "model_class": "ADModelConstraint",
                                "model_version": 0.1
                            },
                            "modelID": "viewConstraints_9d4aa04f-2445-427e-9182-b1ce723cefd2",
                            "model_class": "ADModelViewConstraints",
                            "automatic": 1
                        }
                    }
                }
            },
            "clippingMaskMode": 0,
            "hasClippingMask": false,
            "edited": false,
            "isClosed": true,
            "pointRadiusBehaviour": 1,
            "points": [
                {
                    "_class": "curvePoint",
                    "cornerRadius": 0,
                    "curveFrom": "{0.77614237490000004, 1}",
                    "curveMode": 2,
                    "curveTo": "{0.22385762510000001, 1}",
                    "hasCurveFrom": true,
                    "hasCurveTo": true,
                    "point": "{0.5, 1}"
                },
                {
                    "_class": "curvePoint",
                    "cornerRadius": 0,
                    "curveFrom": "{1, 0.22385762510000001}",
                    "curveMode": 2,
                    "curveTo": "{1, 0.77614237490000004}",
                    "hasCurveFrom": true,
                    "hasCurveTo": true,
                    "point": "{1, 0.5}"
                },
                {
                    "_class": "curvePoint",
                    "cornerRadius": 0,
                    "curveFrom": "{0.22385762510000001, 0}",
                    "curveMode": 2,
                    "curveTo": "{0.77614237490000004, 0}",
                    "hasCurveFrom": true,
                    "hasCurveTo": true,
                    "point": "{0.5, 0}"
                },
                {
                    "_class": "curvePoint",
                    "cornerRadius": 0,
                    "curveFrom": "{0, 0.77614237490000004}",
                    "curveMode": 2,
                    "curveTo": "{0, 0.22385762510000001}",
                    "hasCurveFrom": true,
                    "hasCurveTo": true,
                    "point": "{0, 0.5}"
                }
            ]
        },
        {
            "_class": "shapePath",
            "do_objectID": "C96926E4-56B4-4816-A68B-22789ACF9811",
            "booleanOperation": -1,
            "frame": {
                "_class": "rect",
                "do_objectID": "33C190C2-C868-48CC-B5A5-E033A65A5DC5",
                "constrainProportions": false,
                "height": 30,
                "width": 14,
                "x": 17,
                "y": 10
            },
            "isFixedToViewport": false,
            "isFlippedHorizontal": false,
            "isFlippedVertical": false,
            "isLocked": false,
            "isVisible": true,
            "layerListExpandedType": 1,
            "name": "facebook [#176]",
            "nameIsFixed": false,
            "resizingConstraint": 63,
            "resizingType": 0,
            "rotation": 0,
            "shouldBreakMaskChain": false,
            "userInfo": {
                "com.animaapp.stc-sketch-plugin": {
                    "kModelPropertiesKey": {}
                }
            },
            "clippingMaskMode": 0,
            "hasClippingMask": false,
            "edited": true,
            "isClosed": true,
            "pointRadiusBehaviour": 0,
            "points": [
                {
                    "_class": "curvePoint",
                    "cornerRadius": 0,
                    "curveFrom": "{0.68212824010914053, 1}",
                    "curveMode": 1,
                    "curveTo": "{0.68212824010914053, 1}",
                    "hasCurveFrom": false,
                    "hasCurveTo": false,
                    "point": "{0.68212824010914053, 1}"
                },
                {
                    "_class": "curvePoint",
                    "cornerRadius": 0,
                    "curveFrom": "{0.68212824010914053, 0.55000000000000004}",
                    "curveMode": 1,
                    "curveTo": "{0.68212824010914053, 0.55000000000000004}",
                    "hasCurveFrom": false,
                    "hasCurveTo": false,
                    "point": "{0.68212824010914053, 0.55000000000000004}"
                },
                {
                    "_class": "curvePoint",
                    "cornerRadius": 0,
                    "curveFrom": "{0.95536932371857075, 0.55000000000000004}",
                    "curveMode": 1,
                    "curveTo": "{0.95536932371857075, 0.55000000000000004}",
                    "hasCurveFrom": false,
                    "hasCurveTo": false,
                    "point": "{0.95536932371857075, 0.55000000000000004}"
                },
                {
                    "_class": "curvePoint",
                    "cornerRadius": 0,
                    "curveFrom": "{1, 0.34999999999999998}",
                    "curveMode": 1,
                    "curveTo": "{1, 0.34999999999999998}",
                    "hasCurveFrom": false,
                    "hasCurveTo": false,
                    "point": "{1, 0.34999999999999998}"
                },
                {
                    "_class": "curvePoint",
                    "cornerRadius": 0,
                    "curveFrom": "{0.68212824010914053, 0.34999999999999998}",
                    "curveMode": 1,
                    "curveTo": "{0.68212824010914053, 0.34999999999999998}",
                    "hasCurveFrom": false,
                    "hasCurveTo": false,
                    "point": "{0.68212824010914053, 0.34999999999999998}"
                },
                {
                    "_class": "curvePoint",
                    "cornerRadius": 0,
                    "curveFrom": "{0.68212824010914053, 0.20109999999999956}",
                    "curveMode": 4,
                    "curveTo": "{0.68212824010914053, 0.2525999999999996}",
                    "hasCurveFrom": true,
                    "hasCurveTo": false,
                    "point": "{0.68212824010914053, 0.2525999999999996}"
                },
                {
                    "_class": "curvePoint",
                    "cornerRadius": 0,
                    "curveFrom": "{0.82868836484116337, 0.14999999999999999}",
                    "curveMode": 4,
                    "curveTo": "{0.68475930617813163, 0.14999999999999999}",
                    "hasCurveFrom": false,
                    "hasCurveTo": true,
                    "point": "{0.82868836484116337, 0.14999999999999999}"
                },
                {
                    "_class": "curvePoint",
                    "cornerRadius": 0,
                    "curveFrom": "{0.97446891444162931, 0.14999999999999999}",
                    "curveMode": 1,
                    "curveTo": "{0.97446891444162931, 0.14999999999999999}",
                    "hasCurveFrom": false,
                    "hasCurveTo": false,
                    "point": "{0.97446891444162931, 0.14999999999999999}"
                },
                {
                    "_class": "curvePoint",
                    "cornerRadius": 0,
                    "curveFrom": "{0.97446891444162931, 0.0048499999999989992}",
                    "curveMode": 4,
                    "curveTo": "{0.97446891444162931, 0.0069999999999993175}",
                    "hasCurveFrom": true,
                    "hasCurveTo": false,
                    "point": "{0.97446891444162931, 0.0069999999999993175}"
                },
                {
                    "_class": "curvePoint",
                    "cornerRadius": 0,
                    "curveFrom": "{0.45800038978756463, 0}",
                    "curveMode": 3,
                    "curveTo": "{0.84924965893587745, 0}",
                    "hasCurveFrom": true,
                    "hasCurveTo": true,
                    "point": "{0.72256870005847007, 0}"
                },
                {
                    "_class": "curvePoint",
                    "cornerRadius": 0,
                    "curveFrom": "{0.29234067433248878, 0.23499999999999943}",
                    "curveMode": 4,
                    "curveTo": "{0.29234067433248878, 0.082849999999999119}",
                    "hasCurveFrom": false,
                    "hasCurveTo": true,
                    "point": "{0.29234067433248878, 0.23499999999999943}"
                },
                {
                    "_class": "curvePoint",
                    "cornerRadius": 0,
                    "curveFrom": "{0.29234067433248878, 0.34999999999999998}",
                    "curveMode": 1,
                    "curveTo": "{0.29234067433248878, 0.34999999999999998}",
                    "hasCurveFrom": false,
                    "hasCurveTo": false,
                    "point": "{0.29234067433248878, 0.34999999999999998}"
                },
                {
                    "_class": "curvePoint",
                    "cornerRadius": 0,
                    "curveFrom": "{0, 0.34999999999999998}",
                    "curveMode": 1,
                    "curveTo": "{0, 0.34999999999999998}",
                    "hasCurveFrom": false,
                    "hasCurveTo": false,
                    "point": "{0, 0.34999999999999998}"
                },
                {
                    "_class": "curvePoint",
                    "cornerRadius": 0,
                    "curveFrom": "{0, 0.55000000000000004}",
                    "curveMode": 1,
                    "curveTo": "{0, 0.55000000000000004}",
                    "hasCurveFrom": false,
                    "hasCurveTo": false,
                    "point": "{0, 0.55000000000000004}"
                },
                {
                    "_class": "curvePoint",
                    "cornerRadius": 0,
                    "curveFrom": "{0.29234067433248878, 0.55000000000000004}",
                    "curveMode": 1,
                    "curveTo": "{0.29234067433248878, 0.55000000000000004}",
                    "hasCurveFrom": false,
                    "hasCurveTo": false,
                    "point": "{0.29234067433248878, 0.55000000000000004}"
                },
                {
                    "_class": "curvePoint",
                    "cornerRadius": 0,
                    "curveFrom": "{0.29234067433248878, 1}",
                    "curveMode": 1,
                    "curveTo": "{0.29234067433248878, 1}",
                    "hasCurveFrom": false,
                    "hasCurveTo": false,
                    "point": "{0.29234067433248878, 1}"
                }
            ]
        }
    ]
}

его SVG-код

<g id="Facebook">
    <circle id="Oval" fill="#5B76AF" cx="25" cy="25" r="25"></circle>
    <path d="M26.5497954,40 L26.5497954,26.5 L30.3751705,26.5 L31,20.5 L26.5497954,20.5 L26.5497954,17.578 C26.5497954,16.033 26.5866303,14.5 28.6016371,14.5 L30.6425648,14.5 L30.6425648,10.21 C30.6425648,10.1455 28.8894952,10 27.1159618,10 C23.4120055,10 21.0927694,12.4855 21.0927694,17.05 L21.0927694,20.5 L17,20.5 L17,26.5 L21.0927694,26.5 L21.0927694,40 L26.5497954,40 Z" id="facebook-[#176]" fill="#FFFFFF"></path>
</g>

Я понимаю, что <circle /> исходит из первого слоя, с которым у меня нет проблем, проблема во втором слое, path, который является буквой f, так как его точки эскиза json отображаются на <path d="M26.5497954,40 L26.5497954,26.5 L30.3751705,26.5 L31,20.5 L26.5497954,20.5 L26.5497954,17.578 C26.5497954,16.033 26.5866303,14.5 28.6016371,14.5 L30.6425648,14.5 L30.6425648,10.21 C30.6425648,10.1455 28.8894952,10 27.1159618,10 C23.4120055,10 21.0927694,12.4855 21.0927694,17.05 L21.0927694,20.5 L17,20.5 L17,26.5 L21.0927694,26.5 L21.0927694,40 L26.5497954,40 Z" id="facebook-[#176]" fill="#FFFFFF"></path>

это то, что я изо всех сил пытаюсь взломать .. Есть ли шаблон для превращения эскиза json указывает на путь svg и как я могу это сделать ..

Спасибо.


person JohnPep    schedule 26.11.2018    source источник
comment
Вы понимаете пути SVG, такие как M26.54,40 L26.54,26.5 C30.64,10.14 Z? Если нет, я бы начал с чтения SVG Paths .   -  person Codo    schedule 02.12.2018
comment
@Codo я понимаю как M, L, C, Z, проблема заключается в преобразовании точек json в эти числа после M, то есть M26.53,40 L26.54 и т. д..   -  person JohnPep    schedule 02.12.2018
comment
Привет, ДжонПеп! Вы нашли решение?   -  person nullpexx    schedule 31.01.2019


Ответы (1)


У меня нет полного решения, но есть несколько хороших советов:

Координаты

Кажется, что все слои используют локальную систему координат со значениями x и y от 0 до 1. Таким образом, вам нужны размер и положение слоев для вычисления координат, используемых в SVG:

xsvg = frame.x + xlayer * frame.width
ysvg = frame.y + ylayer< /sub> * кадр.высота

Команды

Сопоставление команд сложнее, поскольку система Sketch использует модель, отличную от SVG. Основное отличие состоит в том, что SVG использует команды для представления сегментов пути (за исключением начального M), тогда как Sketch использует список точек, которые представляют собой либо острые, либо мягкие углы. Для того, чтобы вывести команду, нужно смотреть на две последовательные точки. Назовем их p1 и p2:

p1.hasCurveFrom = false и p2.hasCurveTo = false:

Это представляет собой прямую линию, то есть команду L. Координата берется из p2.point.

p1.hasCurveFrom = true и p2.hasCurveTo = true:

Это кубический сплайн, то есть команда C. Три координаты взяты из:

  1. p1.curveFrom
  2. p2.curveTo
  3. p2.point

Дополнительные советы

Путь начинается с команды M до p.point первой точки.

Атрибут "isClosed": true явно указывает на закрытый путь. Поэтому команды заканчиваются на Z, чтобы закрыть путь.

Наверное, есть еще много тонкостей, которых я не знаю.

Если вы хотите реализовать полный конвертер Sketch в SVG, вам также потребуется реализовать различные классы фигур, а не только треугольник, овал и shapePath и вам нужно будет позаботиться обо всех других атрибутах, таких как isFlippedHorizontal, isFlippedVertical, rotation, cornerRadius, изменение размера и т. д.

person Codo    schedule 02.12.2018