-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcode.ts
149 lines (138 loc) · 3.95 KB
/
code.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
type colorData = {
name: string;
hex: string;
opacity: number;
};
figma.showUI(__html__);
figma.ui.resize(500, 500);
// 現在のファイルの塗りのスタイルを取得
const styles = figma.getLocalPaintStyles();
// toCamelCase
const camelize = (str: string) => {
const wordsArr = str.split(/[\W-_]/g);
const camelizedWords = wordsArr
.map((word) => {
return word.charAt(0).toUpperCase() + word.slice(1);
})
.join("");
return camelizedWords;
};
// toSnakeCase
const snakeCase = (str: string) => {
const camelizedWords = camelize(str);
return camelizedWords.replace(/[A-Z]/g, (c) => { return '_' + c.toLowerCase() }).slice(1);
};
// 255に換算
const to255 = (rgb: number) => {
return Math.round(rgb * 255);
};
// RGBA換算
const toRgba = (rgb: RGB, opacity: number) => {
return (
to255(rgb.r) +
"," +
to255(rgb.g) +
"," +
to255(rgb.b) +
"," +
opacity.toFixed(1)
);
};
// 整数を16進数に変換
const decimalToHex = (decimal = 0) => decimal.toString(16);
// hex換算
// @ https://dev.to/coder4_life/convert-rgb-to-hex-color-codes-in-javascript-2bcd
const rgbToHex = (rgb: RGB) => {
const hex =
"#" +
((1 << 24) + (to255(rgb.r) << 16) + (to255(rgb.g) << 8) + to255(rgb.b))
.toString(16)
.slice(1);
return hex;
};
// jsonの独自形式に整形
const toJSONHex = (color: colorData) => {
if (color.opacity !== 1) {
const opacityTo10 = Number(color.opacity.toFixed(1)) * 100;
color.hex += "." + opacityTo10;
}
let JSONData = ' "' + color.name + '" : "' + color.hex + '"';
return JSONData;
};
if (figma.editorType === "figma") {
figma.ui.onmessage = (message) => {
console.log(message);
let currentData;
switch (message.fileType) {
case "CSS":
console.log(message.fileType);
// cssの形式に整形
const getCSSColorData = styles
.map((style) => {
if (style.paints[0].type !== "SOLID") {
// 単色でなければスキップ
return;
}
const color = style.paints[0].color;
const snakeCaseName = snakeCase(style.name);
return (
"--color-" +
snakeCaseName +
": rgba(" +
toRgba(color, Number(style.paints[0].opacity)) +
")"
);
})
.join(";\n");
currentData = getCSSColorData;
break;
case "XML":
console.log(message.fileType);
// XML形式に整形
const getXMLColorData = styles
.map((style) => {
if (style.paints[0].type !== "SOLID") {
// 単色でなければスキップ
return;
}
const color = style.paints[0].color;
const snakeCaseName = snakeCase(style.name);
return (
'<color name="' +
snakeCaseName +
'">' +
rgbToHex(color) +
"</color>"
);
})
.join("\n");
currentData = getXMLColorData;
break;
case "JSON":
default:
console.log(message.fileType);
// json形式に整形
const getJSONColorsData = styles
.map((style) => {
const opacity = Number(style.paints[0].opacity);
if (style.paints[0].type !== "SOLID") {
// 単色でなければスキップ
return;
}
const color = style.paints[0].color;
const camelizedName = camelize(style.name);
const hexString = rgbToHex(color);
const jsonOriginalHex = toJSONHex({
name: camelizedName,
hex: hexString,
opacity: opacity,
});
return jsonOriginalHex;
})
.join(",\n");
currentData = "{\n" + getJSONColorsData + "\n}";
break;
}
figma.ui.postMessage({ type: "render", body: currentData });
};
}