Skip to content

Commit

Permalink
Merge pull request #1 from mattlean/dev2
Browse files Browse the repository at this point in the history
Add floor values support
  • Loading branch information
mattlean authored May 25, 2020
2 parents aa2ac22 + 7a500ee commit 39a60e8
Show file tree
Hide file tree
Showing 11 changed files with 121 additions and 58 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
dist
node_modules

.eslintcache
main.js
yarn-error.log
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# Gridnik (Alpha)
# Gridnik

## About

**THIS PLUGIN IS CURRENTLY IN ALPHA!**

Gridnik is a plugin for an [Adobe XD](https://www.adobe.com/products/xd.html) that extends the program's ability to create grids.

The plugin's name is based on Dutch graphic designer [Wim Crouwel](https://en.wikipedia.org/wiki/Wim_Crouwel) who was known by his friends as Mr. Gridnik, a nickname given to him due to his obsession with grids.
Expand All @@ -10,4 +12,5 @@ The plugin's name is based on Dutch graphic designer [Wim Crouwel](https://en.wi

- Create an unlimited amount of layout grids with varying dimensions, columns, gutters, and margins
- Build grids and overlay them upon any object: artboards, rectangles, polygons, text, etc.
- Use auto-grid calculations to make sure your grids hold your desired structure while still being valid
- Use auto-calculations to make sure your grids hold your desired structure while still being valid
- Construct grids in measurements of decimals or whole numbers
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
{
"name": "gridnik",
"version": "0.1.0",
"version": "0.2.0",
"main": "dist/main.js",
"repository": "https://github.com/mattlean/gridnik.git",
"author": "Matthew Lean <matt@mattlean.com>",
"private": true,
"scripts": {
"build": "webpack --mode development",
"dev": "DEV=true yarn watch",
"lint": "eslint --cache \"src/**/*.{js,jsx}\"",
"test": "jest",
"watch": "nodemon -w src -e js,jsx,css -w webpack.config.js -x yarn build"
},
Expand Down
18 changes: 17 additions & 1 deletion src/components/Panel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const {
* Adobe XD panel used for plugin UI.
*/
const Panel = ({ selectionAmount, validSelection }) => {
const [floorVals, setFloorVals] = useState(true)
const [canvasType, setCanvasType] = useState('auto')
const [boundType, setBoundType] = useState('path')
const [canvasWidth, setCanvasWidth] = useState('')
Expand All @@ -44,6 +45,7 @@ const Panel = ({ selectionAmount, validSelection }) => {
canvasWidth,
cols,
colWidth,
floorVals,
gridHeight,
gutterWidth,
topMargin,
Expand All @@ -69,6 +71,7 @@ const Panel = ({ selectionAmount, validSelection }) => {
* Reset form & stats on panel UI.
*/
const resetForm = () => {
setFloorVals(true)
setCols('')
setGutterWidth(0)
setColWidth('')
Expand All @@ -86,8 +89,9 @@ const Panel = ({ selectionAmount, validSelection }) => {
setCanvasWidth(calcState.canvasWidth)
setCanvasHeight(calcState.canvasHeight)
setCols(calcState.cols)
setGutterWidth(calcState.gutterWidth)
setColWidth(calcState.colWidth)
setFloorVals(calcState.floorVals)
setGutterWidth(calcState.gutterWidth)
setTopMargin(calcState.topMargin)
setRightMargin(calcState.rightMargin)
setBottomMargin(calcState.bottomMargin)
Expand Down Expand Up @@ -283,6 +287,17 @@ const Panel = ({ selectionAmount, validSelection }) => {
if (selectionAmount === 1) {
content = (
<form method="dialog">
<label className="text-input-combo">
<span>Floor Values</span>
<input
type="checkbox"
checked={floorVals}
onChange={(evt) => {
setFloorVals(evt.target.checked)
}}
uxp-quiet="true"
/>
</label>
<label className="text-input-combo">
<span>Canvas Type</span>
<select defaultValue={canvasType} onChange={handleCanvasTypeChange}>
Expand All @@ -301,6 +316,7 @@ const Panel = ({ selectionAmount, validSelection }) => {
<option value="draw">Draw</option>
</select>
</label>
<hr />
<label className="text-input-combo">
<span>Canvas Size</span>
<div className="multi-inputs">
Expand Down
7 changes: 0 additions & 7 deletions src/main.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,6 @@ const render = (selection = {}, enableForce) => {
}

if (triggerRender || enableForce) {
if (triggerRender) {
console.log('[ Render triggered ]')
} else {
console.log('[ Render forced ]')
}
ReactDOM.render(
<Panel
selectionAmount={prevMainState.selectionAmount}
Expand All @@ -62,7 +57,6 @@ const render = (selection = {}, enableForce) => {
const show = (evt) => {
if (!panelEle) {
panelEle = document.createElement('div')
console.log('[ Show called ]')
render({}, true)
evt.node.appendChild(panelEle)
}
Expand All @@ -77,7 +71,6 @@ const show = (evt) => {
// eslint-disable-next-line no-unused-vars
const update = (selection, docRoot) => {
if (selection) {
console.log('[ Update called ]')
render(selection)
}
}
Expand Down
74 changes: 52 additions & 22 deletions src/scripts/calc.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const GridCalcError = require('./GridCalcError')
const { floorVal } = require('./util')
const { validateCalcResult } = require('./validate')
const { GRID_CALC_ERROR_TYPE_SILENT } = require('./consts')

Expand All @@ -10,19 +11,31 @@ const { GRID_CALC_ERROR_TYPE_SILENT } = require('./consts')
* @returns {Object} Result with updated calcState values & new calculations
*/
const calcRightLeftMargins = (calcState, currResult = { errs: [] }) => {
const { canvasWidth, rightMargin, leftMargin } = calcState
const { canvasWidth, floorVals, rightMargin, leftMargin } = calcState
const rightLeftMarginsSum = rightMargin + leftMargin
const maxRightLeftMarginsSum = canvasWidth - 1

if (rightLeftMarginsSum > maxRightLeftMarginsSum) {
currResult.errs.push(new GridCalcError(3, GRID_CALC_ERROR_TYPE_SILENT))

const rightMarginPercent = calcState.rightMargin / rightLeftMarginsSum
const leftMarginPercent = calcState.leftMargin / rightLeftMarginsSum
const maxLeftRightMargin = maxRightLeftMarginsSum / 2

calcState.rightMargin = maxLeftRightMargin * rightMarginPercent
calcState.leftMargin = maxLeftRightMargin * leftMarginPercent
const rightMarginPercent = floorVal(
floorVals,
calcState.rightMargin / rightLeftMarginsSum
)
const leftMarginPercent = floorVal(
floorVals,
calcState.leftMargin / rightLeftMarginsSum
)
const maxLeftRightMargin = floorVal(floorVals, maxRightLeftMarginsSum / 2)

calcState.rightMargin = floorVal(
floorVals,
maxLeftRightMargin * rightMarginPercent
)
calcState.leftMargin = floorVal(
floorVals,
maxLeftRightMargin * leftMarginPercent
)
currResult.rightMargin = calcState.rightMargin
currResult.leftMargin = calcState.leftMargin
}
Expand Down Expand Up @@ -60,16 +73,19 @@ const calcColWidth = (
currResult[key] = calcState[key]
}
}
const { canvasWidth, cols, gutterWidth } = calcState
const { canvasWidth, cols, floorVals, gutterWidth } = calcState

// Make sure that left + right margins are possible numbers
calcRightLeftMargins(calcState, currResult)
const rightLeftMarginsSum = currResult.rightLeftMarginsSum

// Perform main calculations
const gutterWidthsSum = gutterWidth * (cols - 1)
const colWidth = (canvasWidth - rightLeftMarginsSum - gutterWidthsSum) / cols
const colWidthsSum = colWidth * cols
const gutterWidthsSum = floorVal(floorVals, gutterWidth * (cols - 1))
const colWidth = floorVal(
floorVals,
(canvasWidth - rightLeftMarginsSum - gutterWidthsSum) / cols
)
const colWidthsSum = floorVal(floorVals, colWidth * cols)
const gridWidth = colWidthsSum + gutterWidthsSum

currResult.colWidth = colWidth
Expand Down Expand Up @@ -145,17 +161,19 @@ const calcGutterWidth = (
}
}

const { canvasWidth, cols, colWidth } = calcState
const { canvasWidth, cols, colWidth, floorVals } = calcState

// Make sure that left + margins are possible numbers
calcRightLeftMargins(calcState, currResult)
const rightLeftMarginsSum = currResult.rightLeftMarginsSum

// Perform main calculations
const gutterWidth =
const gutterWidth = floorVal(
floorVals,
(canvasWidth - rightLeftMarginsSum - colWidth * cols) / (cols - 1)
const gutterWidthsSum = gutterWidth * (cols - 1)
const colWidthsSum = colWidth * cols
)
const gutterWidthsSum = floorVal(floorVals, gutterWidth * (cols - 1))
const colWidthsSum = floorVal(floorVals, colWidth * cols)
const gridWidth = colWidthsSum + gutterWidthsSum

currResult.colWidthsSum = colWidthsSum
Expand Down Expand Up @@ -212,19 +230,31 @@ module.exports.calcGutterWidth = calcGutterWidth
* @returns {Object} Result with updated calcState values & new calculations
*/
const calcGridHeight = (calcState, currResult = { errs: [] }) => {
const { canvasHeight, topMargin, bottomMargin } = calcState
const { canvasHeight, floorVals, topMargin, bottomMargin } = calcState
const topBottomMarginsSum = topMargin + bottomMargin
const maxTopBottomMarginsSum = canvasHeight - 1

if (topBottomMarginsSum > maxTopBottomMarginsSum) {
currResult.errs.push(new GridCalcError(5, GRID_CALC_ERROR_TYPE_SILENT))

const topMarginPercent = calcState.topMargin / topBottomMarginsSum
const bottomMarginPercent = calcState.bottomMargin / topBottomMarginsSum
const maxTopBottomMargin = maxTopBottomMarginsSum / 2

calcState.topMargin = maxTopBottomMargin * topMarginPercent
calcState.bottomMargin = maxTopBottomMargin * bottomMarginPercent
const topMarginPercent = floorVal(
floorVals,
calcState.topMargin / topBottomMarginsSum
)
const bottomMarginPercent = floorVal(
floorVals,
calcState.bottomMargin / topBottomMarginsSum
)
const maxTopBottomMargin = floorVal(floorVals, maxTopBottomMarginsSum / 2)

calcState.topMargin = floorVal(
floorVals,
maxTopBottomMargin * topMarginPercent
)
calcState.bottomMargin = floorVal(
floorVals,
maxTopBottomMargin * bottomMarginPercent
)
currResult.topMargin = calcState.topMargin
currResult.bottomMargin = calcState.bottomMargin
}
Expand Down
8 changes: 6 additions & 2 deletions src/scripts/draw.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ const commands = require('commands')
const { Color, Rectangle } = require('scenegraph')
const { editDocument } = require('application')

const draw = (calcData) => {
/**
* Draw grid.
* @param {Object} calcState State for calculations. Should be validated beforehand.
*/
const draw = (calcState) => {
editDocument((selection) => {
const currSelection = selection.items[0]
const {
Expand All @@ -14,7 +18,7 @@ const draw = (calcData) => {
gutterWidth,
topMargin,
leftMargin,
} = calcData
} = calcState
const color = new Color('#00ffff', 0.5)
const newItems = []

Expand Down
2 changes: 1 addition & 1 deletion src/scripts/react-shim.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ if (window.cancelAnimationFrame == null) {
}
if (window.requestAnimationFrame == null) {
window.requestAnimationFrame = function () {
console.log('requestAnimationFrame is not supported yet')
console.log('requestAnimationFrame is not supported yet') // eslint-disable-line no-console
}
}
if (window.HTMLIFrameElement == null) {
Expand Down
32 changes: 26 additions & 6 deletions src/scripts/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@
* Convert calcState non-number values to numbers if possible.
* Mutates the calcState.
* @param {Object} calcState State used for calculations
* @param {'float'|'int'} [type=int] Determines what type of number to convert value to
* @param {boolean} [floorVals=false] Flag that deteremines if value is floored
* @returns {boolean} Returns true if at least one value was converted, false otherwise
*/
const convertCalcStateToNum = (calcState, type = 'int') => {
const convertCalcStateToNum = (calcState, floorVals = false) => {
let isConverted = false

for (let key in calcState) {
const val = calcState[key]
if (isNumericString(val)) {
if (type === 'float') {
calcState[key] = parseFloat(val)
} else {
if (floorVals || key === 'cols') {
calcState[key] = parseInt(val)
} else {
calcState[key] = parseFloat(val)
}
isConverted = true
} else if (
Expand All @@ -35,13 +35,33 @@ const convertCalcStateToNum = (calcState, type = 'int') => {

module.exports.convertCalcStateToNum = convertCalcStateToNum

/**
* Conditionally floor value.
* @param {boolean} floorVals Flag that deteremines if value is floored
* @param {number} val Value to be potentially floored
* @return {number} Value may be floored or not
*/
const floorVal = (floorVals, val) => {
if (floorVals) {
return parseInt(val)
}
return val
}

module.exports.floorVal = floorVal

/**
* Checks if string value is numeric.
* @param {string} val Value to be tested
* @returns {boolean} True if value is numeric, false otherwise
*/
const isNumericString = (val) => {
if (typeof val !== 'number' && !isNaN(val) && val !== '') {
if (
typeof val !== 'number' &&
typeof val !== 'boolean' &&
!isNaN(val) &&
val !== ''
) {
return true
}
return false
Expand Down
4 changes: 3 additions & 1 deletion src/scripts/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ module.exports.validateCalcResult = validateCalcResult
* @param {Object} calcState State for calculations
*/
const validateInputs = (calcState) => {
convertCalcStateToNum(calcState, 'float')
const { floorVals } = calcState
convertCalcStateToNum(calcState, floorVals)

const {
canvasWidth,
canvasHeight,
Expand Down
Loading

0 comments on commit 39a60e8

Please sign in to comment.