paint-brush
ምስሎችን ከ Figma አሪፍ በሆነ መንገድ እንዴት ማስመጣት እንደሚቻል@smileek
አዲስ ታሪክ

ምስሎችን ከ Figma አሪፍ በሆነ መንገድ እንዴት ማስመጣት እንደሚቻል

Andrei Sieedugin8m2025/03/04
Read on Terminal Reader

በጣም ረጅም፤ ማንበብ

ይህ መመሪያ አዶዎችን ከ Figma እንዴት በቀላሉ ወደ React/Vue ፕሮጄክት ማስመጣት እና በተለያየ መጠን እና ቀለም ለመጠቀም የሚያስችል አካል መፍጠር እንደሚቻል ያሳያል።
featured image - ምስሎችን ከ Figma አሪፍ በሆነ መንገድ እንዴት ማስመጣት እንደሚቻል
Andrei Sieedugin HackerNoon profile picture

በFigma ውስጥ የአዶዎች ስብስብ እንዳለህ እና በReact/Vue/ምንም ሌላ ፕሮጀክት እንዳለህ ይናገሩ። ምንም አያስደንቅም፣ እነዚያን አዶዎች መጠቀም ያስፈልግዎታል። እንዴት እናስመጣቸዋለን?


ግትር ከሆንክ አንድ በአንድ አውርደህ እንደ ንብረት ማከል ትችላለህ። ግን ያ አሳዛኝ መንገድ ነው። መውደድ የለም።


ማዘንን ትተን በምትኩ ድንቅ እንሁን። የሚያስፈልገን ይኸውና፡-

  • እነዚያን አዶዎች በተለያየ መጠን እና ቀለም ለመጠቀም የሚያስችል ጥሩ አካል።
  • በአዶ ስሞች ራስ-አጠናቅቅ።
  • አዲስ አዶ ሲታከል ቀላል ዝማኔ።


*ምንም ተጨማሪ ማስደሰት የለም*

እዚ ጀምር

የFigma ማስመሰያ እንፈልጋለን። ይህንን እንዴት ማድረግ እንደሚቻል ማብራራት አስፈላጊ አይመስለኝም, ስለዚህ በምትኩ የእርዳታ ክፍል ይኸውና: https://help.figma.com/hc/en-us/articles/8085703771159-Manage-personal-access-tokens .


ነባሪ ቅንጅቶች በቂ ናቸው፡ የፋይሉ ይዘት ተነባቢ-ብቻ መዳረሻ ያስፈልገናል።



መታወቂያህን ስጠኝ።

የቁሳቁስ ንድፍ አዶዎችን (ማህበረሰብ) እንደ ምሳሌ እጠቀማለሁ።


የፋይል ቁልፍ እና ዋናው መስቀለኛ መንገድ መታወቂያ እንፈልጋለን፡


አሁን በቂ ቅድመ ሁኔታዎች ስላሉን፣ ኮድ ማድረግ እንጀምር። ስክሪፕቶቼን ከዋናው የፕሮጀክት ኮድ የተለዩ እወዳለሁ፣ ስለዚህ በስሩ ውስጥ scripts ማህደር እና በውስጡ fetch-icons.ts እፈጥራለሁ። በታይፕ ስክሪፕት ማድረግ አያስፈልግም፣ ነገር ግን ይህን ጽሁፍ ጥሩ ያደርገዋል፣ ስለዚህ አብሬው እሄዳለሁ።


ሆኖም ፣ ይህ ሁለት ተጨማሪ ጥገኝነቶችን ይፈልጋል-

 yarn add -D tsx dotenv axios @figma/rest-api-spec


dotenv.env ተለዋዋጮችን ለመጠቀም እዚህ አለ ፣ tsx — የቲኤስ ስክሪፕቱን ለማስኬድ (የጌጥ ፣ አስታውስ?) ፣ @figma/rest-api-spec ለአይነት ደህንነት ነው ፣ እና axios እሱን ስለለመድኩ ብቻ ነው። የሚፈለገው dotenv ብቻ ነው (የኤፒአይ ቁልፉን በኮዱ ላይ በማከል ጥሩ ካልሆነ በስተቀር) እና በመጨረሻው ላይ “ንፁህ” የሚለውን እትም እጨምራለሁ ። ለአሁን፣ ይህን ማዋቀር ይኖረናል፣ እና በዚህ የምንጀምረው ነገር እነሆ፡-

 import * as dotenv from "dotenv"; dotenv.config(); const PERSONAL_ACCESS_TOKEN = String( process.env.VITE_FIGMA_PERSONAL_ACCESS_TOKEN ); // I've added my Figma token to the .env file, and so should you const FIGMA_API_URL = "https://api.figma.com/v1"; const FILE_KEY = "v50KJO82W9bBJUppE8intT"; // this one is from the URL const NODE_ID = "2402-2207"; // node-id query param, also from the URL


አምጣ!

በመጀመሪያ፣ ለዋናው ፍሬም ሜታዳታ እናገኛለን፡-

 import { GetFileNodesResponse, GetImagesResponse, HasChildrenTrait, } from "@figma/rest-api-spec"; // ... const fetchFrameData = async ( nodeId: string ): Promise<HasChildrenTrait> => { const { data } = await axios.get<GetFileNodesResponse>( `${FIGMA_API_URL}/files/${FILE_KEY}/nodes?ids=${nodeId}`, getConfig() ); return data.nodes[nodeId].document as HasChildrenTrait; };


ስለልጆቹ መረጃውን ይመልሳል. እነዚያ ምስሎች (አይነታቸው INSTANCE ይሆናል) ወይም ሌሎች በተደጋጋሚ የምንተነተንባቸው ክፈፎች ሊሆኑ ይችላሉ

 const getImageNodes = ( frameData: HasChildrenTrait ): Record<string, string> => { const nodes: Record<string, string> = {}; for (const image of frameData.children.filter( (node) => node.type === 'INSTANCE' )) { // normalizeName simply converts 'check-box' to 'CheckBox' const name = normalizeName(image.name); const id = image.id; nodes[id] = name; } for (const frame of frameData.children.filter( (node) => node.type === 'FRAME' )) { Object.assign(nodes, getImageNodes(frame)); } return nodes; };


በመጨረሻም፣ ብዙ የምስል መታወቂያዎች ሲኖረን የSVG ፋይል ዩአርኤሎችን እናመጣለን፡

 const fetchImageUrls = async ( nodeIds: string[] ): Promise<GetImagesResponse> => { const { data } = await axios.get<GetImagesResponse>( `${FIGMA_API_URL}/images/${FILE_KEY}?ids=${nodeIds.join(",")}&format=svg`, getConfig() ); return data; };


እና በእንደዚህ ዓይነት ዕቃዎች ስብስብ እንጨርሳለን-

 { name: 'CheckBox', url: 'https://figma-alpha-api.s3.us-west-2.amazonaws.com/images/7dd5bc31-4f26-4701-b155-7bf7dea45824' }


አስቀድመህ እንደገመትከው፣ ሁሉንም እናወርዳቸዋለን፣ ግን ያ በጣም አስደሳችው ክፍል አይደለም።

የእነሱ አናቶሚ

SVG ባመጣን ቁጥር እንደዚህ ያለ ነገር እናገኛለን፡-

 <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M17 6H7C3.69 6 1 8.69 [...] 9 17 9Z" fill="black" /> </svg>


ለእያንዳንዱ አዶ ተመሳሳይ ስለሆኑ svg መለያዎችን እናስወግዳለን (ለቀላልነት ተመሳሳይ መጠን ያላቸው ይመስለኛል)። ግን የበለጠ የሚያስደስት ነገር ሁሉንም fill=”black” በአብነት ቃል በቃል በቦታ ያዥ እንተካለን እና በዚህ ምክንያት እንደዚህ ያለ ተግባር ይኖረናል

 export const IconToggleOn = (color: string) => `<path d="M17 6H7C3.69 [...] 9 17 9Z" fill="${color}"/>`;


እንዴት እንደምናገኘው እነሆ፡-

 const cleanupSvg = (data: string): string => { const svgTags = /<\/?svg.*?>/g; const colorFills = /fill=["'].+?["']/g; return data .replace(svgTags, "") .replace(colorFills, 'fill="${color}"') .replace(/\n/g, ""); };


አንዳንድ ሎጎዎችን ማስመጣት ከፈለጉ ቀለሞቹን መተካት አያስፈልግዎትም ነገር ግን ለእነሱ የተለየ አመክንዮ መስራት የቤት ስራዎ ይሆናል።

እንጀምር

እሺ፣ እቅዳችን ይኸውና፡-

  1. የተገኘውን ፋይል ካለ ያስወግዱት።
  2. የአዶ ኖዶችን ከ Figma ያውጡ።
  3. ለነዚያ አንጓዎች አዶ ዩአርኤሎችን ያውጡ።
  4. SVGs አውርድ።
  5. በአዶ ተግባሮቻችን አዲስ ፋይል ይፍጠሩ።


ሙሉውን ፋይል አላነብም - በ GitHub ላይ ማረጋገጥ ትችላለህ. ማውረዱን ራሱ እንመልከት፡-

 const FILE_BATCH_SIZE = 10; const fileContent: string[] = []; const getPromise = async (item: IconData) => { try { const { data } = await axios.get<string>( item.url, getConfig("image/svg+xml") // returns necessary options and headers ); return { name: item.name, data }; } catch (err) { console.error(err); } }; for (let i = 0; i < iconsData.length; i += FILE_BATCH_SIZE) { const batch = await Promise.allSettled( iconsData.slice(i, i + FILE_BATCH_SIZE).map(getPromise) ); for (const icon of batch) { if (icon?.status === "fulfilled" && icon.value) { const iconName = `Icon${icon.value.name}`; const svgData = cleanupSvg(icon.value.data); fileContent.push( `export const ${iconName} = (color: string) =>\n \`${svgData}\`;\n` ); } } }


እዚህ መጋገር አስፈላጊ ነው ምክንያቱም አለበለዚያ በትይዩ በሺዎች የሚቆጠሩ ፋይሎችን ለማውረድ ከወሰኑ Figma አይወድዎትም።


ከጀርባ በተቀበሉት ስም አዶ ማግኘት ከፈለጉ መዝገበ ቃላት መፍጠር ይችላሉ፡-

 const iconArray: string[] = []; // ... for (const icon of batch) { if (icon?.status === "fulfilled" && icon.value) { const iconName = `Icon${icon.value.name}`; const svgData = cleanupSvg(icon.value.data); fileContent.push( `export const ${iconName} = (color: string) =>\n \`${svgData}\`;\n` ); iconArray.push(iconName); // <-- we added this } } // ... when all files are processed fileContent.push( `\r\nexport const iconDictionary: Record<string, (color: string) => string> = {\r\n ${iconArray.join( ",\r\n " )}\r\n};\r\n` );


ምንም እንኳን አንድ አዶ በመዝገበ-ቃላት ቢጠቀሙም ሙሉው ስብስብ ወደ ጥቅል ስለሚጨመር ይህ አካሄድ የከፋ ነው ፣ ግን አንዳንድ ጊዜ ፣ አንድ ደስ የማይል ነገር ማድረግ አለብዎት። እንዲሁም፣ የእኔን ESLint ለማስደሰት ሁሉም \r\n እና ክፍተቶች እዚህ አሉ፡ መጠናቸውን ማስተካከል ሊኖርብዎ ይችላል።


እዚህ የመጨረሻው ደረጃ ይመጣል; አዲስ ፋይል እንፍጠር፡-

 import path from "path"; import { fileURLToPath } from "url"; // ... const PATH_TO_ICONS = "../src/assets/icons"; const currentPath = fileURLToPath(import.meta.url); const currentDirectory = path.dirname(currentPath); const fileName = "index.ts"; const filePath = path.join( path.resolve(currentDirectory, PATH_TO_ICONS), fileName ); // ... fs.writeFileSync(filePath, fileContent.join(""));


አንድ ትንሽ ነገር

ዩአርኤሎቹን ከወሰዱ በኋላ አዶዎችን መደርደር ጥሩ ሀሳብ ነው፣ ይህም እንደዚህ ቀላል ነው።

 iconsData.sort((a, b) => a.name.localeCompare(b.name));


የተደረደሩ ዝርዝር ለማንበብ ቀላል ይሆናል፣ እና ከሁሉም በላይ አስፈላጊ የሆነው፣ አዲስ አዶዎችን ባገኘን ቁጥር ሊነበብ የሚችል ልዩነት ይኖረናል። አለበለዚያ ትዕዛዙ ዋስትና አይሰጥም, እና አንድ አዶ ማከል ሁሉንም ነገር ሊያበላሽ ይችላል.

ፋይሉን እንደገና እንፈጥራለን፣ የአዶዎቹ ቅደም ተከተል ግን እንዳለ ይቆያል


አሁን ምን?

የአዶውን ሕብረቁምፊ፣ ቀለም እና መጠን እንደ መደገፊያ የሚቀበል እና ጣፋጭ ነገር የሚስል አካል እንፈልጋለን።

 import React, { useMemo } from "react"; import { IconSvg } from "../types/IconSvg"; interface IconProps { svg: IconSvg; // type IconSvg = (color: string) => string; color?: string; size?: number | string; } const refine = (x: string | number) => { return typeof x === "number" || !/\D+/.test(x) ? `${x}px` : x; }; const MyIcon: React.FC<IconProps> = ({ svg, color, size, }) => { const iconColor = useMemo(() => color ?? "black", [color]); const refinedSize = useMemo(() => refine(size ?? 24), [size]); const currentIcon = useMemo(() => svg(currentColor), [svg, currentColor]); return ( <svg viewBox="0 0 24 24" // make sure it's the same as in Figma dangerouslySetInnerHTML={{ __html: currentIcon }} style={{ width: refinedSize, minWidth: refinedSize, height: refinedSize, minHeight: refinedSize, }} ></svg> ); }; export default MyIcon;


ልክ እንደማጣራት ካልሆነ በስተቀር በጣም ቀላል ነው ብዬ አምናለሁ፡ ለመጀመሪያ ጊዜ ተግባራዊ ሳደርግ Chrome ቁጥሮችን እንደ ስፋት/ቁመት የሲኤስኤስ ባህሪያት ተቀብሏል ነገርግን ፋየርፎክስ አላደረገም, ስለዚህ px ጨምሬያለሁ. አሁን ጉዳዩ ባይሆንም እንደታሰበው እንደ መስፈርት እናቆየው።


እና እኔ ቃል የገባሁት ራስ-አጠናቅቅ ይኸውና፡-

ያ ሁሉም ሰዎች ናቸው።

እንደዚህ ነው የማበስለው። ጠቃሚ ሆኖ እንዳገኙት ተስፋ አደርጋለሁ።


የዚህ አቀራረብ ጉዳቱ አዶዎቹ ወደ ውስጥ እንዲገቡ እና በዚህ ምክንያት እንዳይሸጎጡ ማድረጉ ነው። ይሁን እንጂ ለጥቂት ባይት ትልቅ ጉዳይ ነው ብዬ አላምንም። በተጨማሪም ፣ በማንዣበብ ላይ ያለውን ቀለም መለወጥ ፣ ሌላ ማንኛውንም ማሽከርከር ማከል ይችላሉ ፣ እና የእነዚያ አዶዎች ትንሽ የስዊስ-ሠራዊት ቢላዋ ይኖርዎታል።


እንዲሁም፣ በFigma ውስጥ የተደራጀ ፋይል ያስፈልገዋል። ግን ሄይ፣ ይህን ሁሉ ኮድ መፃፍ ከቻልክ ዲዛይነሮችህን እንዲያስተካክሉ ማሳመንም ትችላለህ።


React እና Vue ክፍሎችን ጨምሮ ሙሉውን ኮድ እና ጥቂት ጥገኞች ያለው የ Node.js ስሪት እዚህ ማግኘት ይችላሉ ፡ https://github.com/Smileek/fetch-icons

L O A D I N G
. . . comments & more!

About Author

Andrei Sieedugin HackerNoon profile picture
Andrei Sieedugin@smileek
Senior frontend developer with product management experience

ተንጠልጣይ መለያዎች

ይህ ጽሑፍ ቀርቧል...