kopyl

Figma utilities 23.03.2022

Mar 22nd, 2022
187
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. let fgLayer = null
  2.  
  3. const keypresses = {}
  4.  
  5. const l = console.log
  6.  
  7. class Styles {
  8.     constructor(layer) {
  9.         this.text = layer.textStyleId
  10.         this.color = layer.fillStyleId
  11.     }
  12. }
  13.  
  14. const getStyles = (layer) => {
  15.     return new Styles(layer)
  16. }
  17.  
  18.  
  19. const styles = {
  20.     get color() {
  21.         return new Styles(fSelected()).color
  22.     },
  23.     get text() {
  24.         return new Styles(fSelected()).text
  25.     }
  26. }
  27.  
  28. function isNumeric(str) {
  29.   if (typeof str != "string") return false // we only process strings!
  30.   return !isNaN(str) && // use type coercion to parse the _entirety_ of the string (`parseFloat` alone does not do this)...
  31.          !isNaN(parseFloat(str)) // ...and ensure strings of whitespace fail
  32. }
  33.  
  34. alphabet = {
  35.     getCharCodes(lower=true) {
  36.         const addValue = lower ? 97 : 65
  37.         const emptyArray = Array.from(Array(26))
  38.         return emptyArray.map((e, i) => i + addValue)
  39.     },
  40.     generateAlphabesArray(lower=true) {
  41.         const charCodes = this.getCharCodes(lower)
  42.         return charCodes.map((x) => String.fromCharCode(x))
  43.     },
  44.     get lower() {
  45.         return this.generateAlphabesArray(lower=true)
  46.     },
  47.     get upper() {
  48.         return this.generateAlphabesArray(lower=false)
  49.     }
  50. }
  51.  
  52. const selected = () => figma.currentPage.selection
  53.  
  54. const sleep = delay => new Promise(resolve => setTimeout(resolve, delay));
  55.  
  56. const select = (arrayLayers) => {
  57.     figma.currentPage.selection = arrayLayers
  58. }
  59.  
  60. const getStrDate = () => {
  61.     date = new Date()
  62.  
  63.     d = date.getDate()
  64.     mm = date.getMonth()
  65.     y = date.getFullYear()
  66.     h = date.getHours()
  67.     m = date.getMinutes()
  68.     s = date.getSeconds()
  69.    
  70.     return `${d}.${mm}.${y} ${h}:${m}:${s}`
  71. }
  72.  
  73. // Object.prototype.__defineGetter__(
  74. //     'values',
  75. //     function() {
  76. //         return Object.values(this)
  77. //     }
  78. // )
  79.  
  80. // Object.prototype.__defineGetter__(
  81. //     'keys',
  82. //     function() {
  83. //         return Object.keys(this)
  84. //     }
  85. // )
  86.  
  87. const fSelected = () => {
  88.     return figma.currentPage.selection[0]
  89. }
  90.  
  91. const replaceWithRandomNumbers = async(min, max) => {
  92.     let allNumbers = []
  93.     while(allNumbers.length < selected().length){
  94.             let numberReplaceWith = getRandomNmber(min, max)
  95.             numberReplaceWith = String(numberReplaceWith)
  96.             if(allNumbers.indexOf(numberReplaceWith) === -1) allNumbers.push(numberReplaceWith);
  97.         }
  98.  
  99.     for (let number = 0; number < selected().length; number++) {
  100.         await figma.loadFontAsync(selected()[number].fontName)
  101.         selected()[number].characters = allNumbers[number]
  102.     }
  103. }
  104.  
  105. const randomizeHotCold = () => {
  106.     let bools = createRandomBooArray(80)
  107.     let hot = figma.getNodeById("41:149")
  108.     let cold = figma.getNodeById("41:155")
  109.     let swapWith
  110.     for (let frame = 0; frame < selected().length; frame++) {
  111.         if (bools[frame] === true) {
  112.             swapWith = hot
  113.         } else {
  114.             swapWith = cold
  115.         }
  116.         selected()[frame].children.slice(-1)[0].swapComponent(swapWith)
  117.     }
  118. }
  119.  
  120.  
  121.  
  122.  
  123. class Archive {
  124.  
  125.     constructor() {
  126.         this.id = null
  127.         this.page = this.find()
  128.         this.exists = Boolean(this.page)
  129.         this.create()
  130.         this.notEmpty = this.page.findChild(e => e)
  131.         this.placeholderNode = this.createPlaceholderNode()
  132.     }
  133.  
  134.     find() {
  135.         const archive = figma.root.findChild(
  136.             e => e.type == "PAGE" && e.name == "Archive"
  137.         )
  138.         if (archive) this.id = archive.id
  139.         return archive
  140.     }
  141.  
  142.     create() {
  143.         if (this.exists) return
  144.         this.page = figma.createPage()
  145.         this.page.name = "Archive"
  146.         this.id = this.page.id
  147.     }
  148.    
  149.     createPlaceholderNode() {
  150.         /*
  151.         In case there were no layers in archive
  152.         It should have been better implemented
  153.         but there is no time for that,
  154.         and it works
  155.         so I'm leaving it as is
  156.         */
  157.         if (this.notEmpty) return
  158.         const placeholderNode = figma.createRectangle()
  159.         this.page.appendChild(placeholderNode)
  160.         return placeholderNode
  161.     }
  162.    
  163.     removePlaceholder() {
  164.         if (!this.placeholderNode) return
  165.         this.placeholderNode.remove()
  166.     }
  167.  
  168. }
  169.  
  170.  
  171.  
  172. const createRandomBooArray = (amount) => {
  173.     let allNumbers = []
  174.     while(allNumbers.length < amount){
  175.         let number = getRandomNmber(0, amount)
  176.         allNumbers.push(number)
  177.     }
  178.     let allBools = []
  179.     for (number of allNumbers) {
  180.         if (number % 2 === 0) {
  181.             allBools.push(true)
  182.         } else {
  183.             allBools.push(false)
  184.         }
  185.     }
  186.     return allBools
  187. }
  188.  
  189. const getRandomNmber = (min, max) => {
  190.   number = Math.random() * (max - min) + min
  191.   return Math.floor(number);
  192. }
  193.  
  194. const doublePressed = (event) => {
  195.     key = event.key
  196.     if (!keypresses[key]) {
  197.         keypresses[key] = Date.now()
  198.         return false
  199.     }
  200.     difference = Date.now() - keypresses[key]
  201.     if (difference < 1000) {
  202.         delete keypresses[key]
  203.         return true
  204.     } else {
  205.         delete keypresses[key]
  206.         return false
  207.     }
  208. }
  209.  
  210. const operators = {
  211.     '+': function(a) { return a + 1 },
  212.     '-': function(a) { return a - 1 },
  213. };
  214.  
  215. const revertResize = (currentlySelectedLayers, resizeDirection, horizontalOrVerical="horizontal") => {
  216.     for (let x=0; x<currentlySelectedLayers.length; x++) {
  217.         let currentlySelectedLayerWidth = currentlySelectedLayers[x].width
  218.         let currentlySelectedLayerHeight = currentlySelectedLayers[x].height
  219.        
  220.         if (horizontalOrVerical == "vertical") {
  221.             if (currentlySelectedLayers[x].type === "LINE") {continue}
  222.             currentlySelectedLayers[x].resize(currentlySelectedLayerWidth, operators[resizeDirection](currentlySelectedLayerHeight))
  223.             continue
  224.         }
  225.         currentlySelectedLayers[x].resize(operators[resizeDirection](currentlySelectedLayerWidth), currentlySelectedLayerHeight)
  226.     }  
  227. }
  228.  
  229. const collapseParentOf = (currentlySelectedLayer) => {
  230.     let parent = currentlySelectedLayer.parent
  231.     try {
  232.         figma.currentPage.selection = [parent]
  233.         parent.expanded = false
  234.      } catch {
  235.         currentlySelectedLayer.expanded = false
  236.      }
  237. }
  238.  
  239. const ToggleCurrentLayerCollapsion = () => {
  240.     selectedLayer = fSelected()
  241.     if ( selectedLayer.expanded == undefined ) {
  242.         select([selectedLayer.parent])
  243.         selectedLayer.parent.expanded = !selectedLayer.parent.expanded
  244.         return
  245.     }
  246.     selectedLayer.expanded = !selectedLayer.expanded
  247. }
  248.  
  249. const selectFirstLayerInGroup = () => {
  250.     let nodeToSelect = figma.currentPage.selection[0].children.slice(-1)[0] // last
  251.     figma.currentPage.selection = [nodeToSelect]
  252.     nodeToSelect.expanded = false
  253. }
  254.  
  255. const toggleTextBoundBox = async() => {
  256.     textLayer = figma.currentPage.selection[0]
  257.     await figma.loadFontAsync(textLayer.fontName)
  258.     if (textLayer.textAutoResize != "WIDTH_AND_HEIGHT") {
  259.         textLayer.textAutoResize = "WIDTH_AND_HEIGHT"
  260.     } else {
  261.         textLayer.textAutoResize = "HEIGHT"
  262.     }
  263. }
  264.  
  265. const getNextLayer = (parentChildren, nextLayer, event) => {
  266.     layerToSelect = [parentChildren[nextLayer]]
  267.     layersToSelect = layerToSelect.concat(figma.currentPage.selection)
  268.     let layersToSelectSatuses = {}
  269.     for (layer of layersToSelect) {
  270.         let layerStatus = layer.expanded
  271.         layersToSelectSatuses[layer.id] = layerStatus
  272.     }
  273.     if (event.altKey) {
  274.         figma.currentPage.selection = layersToSelect
  275.     } else {
  276.         figma.currentPage.selection = [layersToSelect[0]]
  277.     }
  278.     for (layer of layersToSelect) {
  279.         let layerStatus = layersToSelectSatuses[layer.id]
  280.         node = figma.getNodeById(layer.id)
  281.         node.expanded = layerStatus
  282.     }
  283. }
  284.  
  285. const getPrevLayer = (parentChildren, previousLayer, event) => {
  286.     layerToSelect = [parentChildren[previousLayer]]
  287.     layersToSelect = layerToSelect.concat(figma.currentPage.selection)
  288.     l(layersToSelect)
  289.     let layersToSelectSatuses = {}
  290.     for (layer of layersToSelect) {
  291.         let layerStatus = layer.expanded
  292.         layersToSelectSatuses[layer.id] = layerStatus
  293.     }
  294.     if (event.altKey) {
  295.         figma.currentPage.selection = layersToSelect
  296.     } else {
  297.         figma.currentPage.selection = [layersToSelect[0]]
  298.     }
  299.     for (layer of layersToSelect) {
  300.         let layerStatus = layersToSelectSatuses[layer.id]
  301.         node = figma.getNodeById(layer.id)
  302.         node.expanded = layerStatus
  303.     }
  304. }
  305.  
  306.  
  307. // const getPrevLayer = (parentChildren, previousLayer, event) => {
  308. //  layerToSelect = [parentChildren[previousLayer]]
  309. //  layersToSelect = figma.currentPage.selection.concat(layerToSelect)
  310. //  let layersToSelectSatuses = {}
  311. //  for (layer of layersToSelect) {
  312. //      let layerStatus = layer.expanded
  313. //      layersToSelectSatuses[layer.id] = layerStatus
  314. //  }
  315. //  if (event.altKey) {
  316. //      figma.currentPage.selection = layersToSelect
  317. //  } else {
  318. //      figma.currentPage.selection = [layersToSelect[0]]
  319. //  }
  320. //  for (layer of layersToSelect) {
  321. //      let layerStatus = layersToSelectSatuses[layer.id]
  322. //      node = figma.getNodeById(layer.id)
  323. //      node.expanded = layerStatus
  324. //  }
  325. // }
  326.  
  327. const getLayer = (order="next", event) => {
  328.     selection = figma.currentPage.selection
  329.     if (order == "next") {
  330.         selection = selection[0]
  331.     } else {
  332.         selection = selection[selection.length-1]
  333.     }
  334.     parent = selection.parent
  335.     parentChildren = parent.children
  336.     selectionId = selection.id
  337.  
  338.     orderOfSelectedLayerInGroup = 0
  339.     for (let x = 0; x<=parentChildren.length; x++) {
  340.         if (parentChildren[x].id == selectionId) {
  341.             break
  342.         }
  343.         orderOfSelectedLayerInGroup += 1
  344.     }
  345.     nextLayer = orderOfSelectedLayerInGroup - 1
  346.     previousLayer = orderOfSelectedLayerInGroup + 1
  347.  
  348.     if (order == "next") {
  349.         getNextLayer(parentChildren, nextLayer, event)
  350.     } else {
  351.         getPrevLayer(parentChildren, previousLayer, event)
  352.     }
  353. }
  354.  
  355. const revertFixedHeightTextLayer = async(currentlySelectedLayers) => {
  356.     for (let x=0; x<currentlySelectedLayers.length; x++) {
  357.         currentlySelectedLayer = currentlySelectedLayers[x]
  358.         if (currentlySelectedLayer.type == "TEXT") {
  359.             await figma.loadFontAsync(currentlySelectedLayer.fontName)
  360.             textAutoResize = localStorage.getItem(currentlySelectedLayer.id);
  361.             currentlySelectedLayer.textAutoResize = textAutoResize
  362.         }
  363.     }
  364. }
  365.  
  366. const saveTextLayerProperty = async(currentlySelectedLayers, event) => {
  367.     for (let x=0; x<currentlySelectedLayers.length; x++) {
  368.         currentlySelectedLayer = currentlySelectedLayers[x]
  369.         if (currentlySelectedLayer.type == "TEXT") {
  370.             await figma.loadFontAsync(currentlySelectedLayer.fontName)
  371.             localStorage.setItem(currentlySelectedLayer.id, currentlySelectedLayer.textAutoResize);
  372.         }
  373.     }
  374. }
  375.  
  376. const resetVerticalAlignment = () => {
  377.     selected()[0].textAlignVertical = "TOP"
  378. }
  379.  
  380. const fixPositionOfLayerWhichWasTakenOutOfGroup = (previousProperties) => {
  381.     fSelected().x = previousProperties.parent.x + previousProperties.x
  382.     fSelected().y = previousProperties.parent.y + previousProperties.y
  383. }
  384.  
  385. const getOutLayerOfTheGroup = () => {
  386.     layerToGetOut = figma.getNodeById(selected()[0].id)
  387.     layers = layerToGetOut.parent.parent.children
  388.     ids = layers.map(layer => layer.id)
  389.     layerIndex = ids.indexOf(layerToGetOut.parent.id)
  390.     layerToGetOut.parent.parent.insertChild(layerIndex+1, layerToGetOut)
  391. }
  392.  
  393. const pasteY = (rect) => {
  394.     rectSmall = selected()[0]
  395.     rectSmall.y = rect.y + rect.height + 144
  396.     rectSmall.x = rect.x
  397. }
  398.  
  399. const align = () => {
  400.     previouslySelected = selected()[0]
  401.     let focusSwitched = setInterval(function() {
  402.        if (previouslySelected.id != selected()[0].id) {
  403.           pasteY(previouslySelected)
  404.           clearInterval(focusSwitched);
  405.        }
  406.     }, 100); // check every 100ms
  407. }
  408.  
  409. const copyPastePosition = () => {
  410.     positions = localStorage.getItem('positions')
  411.     if (positions && positions != null) {
  412.         positions = JSON.parse(positions)
  413.         selected()[0].x = positions.x
  414.         selected()[0].y = positions.y
  415.         localStorage.removeItem('positions')
  416.     } else {
  417.         x = selected()[0].x
  418.         y = selected()[0].y
  419.         let xy = {"x": x, "y": y}
  420.         positions = JSON.stringify(xy)
  421.         localStorage.setItem('positions', positions)
  422.     }
  423. }
  424.  
  425.  
  426. document.addEventListener('keydown', function(event) {
  427.   if (event.ctrlKey && event.key === 't') {
  428.     resetVerticalAlignment()
  429.   }
  430. });
  431.  
  432. document.addEventListener('keydown', function(event) {
  433.   if (event.ctrlKey && event.key != 'ArrowDown' && event.key != 'ArrowUp' && event.key != 'ArrowLeft') {
  434.     let currentlySelectedLayers = figma.currentPage.selection
  435.     saveTextLayerProperty(currentlySelectedLayers, event)
  436.   }
  437. });
  438.  
  439. document.addEventListener('keydown', function(event) {
  440.   if (event.ctrlKey && event.key === 'ArrowLeft') {
  441.     let currentlySelectedLayers = figma.currentPage.selection
  442.     revertResize(currentlySelectedLayers, "+")
  443.     collapseParentOf(currentlySelectedLayers[0])
  444.     revertFixedHeightTextLayer(currentlySelectedLayers)
  445.   }
  446. });
  447.  
  448. document.addEventListener('keydown', function(event) {
  449.   if (event.shiftKey && event.key === 'Ç') {
  450.     ToggleCurrentLayerCollapsion()
  451.   }
  452. });
  453.  
  454. document.addEventListener('keydown', function(event) {
  455.   if (event.ctrlKey && event.key === 'ArrowRight') {
  456.     let currentlySelectedLayers = figma.currentPage.selection
  457.     revertResize(currentlySelectedLayers, "-")
  458.     selectFirstLayerInGroup()
  459.   }
  460. });
  461.  
  462. document.addEventListener('keydown', function(event) {
  463.   if (event.shiftKey && event.altKey && event.key === 'ˇ') {
  464.     toggleTextBoundBox()
  465.   }
  466. });
  467.  
  468. document.addEventListener('keydown', function(event) {
  469.   if (event.ctrlKey && event.key === 'ArrowUp') {
  470.     let currentlySelectedLayers = figma.currentPage.selection
  471.     revertResize(currentlySelectedLayers, "+", horizontalOrVerical="vertical")
  472.     getLayer("prev", event)
  473.     revertFixedHeightTextLayer(currentlySelectedLayers)
  474.   }
  475. });
  476.  
  477. document.addEventListener('keydown', function(event) {
  478.   if (event.ctrlKey && event.key === 'ArrowDown') {
  479.     let currentlySelectedLayers = figma.currentPage.selection
  480.     revertResize(currentlySelectedLayers, "-", horizontalOrVerical="vertical")
  481.     getLayer("next", event)
  482.     revertFixedHeightTextLayer(currentlySelectedLayers)
  483.     event.stopPropagation()
  484.   }
  485. });
  486.  
  487. document.addEventListener('keyup', function(event) {
  488.   if (event.key === 'Enter') {
  489.     let layer = figma.currentPage.selection[0]
  490.     if (layer.name == "bg") {
  491.         layer.name = "Background"
  492.     }
  493.   }
  494. });
  495.  
  496. document.addEventListener('keydown', function(event) {
  497.   if (event.ctrlKey && event.key === 'a') {
  498.     align()
  499.   }
  500. });
  501.  
  502. document.addEventListener('keydown', function(event) {
  503.   if (event.shiftKey && event.key === 'G') {
  504.     if (doublePressed(event)) {
  505.         // previousProperties = {x: fSelected().x, y: fSelected().y, parent: fSelected().parent}
  506.         getOutLayerOfTheGroup()
  507.         // fixPositionOfLayerWhichWasTakenOutOfGroup(previousProperties)
  508.     }
  509.   }
  510. });
  511.  
  512. document.addEventListener('keydown', function(event) {
  513.   if (event.shiftKey && event.key === '~') {
  514.     copyPastePosition()
  515.   }
  516. });
  517.  
  518.  
  519. const exportImageAsync = async(layer) => {
  520.     return await layer.exportAsync({format: "PNG", constraint: { type: "SCALE", value: 4 }})
  521. }
  522.  
  523. const sendNotification = async(message, hideAfterSeconds=1000) => {
  524.     let notification = document.createElement("p")
  525.     notification.innerText = message
  526.     notification.style.textAlign = "center"
  527.     notification.style.padding = "0px 0 0px 0"
  528.     notification.style.zIndex = "100"
  529.     notification.style.position = 'fixed'
  530.     notification.style.width = '0%'
  531.     notification.style.height = '48px'
  532.     notification.style.lineHeight = '48px'
  533.     notification.style.color = 'white'
  534.     notification.style.background = 'blue'
  535.     notification.style.overflow = 'hidden'
  536.     notification.style.left = '50%'
  537.     notification.style.transform = 'translateX(-50%)'
  538.     notification.style.fontFamily = 'Roboto'
  539.     notification.classList.add('notificationCustom')
  540.    
  541.     let parent = document.getElementById("fullscreen-body")
  542.     parent.insertBefore(notification, parent.firstChild);
  543.     await sleep(hideAfterSeconds);
  544.     notification.remove()
  545. }
  546.  
  547. const copyImage = async() => {
  548.    
  549.     const image = await exportImageAsync(fSelected())
  550.     const blob = new Blob([image.buffer], { type: 'image/png' })
  551.     const clipimage = new ClipboardItem({
  552.         'image/png': blob
  553.     })
  554.     navigator.clipboard.write([clipimage])
  555.     figma.notify("Image copied to clipboard :)")
  556. }
  557.  
  558. const downloadImage = async() => {
  559.     for ( layer of selected() ) {
  560.         const image = await exportImageAsync(layer)
  561.    
  562.         const link = document.createElement( 'a' );
  563.         link.style.display = 'none';
  564.         document.body.appendChild( link );
  565.    
  566.    
  567.         const blob = new Blob( [ image ], { type: 'text/plain' } );
  568.         const objectURL = URL.createObjectURL( blob );
  569.          
  570.         link.href = objectURL;
  571.         link.href = URL.createObjectURL( blob );
  572.         fileName = `${layer.name}.png`
  573.         link.download =  fileName;
  574.         link.click();
  575.        
  576.         const data = [new ClipboardItem({ [blob.type]: blob })]
  577.         await navigator.clipboard.write(data)
  578.     }
  579. }
  580.  
  581. document.addEventListener('keydown', function(event) {
  582.   if (event.shiftKey && event.ctrlKey &&  event.key === 'E') {
  583.     downloadImage()
  584.   }
  585. });
  586.  
  587. document.addEventListener('keydown', function(event) {
  588.   if (event.ctrlKey && event.altKey && event.which === 69) {
  589.     copyImage()
  590.   }
  591. });
  592.  
  593.  
  594.  
  595.  
  596. const markApproved = () => {
  597.     layer = selected()[0]
  598.     if (layer.name.includes("✅✅ ")) {
  599.         layer.name = layer.name.replace("✅✅ ", "")
  600.     } else if (layer.name.charAt(0) == "✅") {
  601.         layer.name = "✅" + layer.name
  602.     } else {
  603.         layer.name = "✅ " + layer.name
  604.     }
  605. }
  606.  
  607. document.addEventListener('keydown', function(event) {
  608.   if (event.shiftKey && event.key === ' ') {
  609.     markApproved()
  610.   }
  611. });
  612.  
  613.  
  614.  
  615.  
  616.  
  617.  
  618.  
  619. const saveFgLayer = () => {
  620.     fgLayer = fSelected()
  621. }
  622.  
  623. const pasteSelectedLayerOverCopiedLayer = () => {
  624.     bgLayer = fSelected()
  625.     bgLayer.parent
  626.     bgParentChildren = bgLayer.parent.children
  627.      
  628.     orderOfSelectedLayerInGroup = 0
  629.     for (let x = 0; x<bgParentChildren.length; x++) {
  630.         l(bgParentChildren[x])
  631.         if (bgParentChildren[x].id == bgLayer.id) {
  632.             break
  633.         }
  634.         orderOfSelectedLayerInGroup += 1
  635.     }
  636.    
  637.     bgLayer.parent.insertChild(orderOfSelectedLayerInGroup+1, fgLayer)
  638.     figma.currentPage.selection = [fgLayer]
  639. }
  640.  
  641. document.addEventListener('keydown', function(event) {
  642.   if (event.altKey && event.shiftKey && event.key === 'Ç') {
  643.     l("layerindexcopied")
  644.     saveFgLayer()
  645.   }
  646. });
  647. document.addEventListener('keydown', function(event) {
  648.   if (event.altKey && event.shiftKey && event.key === '◊') {
  649.     l("layerindexpasted")
  650.     pasteSelectedLayerOverCopiedLayer()
  651.   }
  652. });
  653.  
  654.  
  655.  
  656. const increaseSpace = () => {
  657.     let selection = selected()
  658.     selection = [].concat(selection)
  659.     selection.sort(function(a, b) {return a.x - b.x})
  660.  
  661.     let addBy = 1
  662.  
  663.     for (let layer = 1; layer < selection.length; layer++) {
  664.         l(selection[layer].name)
  665.         selection[layer].x = selection[layer].x + addBy
  666.         addBy += 1
  667.     }
  668. }
  669.  
  670. const decreaseSpace = () => {
  671.     let selection = selected()
  672.     selection = [].concat(selection)
  673.     selection.sort(function(a, b) {return a.x - b.x})
  674.  
  675.     let subtractBy = 1
  676.  
  677.     for (let layer = 1; layer < selection.length; layer++) {
  678.         l(selection[layer].name)
  679.         selection[layer].x = selection[layer].x - subtractBy
  680.         subtractBy += 1
  681.     }
  682. }
  683.  
  684. const increaseSpaceVertical = () => {
  685.     let selection = selected()
  686.     selection = [].concat(selection)
  687.     selection.sort(function(a, b) {return a.y - b.y})
  688.  
  689.     let subtractBy = 1
  690.  
  691.     for (let layer = 1; layer < selection.length; layer++) {
  692.         l(selection[layer].name)
  693.         selection[layer].y = selection[layer].y + subtractBy
  694.         subtractBy += 1
  695.     }
  696. }
  697.  
  698. const decreaseSpaceVertical = () => {
  699.     let selection = selected()
  700.     selection = [].concat(selection)
  701.     selection.sort(function(a, b) {return a.y - b.y})
  702.  
  703.     let subtractBy = 1
  704.  
  705.     for (let layer = 1; layer < selection.length; layer++) {
  706.         l(selection[layer].name)
  707.         selection[layer].y = selection[layer].y - subtractBy
  708.         subtractBy += 1
  709.     }
  710. }
  711.  
  712.  
  713. document.addEventListener('keydown', function(event) {
  714.   if (event.altKey && event.key === '≠') {
  715.     increaseSpace()
  716.   }
  717.   else if (event.altKey && event.key === '–') {
  718.     decreaseSpace()
  719.   }
  720.   else if (event.altKey && event.key === '‘') {
  721.     increaseSpaceVertical()
  722.   }
  723.   else if (event.altKey && event.key === '“') {
  724.     decreaseSpaceVertical()
  725.   }
  726. });
  727.  
  728.  
  729. // document.addEventListener('keydown', function(event) {
  730. //  if (event.ctrlKey && event.key === 'u') {
  731. //      const layer = figma.union(selected(), fSelected().parent)
  732. //      figma.currentPage.selection = [layer]
  733. //  } else if (event.ctrlKey && event.key === 's') {
  734. //      const layer = figma.subtract(selected(), fSelected().parent)
  735. //      figma.currentPage.selection = [layer]
  736. //  }
  737. // })
  738.  
  739.  
  740.  
  741. document.addEventListener('keydown', function(event) {
  742.     if (!(event.ctrlKey)) return
  743.     const booleanOperations = {u: figma.union, s: figma.subtract}
  744.     if (!(Object.keys(booleanOperations).includes(event.key))) return
  745.     let operation = booleanOperations[event.key]
  746.     let layer = operation(selected(), fSelected().parent)
  747.     figma.currentPage.selection = [layer]
  748. })
  749.  
  750.  
  751.  
  752.  
  753.  
  754.  
  755.  
  756. // document.addEventListener('keydown', function(event) {
  757. //  const operatorsDecimal = {
  758. //      x: {
  759. //          'ArrowRight': function() { return fSelected().x - 0.9 },
  760. //          'ArrowLeft': function() { return fSelected().x + 0.9 }
  761. //      },
  762. //      y: {
  763. //          'ArrowUp': function() { return fSelected().y - 0.9 },
  764. //          'ArrowDown': function() { return fSelected().y + 0.9 },
  765. //      }
  766. //  }
  767. //  if (!event.altKey) return
  768. //  fSelected().x = operatorsDecimal.x[event.key]()
  769. //  fSelected().y = operatorsDecimal.y[event.key]()
  770. // });
  771.  
  772.  
  773.  
  774.  
  775.  
  776. // document.addEventListener('keydown', function(event) {
  777. //  if (event.shiftKey) return
  778. //  const operatorsDecimal = {
  779. //      x: {
  780. //          'ArrowRight': function() { return Math.round(fSelected().x * 10)/10 - 0.9 },
  781. //          'ArrowLeft': function() { return Math.round(fSelected().x * 10)/10 + 0.9 }
  782. //      },
  783. //      y: {
  784. //          'ArrowUp': function() { return Math.round(fSelected().y * 10)/10 + 0.9 },
  785. //          'ArrowDown': function() { return Math.round(fSelected().y * 10)/10 - 0.9 },
  786. //      }
  787. //  }
  788. //  for (let i of Object.keys(operatorsDecimal)) {
  789. //      if (!(event.altKey && event.ctrlKey && Object.keys(operatorsDecimal[i]).includes(event.key))) continue
  790. //      if (Object.keys(operatorsDecimal[i]).includes(event.key)){
  791. //          fSelected()[i] = operatorsDecimal[i][event.key]()
  792. //      }
  793. //  }
  794. // });
  795.  
  796.  
  797.  
  798.  
  799.  
  800.  
  801.  
  802. let previouslySelected = null
  803. previouslySelectedArray = []
  804. previouslySelectedArrayLastTen = []
  805.  
  806. let focusSwitched = setInterval(function() {
  807.     if (fSelected() == undefined) return
  808.     if (previouslySelected == null) {
  809.         previouslySelected = fSelected()
  810.     }
  811.  
  812.    if (previouslySelected.id != fSelected().id) {
  813.       previouslySelected = fSelected()
  814.    }
  815.     currentlySelected = selected().map(el => el.id).toString()
  816.     wasPreviouslySelected = previouslySelectedArray.map(el => el.id).toString()
  817.     if (currentlySelected == wasPreviouslySelected) return
  818.     previouslySelectedArray = selected()
  819.     if (fSelected().parent.id != '638:3349') {
  820.         previouslySelectedArrayLastTen.push(...previouslySelectedArray)
  821.         if (previouslySelectedArrayLastTen.length > 10) {
  822.             previouslySelectedArrayLastTen = previouslySelectedArrayLastTen.slice(Math.max(previouslySelectedArrayLastTen.length - 10, 0))
  823.         }
  824.     }
  825.     l("changed")
  826. }, 100); // check every 100ms
  827.  
  828.  
  829.  
  830. const getBottomLayerOfArchive = () => {
  831.     archive = new Archive().page
  832.     children = [ ...archive.children]
  833.     children.sort(function(a, b) {return a.y - b.y})
  834.     bottomLayer = children.slice(-1)[0]
  835.     return bottomLayer
  836. }
  837.  
  838. const getRightLayerOfArchive = () => {
  839.     archive = new Archive().page
  840.     children = [ ...archive.children]
  841.     children.sort(function(a, b) {return a.x - b.x})
  842.     rightLayer = children.slice(-1)[0]
  843.     return rightLayer
  844. }
  845.  
  846. const getDateFromStr = (str) => {
  847.     str = str.split("|").slice(-1)[0].split(" ").filter(el => el != "")
  848.     let dateLayer = str[0]
  849.     return dateLayer
  850. }
  851.  
  852. const dateOfBottomLayerIsDifferent = () => {
  853.     let dateAndTimeLayer = getRightLayerOfArchive().name
  854.     let dateLayer = getDateFromStr(dateAndTimeLayer)
  855.     let currentDate = getDateFromStr(getStrDate())
  856.     return !( [currentDate, dateLayer].every((val, i, arr) => val == arr[0]) )
  857. }
  858.  
  859. const getFurthestXLayerX = (layers) => {
  860.     let biggestXLayerValue = Number.NEGATIVE_INFINITY
  861.     let biggestXLayer = null
  862.     for (const layer of layers) {
  863.         if ( layer.x > biggestXLayerValue ) {
  864.             biggestXLayerValue = layer.x
  865.             biggestXLayer = layer
  866.         }
  867.     }
  868.     return biggestXLayer.x
  869. }
  870.  
  871. const getXCoordToPutNewDayLayer = () => {
  872.     const dateAndTimeLayer = getRightLayerOfArchive()
  873.     const layers = archive.findAll(
  874.         layer => layer.name.includes(
  875.             getDateFromStr(dateAndTimeLayer.name)
  876.         )
  877.     )
  878.     const widths = layers.map(layer => layer.width)
  879.     const maxWidth = Math.max(...widths)
  880.     const furthestXLayerX = getFurthestXLayerX(layers)
  881.     return furthestXLayerX + maxWidth + 500
  882. }
  883.  
  884.  
  885. document.addEventListener("keydown", function(event) {
  886.     if (event.which == 8 && event.shiftKey && event.altKey) {
  887.         if (
  888.             // selected().length && selected().map((el) => el.type).every( (val, i, arr) => {l(val); return val === arr[0] && (val == "FRAME" && arr[0] == "FRAME")})
  889.             selected().length
  890.         ) {
  891.                 const archive = new Archive
  892.                  for (layer of selected()) {
  893.                     layer.name = layer.name + " | " + getStrDate()
  894.                     rightLayer = getRightLayerOfArchive()
  895.                     if (dateOfBottomLayerIsDifferent() ) {
  896.                         archive.page.appendChild(layer)
  897.                         layer.x = getXCoordToPutNewDayLayer()
  898.                         layer.y = 5915
  899.                     } else {
  900.                         archive.page.appendChild(layer)
  901.                         layer.x = rightLayer.x
  902.                         layer.y = rightLayer.y + rightLayer.height + 200
  903.                     }
  904.                  }
  905.                 archive.removePlaceholder()
  906.                 /*^ in case there were no layers in archive */
  907.                 figma.currentPage.selection = []
  908.      
  909.         }
  910.         }
  911. });
  912.  
  913.  
  914.  
  915. // let dateTimeWorkdayIsFinished = new Date('September 17, 2021 00:36:00');
  916. // let timeLeft = new Date( dateTimeWorkdayIsFinished - Date.now()).toISOString().substr(11, 8)
  917. // document.title = timeLeft
  918.  
  919.  
  920. let timeLeftToEndWorkday = setInterval(function() {
  921.     let dateTimeWorkdayIsFinished = new Date('September 18, 2021 01:17:00');
  922.     if (dateTimeWorkdayIsFinished - Date.now() < 0) {
  923.         return
  924.     }
  925.     let timeLeft = new Date( dateTimeWorkdayIsFinished - Date.now()).toISOString().substr(11, 8)
  926.     document.title = timeLeft
  927. }, 1000)
  928.  
  929.  
  930.  
  931. const layerInCurrentPage = (layer) => {
  932.     if (!(layer)) return
  933.     layer = figma.currentPage.findAll(l => l.id === layer.id)
  934.     return Boolean(layer.length)
  935. }
  936.  
  937. // while
  938.  
  939.  
  940. // figmaIsLoaded = () => {
  941. //  try {
  942. //      figma
  943. //      return true
  944. //  } catch {
  945. //      return false
  946. //  }
  947. // }
  948.  
  949. // while (true) {
  950. //  if ( figmaIsLoaded() ) {
  951. //      Object.prototype.select = function() {figma.currentPage.selection = [this]}
  952. //  }
  953. // }
  954.  
  955.  
  956.  
  957.  
  958. // document.addEventListener('keydown', function(event) {
  959. //  if (!(event.ctrlKey && event.key === 'Enter')) return
  960. //  for (layer of previouslySelectedArray.reverse()) {
  961. //      if (layerInCurrentPage(layer)) {
  962. //          figma.currentPage.
  963. //      }
  964. //  }
  965. // })
  966.  
  967.  
  968.  
  969.  
  970.  
  971.  
  972. const isSpeacialCharAndNotNumber = (inputString) => {
  973.     return inputString
  974.            .match(/^[^a-zA-Z]+$/)
  975.            ? true : false
  976. }
  977.  
  978.  
  979. const enumerate = (array) => {
  980.     return array.map((item, index) => [index, item])
  981. }
  982.  
  983.  
  984. const insertAfterFirsItemOfArray = (array, value) => {
  985.     const newArray = [
  986.         array[0], value, ...array.slice(1)
  987.     ]
  988.     return newArray
  989. }
  990.  
  991.  
  992. const fakeTranslateReplacementForWord = (charObject) => {
  993.     if (charObject.isSpecialOrNumber) {
  994.         return charObject.char
  995.     } else {
  996.         return charObject.fakeTranslateReplacement
  997.     }
  998. }
  999.  
  1000. const defineCharToAdd = (wordObject) => {
  1001.     if (wordObject.isAllUpper) return "P"
  1002.     return "v"
  1003. }
  1004.  
  1005.  
  1006. const fakeTranslateReplacementForStr = (wordObject) => {
  1007.     let word
  1008.  
  1009.     if (wordObject.wholeWordIsSpecialCharOrNumber) {
  1010.         word = wordObject.fakeTranslateReplacement
  1011.         word = word.join("")
  1012.         return word
  1013.     }
  1014.  
  1015.     const fakeTranslateReplacement = wordObject.fakeTranslateReplacement
  1016.  
  1017.     let amountCharsToAdd = 12 - wordObject.length.nonSpecial
  1018.     if (amountCharsToAdd < 0) amountCharsToAdd = 0
  1019.    
  1020.     const charToAdd = defineCharToAdd(wordObject)
  1021.     const charsToAdd = charToAdd.repeat(amountCharsToAdd)
  1022.  
  1023.     word = insertAfterFirsItemOfArray(fakeTranslateReplacement, charsToAdd)
  1024.     word = word.join("")
  1025.     return word
  1026. }
  1027.  
  1028.  
  1029. const convertStrToStrObject = (inputString) => {
  1030.  
  1031.  
  1032.     const strObject = {}
  1033.     strObject.string = inputString
  1034.     strObject.fakeTranslateReplacement = ""
  1035.  
  1036.     const words = inputString.split(" ")
  1037.     const wordObjects = []
  1038.  
  1039.  
  1040.     for (let [wordOrder, word] of enumerate(words)) {
  1041.         const wordObject = {}
  1042.  
  1043.         wordObject.word = word
  1044.         wordObject.fakeTranslateReplacement = []
  1045.         wordObject.specialCharInWord = false
  1046.         wordObject.isLast = wordOrder == words.length-1
  1047.         wordObject.isAllUpper = false
  1048.         wordObject.wholeWordIsSpecialCharOrNumber = false
  1049.  
  1050.         wordObject.length = {}
  1051.         wordObject.length.total = word.length
  1052.         wordObject.length.nonSpecial = 0
  1053.         wordObject.length.special = 0
  1054.  
  1055.         wordObject.chars = []
  1056.        
  1057.         word = Array.from(word)
  1058.         for (const [charOrder, char] of enumerate(word)) {
  1059.             const speacialChar = isSpeacialCharAndNotNumber(char)
  1060.             wordObject.length.nonSpecial += ( () => !speacialChar ? 1 : 0 )()
  1061.             wordObject.length.special += ( () => speacialChar ? 1 : 0 )()
  1062.             wordObject.specialCharInWord = speacialChar
  1063.             strObject.specialCharInStr = speacialChar
  1064.  
  1065.             const charObject = {}
  1066.             charObject.char = char
  1067.             charObject.fakeTranslateReplacement = ""
  1068.             charObject.isSpecialOrNumber = speacialChar
  1069.             charObject.isLast = charOrder == word.length-1
  1070.             charObject.isUpper = char == char.toUpperCase()
  1071.             charObject.fakeTranslateReplacement = charObject.isUpper ? "P" : "v"
  1072.             charObject.charOrder = charOrder
  1073.  
  1074.             wordObject.chars.push(charObject)
  1075.         }
  1076.  
  1077.         wordObject.fakeTranslateReplacement = wordObject.chars.map(
  1078.             charObject => (fakeTranslateReplacementForWord(charObject))
  1079.         )
  1080.  
  1081.         wordObject.isAllUpper = (
  1082.             wordObject.chars
  1083.             .every(char => char.isUpper)
  1084.         )
  1085.  
  1086.         wordObject.wholeWordIsSpecialCharOrNumber = (
  1087.             wordObject.chars
  1088.             .every(char => char.isSpecialOrNumber)
  1089.         )
  1090.  
  1091.         wordObjects.push(wordObject)
  1092.     }
  1093.  
  1094.     strObject.wordObjects = wordObjects
  1095.  
  1096.     let strFakeTranslateReplacement = strObject.wordObjects.map(
  1097.         word => ( fakeTranslateReplacementForStr(word) )
  1098.     )
  1099.     strFakeTranslateReplacement = strFakeTranslateReplacement.join(" ")
  1100.     strObject.fakeTranslateReplacement = strFakeTranslateReplacement
  1101.  
  1102.     return strObject
  1103. }
  1104.  
  1105.  
  1106. const fakeTranslate = async() => {
  1107.  
  1108.     await figma.loadFontAsync( fSelected().fontName )
  1109.     const layersText = fSelected().characters
  1110.    
  1111.     const StrObject = convertStrToStrObject(layersText)
  1112.    
  1113.     fSelected().name = layersText
  1114.     fSelected().characters = StrObject.fakeTranslateReplacement
  1115. }
  1116.  
  1117.  
  1118.  
  1119.  
  1120.  
  1121. const revertTranslate = async() => {
  1122.    
  1123.     await figma.loadFontAsync( fSelected().fontName )
  1124.     fSelected().characters = fSelected().name
  1125. }
  1126.  
  1127.  
  1128.  
  1129.  
  1130.  
  1131.  
  1132.  
  1133.  
  1134. document.addEventListener('keydown', function(event) {
  1135.     /* option + shift + L */
  1136.   if (event.shiftKey && event.altKey && event.which === 76) {
  1137.     l("FAKE traaaaanslate")
  1138.     fakeTranslate()
  1139.   }
  1140. });
  1141.  
  1142.  
  1143. document.addEventListener('keydown', function(event) {
  1144.   if (event.shiftKey && event.altKey && event.key === '') {
  1145.     revertTranslate()
  1146.   }
  1147. });
  1148.  
  1149.  
  1150.  
  1151. const collapseAllCollapsableLayers = () => {
  1152.     const page = figma.currentPage
  1153.     const filterFunction = (layer) => {
  1154.         return layer.expanded != undefined
  1155.     }
  1156.     const collapsableLayers = page.findAll(filterFunction)
  1157.     for (const layer of collapsableLayers) {
  1158.         layer.expanded = false
  1159.     }
  1160. }
  1161.  
  1162. const controlOptionC = {
  1163.     get pressed() {
  1164.         return (
  1165.             event.which == 67 &&
  1166.             event.altKey &&
  1167.             event.ctrlKey
  1168.         )
  1169.     }
  1170. }
  1171.  
  1172.  
  1173. document.addEventListener('keydown', function(event){
  1174.     if (controlOptionC.pressed) {
  1175.         collapseAllCollapsableLayers()
  1176.     }
  1177. })
  1178.  
  1179.  
  1180.  
  1181.  
  1182.  
  1183.  
  1184.  
  1185.  
  1186.  
  1187.  
  1188.  
  1189.  
  1190.  
  1191.  
  1192. const getElementsByPartialClassName = (part) => {
  1193.     return document.querySelectorAll(`[class*=${part}]`)
  1194. }
  1195.  
  1196.  
  1197. const updateSelectedItemsCounter = (cls='selectedCounter') => {
  1198.     setInterval(function(){
  1199.         try {
  1200.         const counter = document.querySelector(`.${cls}`)
  1201.         counter.innerText = figma.currentPage.selection.length
  1202.         } catch {}
  1203.     }, 100)
  1204. }
  1205.  
  1206.  
  1207. const addCounterToToolBar = (
  1208.     cls='selectedCounter',
  1209.     innerText="Selected",
  1210.     width="100px"
  1211. ) => {
  1212.     const counterShell = document.createElement('div')
  1213.    
  1214.     counterShell.style.width = width
  1215.     counterShell.style.background = "black"
  1216.     counterShell.style.padding = "10px 10px 10px 0px"
  1217.     counterShell.style.textAlign = "right"
  1218.     counterShell.style.borderRadius = "6px"
  1219.     counterShell.style.marginRight = "6px"
  1220.     counterShell.style.position = "relative"
  1221.    
  1222.     const counterText = document.createElement('span')
  1223.     counterText.classList.add(cls)
  1224.     try {
  1225.         counterText.innerText = figma.currentPage.selection.length
  1226.     } catch {
  1227.         counterText.innerText = "0"
  1228.     }
  1229.    
  1230.     const infoText = document.createElement('span')
  1231.     infoText.innerText = innerText
  1232.     infoText.style.position = "absolute"
  1233.     infoText.style.left = "10px"
  1234.     infoText.style.color = "#bbbbbb"
  1235.    
  1236.     counterShell.appendChild(counterText)
  1237.     counterShell.appendChild(infoText)
  1238.     toolBar = getElementsByPartialClassName('toolbar_view--sideButtonGroup')[1]
  1239.     toolBar.appendChild(counterShell)
  1240.    
  1241.     updateSelectedItemsCounter()
  1242.  
  1243. }
  1244.  
  1245.  
  1246.  
  1247. document.addEventListener('keydown', async function(event){
  1248.     if (!(event.metaKey && event.which == 190)) return
  1249.     await sleep(100)
  1250.     addCounterToToolBar()
  1251. })
  1252.  
  1253.  
  1254. const shiftAsterisk = {
  1255.     get pressed() {
  1256.         return (
  1257.             event.which == 192 &&
  1258.             event.shiftKey
  1259.         )
  1260.     }
  1261. }
  1262.  
  1263.  
  1264.  
  1265.  
  1266.  
  1267.  
  1268.  
  1269. function *iterateOverSelected() {
  1270.    
  1271.     addCounterToToolBar(cls='mmessage', innerText='iterated', width="150px")
  1272.     const iteratedCounter = document.querySelector(".mmessage")
  1273.     document.addEventListener('keydown', () => {
  1274.         if (!shiftAsterisk.pressed) return
  1275.         iteratedCounter.parentNode.remove()
  1276.     })
  1277.     let sel
  1278.     let order = 0
  1279.     for (const layer of sel = selected()) {
  1280.         if (order == 0) {
  1281.             console.log(
  1282.                 "document.addEventListener(" +
  1283.                     " 'keydown', function(e) {" +
  1284.                 " if (e.key == \"`\") {" +
  1285.                 " s.next()" +
  1286.                 " }})"
  1287.             )
  1288.         }
  1289.         select([layer])
  1290.         figma.viewport.scrollAndZoomIntoView([layer])
  1291.         order++
  1292.         const message = `${order} / ${sel.length}`
  1293.         console.log(message)
  1294.         iteratedCounter.innerText = message
  1295.         yield layer
  1296.     }
  1297.     return iteratedCounter.parentNode.remove()
  1298. }
  1299.  
  1300.  
  1301.  
  1302.  
  1303.  
  1304. const commandOptionG = {
  1305.     get pressed() {
  1306.         return (
  1307.             event.which == 71 &&
  1308.             event.altKey &&
  1309.             event.metaKey
  1310.         )
  1311.     }
  1312. }
  1313.  
  1314.  
  1315.  
  1316. document.addEventListener('keydown', function(event){
  1317.     if (!commandOptionG.pressed) return
  1318.     if (fSelected().fills.some(fill => fill.visible)) return
  1319.     fSelected().fills = []
  1320.    
  1321. })
  1322.  
  1323.  
  1324.  
  1325.  
  1326.  
  1327.  
  1328.  
  1329.  
  1330.  
  1331.  
  1332.  
  1333. let selectedNodes = ""
  1334.  
  1335. const getFrameToSelect = (arraySwitch) => {
  1336.     const toReturn = arraySwitch ? 1 : 0
  1337.     arraySwitch = !arraySwitch
  1338.     return toReturn
  1339. }
  1340.  
  1341. const switchFrameViews = () => {
  1342.  
  1343.     if (selected().length <= 1) return
  1344.  
  1345.     let arraySwitch
  1346.  
  1347.     if ( selectedNodes != selected().map(e => e.id).join("") ) {
  1348.         arraySwitch = true
  1349.         selectedNodes = selected().map(e => e.id).join("")
  1350.     } else {
  1351.         arraySwitch = false
  1352.         selectedNodes = ""
  1353.     }
  1354.  
  1355.     let frameToSelect = getFrameToSelect(arraySwitch)
  1356.     frameToSelect = selected()[frameToSelect]
  1357.     figma.viewport.scrollAndZoomIntoView([frameToSelect])
  1358.     figma.viewport.zoom = 1
  1359.     return frameToSelect
  1360. }
  1361.  
  1362.  
  1363. document.addEventListener('keydown', (event) => {
  1364.    if (!(event.which == 27 && event.shiftKey)) return
  1365.    switchFrameViews()
  1366. })
  1367.  
  1368.  
  1369.  
  1370.  
  1371.  
  1372.  
  1373. const alignLayersVertically = (verticalSpaceInPixels=200) => {
  1374.     let height = 0
  1375.  
  1376.     const layers = Array.from( selected() ).sort(e => e.y)
  1377.    
  1378.     for (layer of layers) {
  1379.    
  1380.         layer.y = layers[0].y + height
  1381.         height += layer.height + verticalSpaceInPixels
  1382.    
  1383.     }
  1384. }
  1385.  
  1386.  
  1387.  
  1388.  
  1389.  
  1390.  
  1391. const figmaFunctions = {
  1392.  
  1393.     "alignLayersVertically(verticalSpaceInPixels: string = 200)": {
  1394.         "howToUse": [
  1395.             `Select layers i want to align verically
  1396.             with 200px
  1397.             `
  1398.         ],
  1399.         use(verticalSpaceInPixels=200) {
  1400.             alignLayersVertically(verticalSpaceInPixels)
  1401.            
  1402.         }
  1403.     }
  1404.    
  1405. }
  1406.  
  1407.  
  1408.  
  1409.  
  1410.  
  1411.  
  1412. /* Move layers without cursor hold (as in Sketch) start */
  1413.  
  1414. const mousePositions = {
  1415.     initial: {
  1416.         x: null,
  1417.         y: null
  1418.     },
  1419.     end: {
  1420.         x: 0,
  1421.         y: 0
  1422.     }
  1423. }
  1424.  
  1425. const releasedKeys = {
  1426.     Alt: false,
  1427.     Control: false
  1428. }
  1429.  
  1430. const pressedKeys = {
  1431.     Shift: false
  1432. }
  1433.  
  1434. let selectedLayers = []
  1435. let selectedLayerXs = []
  1436. let selectedLayerYs = []
  1437.  
  1438. const trackCursorAndMoveLayers = (event) => {
  1439.  
  1440.     if (mousePositions.initial.x == null) {
  1441.         mousePositions.initial.x = event.clientX
  1442.         mousePositions.initial.y = event.clientY
  1443.     }
  1444.  
  1445.     mousePositions.end.x = event.clientX
  1446.     mousePositions.end.y = event.clientY
  1447.  
  1448.     let reduceByX = (mousePositions.initial.x - mousePositions.end.x) * 1 / figma.viewport.zoom
  1449.     let reduceByY = (mousePositions.initial.y - mousePositions.end.y) * 1 / figma.viewport.zoom
  1450.     /*
  1451.         * 1 / figma.viewport.zoom
  1452.         To deal with different scale of the Figma's viewport
  1453.     */
  1454.    
  1455.     // console.log(Math.abs(reduceByX), Math.abs(reduceByY))
  1456.    
  1457.     if (pressedKeys.Shift) {
  1458.         if( Math.abs(reduceByX) > Math.abs(reduceByY) ) {
  1459.             reduceByY = 0
  1460.         } else if( Math.abs(reduceByY) > Math.abs(reduceByX) ) {
  1461.             reduceByX = 0
  1462.         }
  1463.     }
  1464.     /*
  1465.         To move layers with Shift key pressed
  1466.     */
  1467.  
  1468.     for (let selectedLayer = 0; selectedLayer < selectedLayers.length; selectedLayer++) {
  1469.         selectedLayers[selectedLayer].x = Math.round(selectedLayerXs[selectedLayer] - reduceByX)
  1470.         selectedLayers[selectedLayer].y = Math.round(selectedLayerYs[selectedLayer] - reduceByY)
  1471.     }
  1472.  
  1473. }
  1474.  
  1475. const setLayerToMove = (event) => {
  1476.     if (event.key == 'Shift') {
  1477.         pressedKeys.Shift = true
  1478.     }
  1479.     if (!(event.altKey && event.ctrlKey)) return  // 3 keys are pressed
  1480.     selectedLayers = figma.currentPage.selection
  1481.     if (!selectedLayers.length) return
  1482.  
  1483.     for (let selectedLayer = 0; selectedLayer < selectedLayers.length; selectedLayer++) {
  1484.         selectedLayerXs.push(selectedLayers[selectedLayer].x)
  1485.         selectedLayerYs.push(selectedLayers[selectedLayer].y)
  1486.     }
  1487.    
  1488.     document.addEventListener('mousemove', trackCursorAndMoveLayers )
  1489. }
  1490.  
  1491. const unsetLayerToMove = (event) => {
  1492.     if (!(event.key == 'Alt' || event.key == 'Control' || event.key == 'Shift')) return
  1493.    
  1494.     releasedKeys[event.key] = true
  1495.    
  1496.     pressedKeys.Shift = false
  1497.  
  1498.     if (!(releasedKeys.Alt == true && releasedKeys.Control == true)) return  // 3 keys are released
  1499.     releasedKeys.Alt = false
  1500.     releasedKeys.Control = false
  1501.  
  1502.     selectedLayers = []
  1503.     selectedLayerXs = []
  1504.     selectedLayerYs = []
  1505.    
  1506.     document.removeEventListener('mousemove', trackCursorAndMoveLayers )
  1507.    
  1508.     mousePositions.initial.x = null
  1509.     mousePositions.initial.y = null
  1510. }
  1511.  
  1512. document.addEventListener('keydown', setLayerToMove )
  1513. document.addEventListener('keyup', unsetLayerToMove )
  1514.  
  1515.  
  1516. /* Move layers without cursor hold (as in Sketch) end */
  1517.  
  1518.  
  1519.  
  1520.  
  1521.  
  1522.  
  1523.  
  1524.  
  1525. let view = {
  1526.     page: null,
  1527.     center: null,
  1528.     zoom: null
  1529. }
  1530.  
  1531. const bookmarkView = () => {
  1532.     view.page = figma.currentPage
  1533.     view.center = figma.viewport.center
  1534.     view.zoom = figma.viewport.zoom
  1535.  
  1536.     sendNotification("View bookmarked")
  1537. }
  1538.  
  1539. const gotoBookmarkedView = () => {
  1540.    
  1541.     if (view.page == null) {
  1542.         sendNotification("Bookmark view first")
  1543.         return
  1544.     }
  1545.    
  1546.     figma.currentPage = view.page
  1547.     figma.viewport.center = view.center
  1548.     figma.viewport.zoom = view.zoom
  1549.  
  1550.     sendNotification("Switched to bookmarked view")
  1551. }
  1552.  
  1553.  
  1554. const pressedKeysForBookmark = {
  1555.     32: false, // space
  1556. }
  1557.  
  1558. const doBookmarkAction = (event) => {
  1559.  
  1560.     if (![32, 66, 71].includes(event.which)) return
  1561.    
  1562.     pressedKeysForBookmark[event.which] = true
  1563.    
  1564.     if (!pressedKeysForBookmark[32]) return
  1565.    
  1566.     switch (event.which) {
  1567.         case 66:
  1568.             bookmarkView()
  1569.             break
  1570.         case 71:
  1571.             gotoBookmarkedView()
  1572.             break
  1573.     }
  1574.  
  1575. }
  1576.  
  1577.  
  1578. const updatePressedKeys = (event) => {
  1579.     if (!(event.which == 32)) return
  1580.     pressedKeysForBookmark[32] = false
  1581. }
  1582.  
  1583. document.addEventListener('keydown', doBookmarkAction )
  1584. document.addEventListener('keyup', updatePressedKeys )
  1585.  
  1586.  
  1587.  
  1588.  
  1589.  
  1590. const keysPressedForBgRename = {
  1591.     66: {  // B
  1592.         isPressed: false,
  1593.         timestamp: Infinity
  1594.     },
  1595.     71: {  // G
  1596.         isPressed: false,
  1597.         timestamp: Infinity
  1598.     },
  1599. }
  1600.  
  1601. const renameToBg = (event) => {
  1602.     if (event.which == 66 || event.which == 71) {
  1603.  
  1604.         keysPressedForBgRename[event.which].isPressed = true
  1605.         keysPressedForBgRename[event.which].timestamp = event.timeStamp
  1606.        
  1607.         // console.log('rename', fSelected());
  1608.  
  1609.         if (
  1610.             Object.values(keysPressedForBgRename)
  1611.             .every(v => v.isPressed) &&
  1612.             Math.abs(
  1613.                 keysPressedForBgRename[66].timestamp -
  1614.                 keysPressedForBgRename[71].timestamp
  1615.             ) < 100
  1616.         ) {
  1617.             keysPressedForBgRename[66].isPressed = false
  1618.             keysPressedForBgRename[71].isPressed = false
  1619.            
  1620.            
  1621.             if (
  1622.                 fSelected() &&
  1623.                 ['RECTANGLE', 'ELLIPSE']
  1624.                 .includes(fSelected().type)
  1625.             ) {
  1626.                 fSelected().name = 'Background'
  1627.             }
  1628.         }
  1629.         return
  1630.     }
  1631.     keysPressedForBgRename[66].isPressed = false
  1632.     keysPressedForBgRename[71].isPressed = false
  1633. }
  1634.  
  1635.  
  1636. document.addEventListener('keydown', renameToBg)
  1637.  
  1638.  
  1639.  
  1640.  
  1641.  
  1642.  
  1643.  
  1644. /* Batch rename layers START */
  1645.  
  1646.  
  1647. const insertCharsIntoChildrenName = (strToInsert = 'Note = false') => {
  1648.  
  1649.     for (child of fSelected().children) {
  1650.  
  1651.         addChars = []
  1652.  
  1653.         if (!child.name.endsWith(",") ) addChars.push(",")
  1654.         if (!child.name.endsWith(" ") ) addChars.push(" ")
  1655.        
  1656.         child.name = child.name +
  1657.         addChars.join("") + ' ' + strToInsert
  1658.  
  1659.     }
  1660. }
  1661.  
  1662.  
  1663. /* Batch rename layers END */
  1664.  
  1665.  
  1666.  
  1667.  
  1668.  
  1669. const changeLineHeight = async (lineHeight, layerToChange = null) => {
  1670.  
  1671.     const selection = figma.currentPage.selection
  1672.     const selectedLayer = selection[0]
  1673.     const layer = layerToChange ?? selectedLayer
  1674.     if (!layer) return
  1675.  
  1676.     const fontName = layer.fontName
  1677.     await figma.loadFontAsync(fontName)
  1678.  
  1679.     const prevHeight = layer.height
  1680.    
  1681.     layer.lineHeight = {
  1682.         unit: "PIXELS",
  1683.         value: lineHeight
  1684.     }
  1685.  
  1686.     layer.y = Math.ceil( layer.y - ( ( layer.height - prevHeight ) / 2 ) )
  1687.  
  1688. }
  1689.  
  1690. const changeLineHeightOfSelected = (lineHeight) => {
  1691.     for (let layer of figma.currentPage.selection) {
  1692.         changeLineHeight(lineHeight, layer)
  1693.     }
  1694. }
Add Comment
Please, Sign In to add comment