kopyl

Figma plugin October 27

Oct 27th, 2021 (edited)
212
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=500) => {
  524.     let notification = document.createElement("p")
  525.     notification.innerText = message
  526.     notification.style.textAlign = "center"
  527.     notification.style.padding = "20px 0 20px 0"
  528.     notification.style.zIndex = "100"
  529.    
  530.     let parent = document.getElementById("fullscreen-body")
  531.     parent.insertBefore(notification, parent.firstChild);
  532.     await sleep(hideAfterSeconds);
  533.     notification.remove()
  534. }
  535.  
  536. const copyImage = async() => {
  537.    
  538.     const image = await exportImageAsync(fSelected())
  539.     const blob = new Blob([image.buffer], { type: 'image/png' })
  540.     const clipimage = new ClipboardItem({
  541.         'image/png': blob
  542.     })
  543.     navigator.clipboard.write([clipimage])
  544.     figma.notify("Image copied to clipboard :)")
  545. }
  546.  
  547. const downloadImage = async() => {
  548.     for ( layer of selected() ) {
  549.         const image = await exportImageAsync(layer)
  550.    
  551.         const link = document.createElement( 'a' );
  552.         link.style.display = 'none';
  553.         document.body.appendChild( link );
  554.    
  555.    
  556.         const blob = new Blob( [ image ], { type: 'text/plain' } );
  557.         const objectURL = URL.createObjectURL( blob );
  558.          
  559.         link.href = objectURL;
  560.         link.href = URL.createObjectURL( blob );
  561.         fileName = `${layer.name}.png`
  562.         link.download =  fileName;
  563.         link.click();
  564.        
  565.         const data = [new ClipboardItem({ [blob.type]: blob })]
  566.         await navigator.clipboard.write(data)
  567.     }
  568. }
  569.  
  570. document.addEventListener('keydown', function(event) {
  571.   if (event.shiftKey && event.ctrlKey &&  event.key === 'E') {
  572.     downloadImage()
  573.   }
  574. });
  575.  
  576. document.addEventListener('keydown', function(event) {
  577.   if (event.ctrlKey && event.altKey && event.which === 69) {
  578.     copyImage()
  579.   }
  580. });
  581.  
  582.  
  583.  
  584.  
  585. const markApproved = () => {
  586.     layer = selected()[0]
  587.     if (layer.name.includes("✅✅ ")) {
  588.         layer.name = layer.name.replace("✅✅ ", "")
  589.     } else if (layer.name.charAt(0) == "✅") {
  590.         layer.name = "✅" + layer.name
  591.     } else {
  592.         layer.name = "✅ " + layer.name
  593.     }
  594. }
  595.  
  596. document.addEventListener('keydown', function(event) {
  597.   if (event.shiftKey && event.key === ' ') {
  598.     markApproved()
  599.   }
  600. });
  601.  
  602.  
  603.  
  604.  
  605.  
  606.  
  607.  
  608. const saveFgLayer = () => {
  609.     fgLayer = fSelected()
  610. }
  611.  
  612. const pasteSelectedLayerOverCopiedLayer = () => {
  613.     bgLayer = fSelected()
  614.     bgLayer.parent
  615.     bgParentChildren = bgLayer.parent.children
  616.      
  617.     orderOfSelectedLayerInGroup = 0
  618.     for (let x = 0; x<bgParentChildren.length; x++) {
  619.         l(bgParentChildren[x])
  620.         if (bgParentChildren[x].id == bgLayer.id) {
  621.             break
  622.         }
  623.         orderOfSelectedLayerInGroup += 1
  624.     }
  625.    
  626.     bgLayer.parent.insertChild(orderOfSelectedLayerInGroup+1, fgLayer)
  627.     figma.currentPage.selection = [fgLayer]
  628. }
  629.  
  630. document.addEventListener('keydown', function(event) {
  631.   if (event.altKey && event.shiftKey && event.key === 'Ç') {
  632.     l("layerindexcopied")
  633.     saveFgLayer()
  634.   }
  635. });
  636. document.addEventListener('keydown', function(event) {
  637.   if (event.altKey && event.shiftKey && event.key === '◊') {
  638.     l("layerindexpasted")
  639.     pasteSelectedLayerOverCopiedLayer()
  640.   }
  641. });
  642.  
  643.  
  644.  
  645. const increaseSpace = () => {
  646.     let selection = selected()
  647.     selection = [].concat(selection)
  648.     selection.sort(function(a, b) {return a.x - b.x})
  649.  
  650.     let addBy = 1
  651.  
  652.     for (let layer = 1; layer < selection.length; layer++) {
  653.         l(selection[layer].name)
  654.         selection[layer].x = selection[layer].x + addBy
  655.         addBy += 1
  656.     }
  657. }
  658.  
  659. const decreaseSpace = () => {
  660.     let selection = selected()
  661.     selection = [].concat(selection)
  662.     selection.sort(function(a, b) {return a.x - b.x})
  663.  
  664.     let subtractBy = 1
  665.  
  666.     for (let layer = 1; layer < selection.length; layer++) {
  667.         l(selection[layer].name)
  668.         selection[layer].x = selection[layer].x - subtractBy
  669.         subtractBy += 1
  670.     }
  671. }
  672.  
  673. const increaseSpaceVertical = () => {
  674.     let selection = selected()
  675.     selection = [].concat(selection)
  676.     selection.sort(function(a, b) {return a.y - b.y})
  677.  
  678.     let subtractBy = 1
  679.  
  680.     for (let layer = 1; layer < selection.length; layer++) {
  681.         l(selection[layer].name)
  682.         selection[layer].y = selection[layer].y + subtractBy
  683.         subtractBy += 1
  684.     }
  685. }
  686.  
  687. const decreaseSpaceVertical = () => {
  688.     let selection = selected()
  689.     selection = [].concat(selection)
  690.     selection.sort(function(a, b) {return a.y - b.y})
  691.  
  692.     let subtractBy = 1
  693.  
  694.     for (let layer = 1; layer < selection.length; layer++) {
  695.         l(selection[layer].name)
  696.         selection[layer].y = selection[layer].y - subtractBy
  697.         subtractBy += 1
  698.     }
  699. }
  700.  
  701.  
  702. document.addEventListener('keydown', function(event) {
  703.   if (event.altKey && event.key === '≠') {
  704.     increaseSpace()
  705.   }
  706.   else if (event.altKey && event.key === '–') {
  707.     decreaseSpace()
  708.   }
  709.   else if (event.altKey && event.key === '‘') {
  710.     increaseSpaceVertical()
  711.   }
  712.   else if (event.altKey && event.key === '“') {
  713.     decreaseSpaceVertical()
  714.   }
  715. });
  716.  
  717.  
  718. // document.addEventListener('keydown', function(event) {
  719. //  if (event.ctrlKey && event.key === 'u') {
  720. //      const layer = figma.union(selected(), fSelected().parent)
  721. //      figma.currentPage.selection = [layer]
  722. //  } else if (event.ctrlKey && event.key === 's') {
  723. //      const layer = figma.subtract(selected(), fSelected().parent)
  724. //      figma.currentPage.selection = [layer]
  725. //  }
  726. // })
  727.  
  728.  
  729.  
  730. document.addEventListener('keydown', function(event) {
  731.     if (!(event.ctrlKey)) return
  732.     const booleanOperations = {u: figma.union, s: figma.subtract}
  733.     if (!(Object.keys(booleanOperations).includes(event.key))) return
  734.     let operation = booleanOperations[event.key]
  735.     let layer = operation(selected(), fSelected().parent)
  736.     figma.currentPage.selection = [layer]
  737. })
  738.  
  739.  
  740.  
  741.  
  742.  
  743.  
  744.  
  745. // document.addEventListener('keydown', function(event) {
  746. //  const operatorsDecimal = {
  747. //      x: {
  748. //          'ArrowRight': function() { return fSelected().x - 0.9 },
  749. //          'ArrowLeft': function() { return fSelected().x + 0.9 }
  750. //      },
  751. //      y: {
  752. //          'ArrowUp': function() { return fSelected().y - 0.9 },
  753. //          'ArrowDown': function() { return fSelected().y + 0.9 },
  754. //      }
  755. //  }
  756. //  if (!event.altKey) return
  757. //  fSelected().x = operatorsDecimal.x[event.key]()
  758. //  fSelected().y = operatorsDecimal.y[event.key]()
  759. // });
  760.  
  761.  
  762.  
  763.  
  764.  
  765. // document.addEventListener('keydown', function(event) {
  766. //  if (event.shiftKey) return
  767. //  const operatorsDecimal = {
  768. //      x: {
  769. //          'ArrowRight': function() { return Math.round(fSelected().x * 10)/10 - 0.9 },
  770. //          'ArrowLeft': function() { return Math.round(fSelected().x * 10)/10 + 0.9 }
  771. //      },
  772. //      y: {
  773. //          'ArrowUp': function() { return Math.round(fSelected().y * 10)/10 + 0.9 },
  774. //          'ArrowDown': function() { return Math.round(fSelected().y * 10)/10 - 0.9 },
  775. //      }
  776. //  }
  777. //  for (let i of Object.keys(operatorsDecimal)) {
  778. //      if (!(event.altKey && event.ctrlKey && Object.keys(operatorsDecimal[i]).includes(event.key))) continue
  779. //      if (Object.keys(operatorsDecimal[i]).includes(event.key)){
  780. //          fSelected()[i] = operatorsDecimal[i][event.key]()
  781. //      }
  782. //  }
  783. // });
  784.  
  785.  
  786.  
  787.  
  788.  
  789.  
  790.  
  791. let previouslySelected = null
  792. previouslySelectedArray = []
  793. previouslySelectedArrayLastTen = []
  794.  
  795. let focusSwitched = setInterval(function() {
  796.     if (fSelected() == undefined) return
  797.     if (previouslySelected == null) {
  798.         previouslySelected = fSelected()
  799.     }
  800.  
  801.    if (previouslySelected.id != fSelected().id) {
  802.       previouslySelected = fSelected()
  803.    }
  804.     currentlySelected = selected().map(el => el.id).toString()
  805.     wasPreviouslySelected = previouslySelectedArray.map(el => el.id).toString()
  806.     if (currentlySelected == wasPreviouslySelected) return
  807.     previouslySelectedArray = selected()
  808.     if (fSelected().parent.id != '638:3349') {
  809.         previouslySelectedArrayLastTen.push(...previouslySelectedArray)
  810.         if (previouslySelectedArrayLastTen.length > 10) {
  811.             previouslySelectedArrayLastTen = previouslySelectedArrayLastTen.slice(Math.max(previouslySelectedArrayLastTen.length - 10, 0))
  812.         }
  813.     }
  814.     l("changed")
  815. }, 100); // check every 100ms
  816.  
  817.  
  818.  
  819. const getBottomLayerOfArchive = () => {
  820.     archive = new Archive().page
  821.     children = [ ...archive.children]
  822.     children.sort(function(a, b) {return a.y - b.y})
  823.     bottomLayer = children.slice(-1)[0]
  824.     return bottomLayer
  825. }
  826.  
  827. const getRightLayerOfArchive = () => {
  828.     archive = new Archive().page
  829.     children = [ ...archive.children]
  830.     children.sort(function(a, b) {return a.x - b.x})
  831.     rightLayer = children.slice(-1)[0]
  832.     return rightLayer
  833. }
  834.  
  835. const getDateFromStr = (str) => {
  836.     str = str.split("|").slice(-1)[0].split(" ").filter(el => el != "")
  837.     let dateLayer = str[0]
  838.     return dateLayer
  839. }
  840.  
  841. const dateOfBottomLayerIsDifferent = () => {
  842.     let dateAndTimeLayer = getRightLayerOfArchive().name
  843.     let dateLayer = getDateFromStr(dateAndTimeLayer)
  844.     let currentDate = getDateFromStr(getStrDate())
  845.     return !( [currentDate, dateLayer].every((val, i, arr) => val == arr[0]) )
  846. }
  847.  
  848. const getFurthestXLayerX = (layers) => {
  849.     let biggestXLayerValue = Number.NEGATIVE_INFINITY
  850.     let biggestXLayer = null
  851.     for (const layer of layers) {
  852.         if ( layer.x > biggestXLayerValue ) {
  853.             biggestXLayerValue = layer.x
  854.             biggestXLayer = layer
  855.         }
  856.     }
  857.     return biggestXLayer.x
  858. }
  859.  
  860. const getXCoordToPutNewDayLayer = () => {
  861.     const dateAndTimeLayer = getRightLayerOfArchive()
  862.     const layers = archive.findAll(
  863.         layer => layer.name.includes(
  864.             getDateFromStr(dateAndTimeLayer.name)
  865.         )
  866.     )
  867.     const widths = layers.map(layer => layer.width)
  868.     const maxWidth = Math.max(...widths)
  869.     const furthestXLayerX = getFurthestXLayerX(layers)
  870.     return furthestXLayerX + maxWidth + 500
  871. }
  872.  
  873.  
  874. document.addEventListener("keydown", function(event) {
  875.     if (event.which == 8 && event.shiftKey && event.altKey) {
  876.         if (
  877.             // selected().length && selected().map((el) => el.type).every( (val, i, arr) => {l(val); return val === arr[0] && (val == "FRAME" && arr[0] == "FRAME")})
  878.             selected().length
  879.         ) {
  880.                 const archive = new Archive
  881.                  for (layer of selected()) {
  882.                     layer.name = layer.name + " | " + getStrDate()
  883.                     rightLayer = getRightLayerOfArchive()
  884.                     if (dateOfBottomLayerIsDifferent() ) {
  885.                         archive.page.appendChild(layer)
  886.                         layer.x = getXCoordToPutNewDayLayer()
  887.                         layer.y = 5915
  888.                     } else {
  889.                         archive.page.appendChild(layer)
  890.                         layer.x = rightLayer.x
  891.                         layer.y = rightLayer.y + rightLayer.height + 200
  892.                     }
  893.                  }
  894.                 archive.removePlaceholder()
  895.                 /*^ in case there were no layers in archive */
  896.                 figma.currentPage.selection = []
  897.      
  898.         }
  899.         }
  900. });
  901.  
  902.  
  903.  
  904. // let dateTimeWorkdayIsFinished = new Date('September 17, 2021 00:36:00');
  905. // let timeLeft = new Date( dateTimeWorkdayIsFinished - Date.now()).toISOString().substr(11, 8)
  906. // document.title = timeLeft
  907.  
  908.  
  909. let timeLeftToEndWorkday = setInterval(function() {
  910.     let dateTimeWorkdayIsFinished = new Date('September 18, 2021 01:17:00');
  911.     if (dateTimeWorkdayIsFinished - Date.now() < 0) {
  912.         return
  913.     }
  914.     let timeLeft = new Date( dateTimeWorkdayIsFinished - Date.now()).toISOString().substr(11, 8)
  915.     document.title = timeLeft
  916. }, 1000)
  917.  
  918.  
  919.  
  920. const layerInCurrentPage = (layer) => {
  921.     if (!(layer)) return
  922.     layer = figma.currentPage.findAll(l => l.id === layer.id)
  923.     return Boolean(layer.length)
  924. }
  925.  
  926. // while
  927.  
  928.  
  929. // figmaIsLoaded = () => {
  930. //  try {
  931. //      figma
  932. //      return true
  933. //  } catch {
  934. //      return false
  935. //  }
  936. // }
  937.  
  938. // while (true) {
  939. //  if ( figmaIsLoaded() ) {
  940. //      Object.prototype.select = function() {figma.currentPage.selection = [this]}
  941. //  }
  942. // }
  943.  
  944.  
  945.  
  946.  
  947. // document.addEventListener('keydown', function(event) {
  948. //  if (!(event.ctrlKey && event.key === 'Enter')) return
  949. //  for (layer of previouslySelectedArray.reverse()) {
  950. //      if (layerInCurrentPage(layer)) {
  951. //          figma.currentPage.
  952. //      }
  953. //  }
  954. // })
  955.  
  956.  
  957.  
  958.  
  959.  
  960.  
  961. const isSpeacialCharAndNotNumber = (inputString) => {
  962.     return inputString
  963.            .match(/^[^a-zA-Z]+$/)
  964.            ? true : false
  965. }
  966.  
  967.  
  968. const enumerate = (array) => {
  969.     return array.map((item, index) => [index, item])
  970. }
  971.  
  972.  
  973. const insertAfterFirsItemOfArray = (array, value) => {
  974.     const newArray = [
  975.         array[0], value, ...array.slice(1)
  976.     ]
  977.     return newArray
  978. }
  979.  
  980.  
  981. const fakeTranslateReplacementForWord = (charObject) => {
  982.     if (charObject.isSpecialOrNumber) {
  983.         return charObject.char
  984.     } else {
  985.         return charObject.fakeTranslateReplacement
  986.     }
  987. }
  988.  
  989. const defineCharToAdd = (wordObject) => {
  990.     if (wordObject.isAllUpper) return "P"
  991.     return "v"
  992. }
  993.  
  994.  
  995. const fakeTranslateReplacementForStr = (wordObject) => {
  996.     let word
  997.  
  998.     if (wordObject.wholeWordIsSpecialCharOrNumber) {
  999.         word = wordObject.fakeTranslateReplacement
  1000.         word = word.join("")
  1001.         return word
  1002.     }
  1003.  
  1004.     const fakeTranslateReplacement = wordObject.fakeTranslateReplacement
  1005.  
  1006.     let amountCharsToAdd = 12 - wordObject.length.nonSpecial
  1007.     if (amountCharsToAdd < 0) amountCharsToAdd = 0
  1008.    
  1009.     const charToAdd = defineCharToAdd(wordObject)
  1010.     const charsToAdd = charToAdd.repeat(amountCharsToAdd)
  1011.  
  1012.     word = insertAfterFirsItemOfArray(fakeTranslateReplacement, charsToAdd)
  1013.     word = word.join("")
  1014.     return word
  1015. }
  1016.  
  1017.  
  1018. const convertStrToStrObject = (inputString) => {
  1019.  
  1020.  
  1021.     const strObject = {}
  1022.     strObject.string = inputString
  1023.     strObject.fakeTranslateReplacement = ""
  1024.  
  1025.     const words = inputString.split(" ")
  1026.     const wordObjects = []
  1027.  
  1028.  
  1029.     for (let [wordOrder, word] of enumerate(words)) {
  1030.         const wordObject = {}
  1031.  
  1032.         wordObject.word = word
  1033.         wordObject.fakeTranslateReplacement = []
  1034.         wordObject.specialCharInWord = false
  1035.         wordObject.isLast = wordOrder == words.length-1
  1036.         wordObject.isAllUpper = false
  1037.         wordObject.wholeWordIsSpecialCharOrNumber = false
  1038.  
  1039.         wordObject.length = {}
  1040.         wordObject.length.total = word.length
  1041.         wordObject.length.nonSpecial = 0
  1042.         wordObject.length.special = 0
  1043.  
  1044.         wordObject.chars = []
  1045.        
  1046.         word = Array.from(word)
  1047.         for (const [charOrder, char] of enumerate(word)) {
  1048.             const speacialChar = isSpeacialCharAndNotNumber(char)
  1049.             wordObject.length.nonSpecial += ( () => !speacialChar ? 1 : 0 )()
  1050.             wordObject.length.special += ( () => speacialChar ? 1 : 0 )()
  1051.             wordObject.specialCharInWord = speacialChar
  1052.             strObject.specialCharInStr = speacialChar
  1053.  
  1054.             const charObject = {}
  1055.             charObject.char = char
  1056.             charObject.fakeTranslateReplacement = ""
  1057.             charObject.isSpecialOrNumber = speacialChar
  1058.             charObject.isLast = charOrder == word.length-1
  1059.             charObject.isUpper = char == char.toUpperCase()
  1060.             charObject.fakeTranslateReplacement = charObject.isUpper ? "P" : "v"
  1061.             charObject.charOrder = charOrder
  1062.  
  1063.             wordObject.chars.push(charObject)
  1064.         }
  1065.  
  1066.         wordObject.fakeTranslateReplacement = wordObject.chars.map(
  1067.             charObject => (fakeTranslateReplacementForWord(charObject))
  1068.         )
  1069.  
  1070.         wordObject.isAllUpper = (
  1071.             wordObject.chars
  1072.             .every(char => char.isUpper)
  1073.         )
  1074.  
  1075.         wordObject.wholeWordIsSpecialCharOrNumber = (
  1076.             wordObject.chars
  1077.             .every(char => char.isSpecialOrNumber)
  1078.         )
  1079.  
  1080.         wordObjects.push(wordObject)
  1081.     }
  1082.  
  1083.     strObject.wordObjects = wordObjects
  1084.  
  1085.     let strFakeTranslateReplacement = strObject.wordObjects.map(
  1086.         word => ( fakeTranslateReplacementForStr(word) )
  1087.     )
  1088.     strFakeTranslateReplacement = strFakeTranslateReplacement.join(" ")
  1089.     strObject.fakeTranslateReplacement = strFakeTranslateReplacement
  1090.  
  1091.     return strObject
  1092. }
  1093.  
  1094.  
  1095. const fakeTranslate = async() => {
  1096.  
  1097.     await figma.loadFontAsync( fSelected().fontName )
  1098.     const layersText = fSelected().characters
  1099.    
  1100.     const StrObject = convertStrToStrObject(layersText)
  1101.    
  1102.     fSelected().name = layersText
  1103.     fSelected().characters = StrObject.fakeTranslateReplacement
  1104. }
  1105.  
  1106.  
  1107.  
  1108.  
  1109.  
  1110. const revertTranslate = async() => {
  1111.    
  1112.     await figma.loadFontAsync( fSelected().fontName )
  1113.     fSelected().characters = fSelected().name
  1114. }
  1115.  
  1116.  
  1117.  
  1118.  
  1119.  
  1120.  
  1121.  
  1122.  
  1123. document.addEventListener('keydown', function(event) {
  1124.     /* option + shift + L */
  1125.   if (event.shiftKey && event.altKey && event.which === 76) {
  1126.     l("FAKE traaaaanslate")
  1127.     fakeTranslate()
  1128.   }
  1129. });
  1130.  
  1131.  
  1132. document.addEventListener('keydown', function(event) {
  1133.   if (event.shiftKey && event.altKey && event.key === '') {
  1134.     revertTranslate()
  1135.   }
  1136. });
  1137.  
  1138.  
  1139.  
  1140. const collapseAllCollapsableLayers = () => {
  1141.     const page = figma.currentPage
  1142.     const filterFunction = (layer) => {
  1143.         return layer.expanded != undefined
  1144.     }
  1145.     const collapsableLayers = page.findAll(filterFunction)
  1146.     for (const layer of collapsableLayers) {
  1147.         layer.expanded = false
  1148.     }
  1149. }
  1150.  
  1151. const controlOptionC = {
  1152.     get pressed() {
  1153.         return (
  1154.             event.which == 67 &&
  1155.             event.altKey &&
  1156.             event.ctrlKey
  1157.         )
  1158.     }
  1159. }
  1160.  
  1161.  
  1162. document.addEventListener('keydown', function(event){
  1163.     if (controlOptionC.pressed) {
  1164.         collapseAllCollapsableLayers()
  1165.     }
  1166. })
  1167.  
  1168.  
  1169.  
  1170.  
  1171.  
  1172.  
  1173.  
  1174.  
  1175.  
  1176.  
  1177.  
  1178.  
  1179.  
  1180.  
  1181. const getElementsByPartialClassName = (part) => {
  1182.     return document.querySelectorAll(`[class*=${part}]`)
  1183. }
  1184.  
  1185.  
  1186. const updateSelectedItemsCounter = (cls='selectedCounter') => {
  1187.     setInterval(function(){
  1188.         try {
  1189.         const counter = document.querySelector(`.${cls}`)
  1190.         counter.innerText = figma.currentPage.selection.length
  1191.         } catch {}
  1192.     }, 100)
  1193. }
  1194.  
  1195.  
  1196. const addCounterToToolBar = (
  1197.     cls='selectedCounter',
  1198.     innerText="Selected",
  1199.     width="100px"
  1200. ) => {
  1201.     const counterShell = document.createElement('div')
  1202.    
  1203.     counterShell.style.width = width
  1204.     counterShell.style.background = "black"
  1205.     counterShell.style.padding = "10px 10px 10px 0px"
  1206.     counterShell.style.textAlign = "right"
  1207.     counterShell.style.borderRadius = "6px"
  1208.     counterShell.style.marginRight = "6px"
  1209.     counterShell.style.position = "relative"
  1210.    
  1211.     const counterText = document.createElement('span')
  1212.     counterText.classList.add(cls)
  1213.     try {
  1214.         counterText.innerText = figma.currentPage.selection.length
  1215.     } catch {
  1216.         counterText.innerText = "0"
  1217.     }
  1218.    
  1219.     const infoText = document.createElement('span')
  1220.     infoText.innerText = innerText
  1221.     infoText.style.position = "absolute"
  1222.     infoText.style.left = "10px"
  1223.     infoText.style.color = "#bbbbbb"
  1224.    
  1225.     counterShell.appendChild(counterText)
  1226.     counterShell.appendChild(infoText)
  1227.     toolBar = getElementsByPartialClassName('toolbar_view--sideButtonGroup')[1]
  1228.     toolBar.appendChild(counterShell)
  1229.    
  1230.     updateSelectedItemsCounter()
  1231.  
  1232. }
  1233.  
  1234.  
  1235.  
  1236. document.addEventListener('keydown', async function(event){
  1237.     if (!(event.metaKey && event.which == 190)) return
  1238.     await sleep(100)
  1239.     addCounterToToolBar()
  1240. })
  1241.  
  1242.  
  1243. const shiftAsterisk = {
  1244.     get pressed() {
  1245.         return (
  1246.             event.which == 192 &&
  1247.             event.shiftKey
  1248.         )
  1249.     }
  1250. }
  1251.  
  1252.  
  1253.  
  1254.  
  1255.  
  1256.  
  1257.  
  1258. function *iterateOverSelected() {
  1259.    
  1260.     addCounterToToolBar(cls='mmessage', innerText='iterated', width="150px")
  1261.     const iteratedCounter = document.querySelector(".mmessage")
  1262.     document.addEventListener('keydown', () => {
  1263.         if (!shiftAsterisk.pressed) return
  1264.         iteratedCounter.parentNode.remove()
  1265.     })
  1266.     let sel
  1267.     let order = 0
  1268.     for (const layer of sel = selected()) {
  1269.         if (order == 0) {
  1270.             console.log(
  1271.                 "document.addEventListener(" +
  1272.                     " 'keydown', function(e) {" +
  1273.                 " if (e.key == \"`\") {" +
  1274.                 " s.next()" +
  1275.                 " }})"
  1276.             )
  1277.         }
  1278.         select([layer])
  1279.         figma.viewport.scrollAndZoomIntoView([layer])
  1280.         order++
  1281.         const message = `${order} / ${sel.length}`
  1282.         console.log(message)
  1283.         iteratedCounter.innerText = message
  1284.         yield layer
  1285.     }
  1286.     return iteratedCounter.parentNode.remove()
  1287. }
  1288.  
  1289.  
  1290.  
  1291.  
  1292.  
  1293. const commandOptionG = {
  1294.     get pressed() {
  1295.         return (
  1296.             event.which == 71 &&
  1297.             event.altKey &&
  1298.             event.metaKey
  1299.         )
  1300.     }
  1301. }
  1302.  
  1303.  
  1304.  
  1305. document.addEventListener('keydown', function(event){
  1306.     if (!commandOptionG.pressed) return
  1307.     if (fSelected().fills.some(fill => fill.visible)) return
  1308.     fSelected().fills = []
  1309.    
  1310. })
  1311.  
  1312.  
  1313.  
  1314.  
  1315.  
  1316.  
  1317.  
  1318.  
  1319.  
  1320.  
  1321.  
  1322. let selectedNodes = ""
  1323.  
  1324. const getFrameToSelect = (arraySwitch) => {
  1325.     const toReturn = arraySwitch ? 1 : 0
  1326.     arraySwitch = !arraySwitch
  1327.     return toReturn
  1328. }
  1329.  
  1330. const switchFrameViews = () => {
  1331.  
  1332.     if (selected().length <= 1) return
  1333.  
  1334.     let arraySwitch
  1335.  
  1336.     if ( selectedNodes != selected().map(e => e.id).join("") ) {
  1337.         arraySwitch = true
  1338.         selectedNodes = selected().map(e => e.id).join("")
  1339.     } else {
  1340.         arraySwitch = false
  1341.         selectedNodes = ""
  1342.     }
  1343.  
  1344.     let frameToSelect = getFrameToSelect(arraySwitch)
  1345.     frameToSelect = selected()[frameToSelect]
  1346.     figma.viewport.scrollAndZoomIntoView([frameToSelect])
  1347.     figma.viewport.zoom = 1
  1348.     return frameToSelect
  1349. }
  1350.  
  1351.  
  1352. document.addEventListener('keydown', (event) => {
  1353.    if (!(event.which == 27 && event.shiftKey)) return
  1354.    switchFrameViews()
  1355. })
  1356.  
  1357.  
  1358.  
  1359.  
  1360.  
  1361.  
  1362. const alignLayersVertically = (verticalSpaceInPixels=200) => {
  1363.     let height = 0
  1364.  
  1365.     const layers = Array.from( selected() ).sort(e => e.y)
  1366.    
  1367.     for (layer of layers) {
  1368.    
  1369.         layer.y = layers[0].y + height
  1370.         height += layer.height + verticalSpaceInPixels
  1371.    
  1372.     }
  1373. }
  1374.  
  1375.  
  1376.  
  1377.  
  1378.  
  1379.  
  1380. const figmaFunctions = {
  1381.  
  1382.     "alignLayersVertically(verticalSpaceInPixels: string = 200)": {
  1383.         "howToUse": [
  1384.             `Select layers i want to align verically
  1385.             with 200px
  1386.             `
  1387.         ],
  1388.         use(verticalSpaceInPixels=200) {
  1389.             alignLayersVertically(verticalSpaceInPixels)
  1390.            
  1391.         }
  1392.     }
  1393.    
  1394. }
  1395.  
  1396.  
Add Comment
Please, Sign In to add comment