Install
openclaw skills install figma-plugin-writer自动生成和更新 Figma 插件的 code.js 以创建和修改设计元素,用户更新代码后需手动运行插件执行。
openclaw skills install figma-plugin-writerWrite plugin code (code.js) to automate design in Figma files. After updating the code, notify the user to run the plugin.
The user must provide:
code.js and manifest.jsoncode.jscode.jsPlugins → Development → <plugin-name>await figma.loadFontAsync({ family: "Inter", style: "Regular" });
await figma.loadFontAsync({ family: "Inter", style: "Medium" });
await figma.loadFontAsync({ family: "Inter", style: "Semi Bold" });
await figma.loadFontAsync({ family: "Inter", style: "Bold" });
var frame = figma.createFrame();
frame.name = "MyFrame";
frame.resize(width, height);
frame.cornerRadius = 12;
frame.fills = [{ type: "SOLID", color: { r: 1, g: 1, b: 1 } }];
frame.x = 0;
frame.y = 0;
var text = figma.createText();
text.characters = "Hello World";
text.fontSize = 16;
text.fontName = { family: "Inter", style: "Regular" };
text.fills = [{ type: "SOLID", color: { r: 0, g: 0, b: 0 } }];
var rect = figma.createRectangle();
rect.resize(100, 50);
rect.fills = [{ type: "SOLID", color: { r: 0.9, g: 0.2, b: 0.2 } }];
rect.cornerRadius = 8;
frame.appendChild(text);
parentPage.appendChild(frame);
frame.effects = [{
type: "DROP_SHADOW",
color: { r: 0, g: 0, b: 0, a: 0.1 },
offset: { x: 0, y: 4 },
radius: 12,
spread: 0,
visible: true,
blendMode: "NORMAL",
}];
frame.strokes = [{ type: "SOLID", color: { r: 0.8, g: 0.8, b: 0.8 } }];
frame.strokeWeight = 1;
text.textAlignHorizontal = "CENTER"; // LEFT | CENTER | RIGHT | JUSTIFIED
text.textAlignVertical = "CENTER"; // TOP | CENTER | BOTTOM
frame.layoutMode = "VERTICAL"; // or "HORIZONTAL"
frame.primaryAxisAlignItems = "CENTER"; // MIN | CENTER | MAX | SPACE_BETWEEN
frame.counterAxisAlignItems = "CENTER";
frame.paddingTop = 16;
frame.paddingBottom = 16;
frame.paddingLeft = 16;
frame.paddingRight = 16;
frame.itemSpacing = 8;
var pages = figma.root.children;
var targetPage = pages[pages.length - 1];
await figma.setCurrentPageAsync(targetPage);
var old = targetPage.children.slice();
for (var i = 0; i < old.length; i++) {
old[i].remove();
}
figma.viewport.scrollAndZoomIntoView([frame]);
figma.notify("Done!", { timeout: 3000 });
figma.notify("ERROR: " + e.message, { timeout: 10000 });
var pages = figma.root.children;
var count = pages.length;
var pageName = pages[0].name;
async function main() {
try {
// 1. Load fonts
await figma.loadFontAsync({ family: "Inter", style: "Regular" });
await figma.loadFontAsync({ family: "Inter", style: "Bold" });
// 2. Get target page
var pages = figma.root.children;
var target = pages[pages.length - 1];
await figma.setCurrentPageAsync(target);
// 3. Clear old content
var old = target.children.slice();
for (var i = 0; i < old.length; i++) old[i].remove();
// 4. Create design...
var frame = figma.createFrame();
frame.name = "Screen";
frame.resize(375, 812);
frame.fills = [{ type: "SOLID", color: { r: 1, g: 1, b: 1 } }];
frame.x = 0;
frame.y = 0;
target.appendChild(frame);
// 5. Done
figma.viewport.scrollAndZoomIntoView([frame]);
figma.notify("Design complete!", { timeout: 3000 });
} catch (e) {
figma.notify("ERROR: " + e.message, { timeout: 10000 });
}
}
main();
If manifest.json has "documentAccess": "dynamic-page":
figma.currentPage = page → ✅ await figma.setCurrentPageAsync(page)figma.getNodeById() → ✅ await figma.getNodeByIdAsync()figma.closePlugin() → ✅ await figma.closePluginAsync()try-catchfigma.notify("ERROR: " + e.message, { timeout: 10000 })figma.closePlugin() automatically (let user close manually){ r, g, b } format with 0-1 rangeOn each design iteration:
page.children.slice().forEach(c => c.remove())