├── .gitignore
├── README.md
├── Snap to 8pt Grid.sketchplugin
└── Contents
│ ├── Resources
│ ├── icon-square.png
│ ├── icon.png
│ ├── screengrab.gif
│ ├── snap-fontSize.png
│ ├── snap-height.png
│ ├── snap-lineHeight.png
│ ├── snap-width.png
│ ├── snap-x.png
│ └── snap-y.png
│ └── Sketch
│ ├── __snap.js
│ ├── __snap.js.map
│ └── manifest.json
├── appcast.xml
├── assets
├── icon-square.png
├── icon.png
├── screengrab.gif
├── snap-fontSize.png
├── snap-height.png
├── snap-lineHeight.png
├── snap-width.png
├── snap-x.png
└── snap-y.png
├── package-lock.json
├── package.json
├── sketch-assets
└── icons.sketch
└── src
├── manifest.json
└── snap.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # build artifacts
2 | snapper.sketchplugin
3 |
4 | # npm
5 | node_modules
6 | .npm
7 | npm-debug.log
8 |
9 | # mac
10 | .DS_Store
11 |
12 | # WebStorm
13 | .idea
14 |
15 | # sketch
16 | # sketch-assets
17 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Snap to 8pt Grid
4 |
5 | A Sketch plugin which helps with snapping layer properties to the 8 point grid.
6 | It's also possible to change to other point grids like a 10 point grid. This can be altered via the settings of the plugin menu.
7 |
8 |
9 |
10 | ## Usage
11 | 1. Select any type of layer (or make a selection)
12 | 2. Choose one of the snapping commands from the menu or use Runner ;)
13 | 3. Boom! Your layer property is snapped to the 8pt grid😎
14 |
15 | ## Layer properties that can be snapped
16 | - X
17 | - Y
18 | - Height
19 | - Width
20 | - Line-height
21 | - Font-size
22 |
23 | ## Installation
24 |
25 | - [Download](../../releases/latest/download/Snap.to.8pt.Grid.sketchplugin.zip) the latest release of the plugin
26 | - Un-zip
27 | - Double-click on snapper.sketchplugin
28 |
29 | ## Development Guide
30 |
31 | _This plugin was created using `skpm`. For a detailed explanation on how things work, checkout the [skpm Readme](https://github.com/skpm/skpm/blob/master/README.md)._
32 |
33 | ## To Do / Idea's
34 |
35 | - Snapping of paths
36 | - Add keyboard shortcuts
37 | - ~~Change pt/px amount of snapping (for example 10pt grid)~~
38 |
--------------------------------------------------------------------------------
/Snap to 8pt Grid.sketchplugin/Contents/Resources/icon-square.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mheesakkers/sketch-plugin-snap-to-8pt-grid/9575329fd4b7bee105b372677797a509fe2f4ef6/Snap to 8pt Grid.sketchplugin/Contents/Resources/icon-square.png
--------------------------------------------------------------------------------
/Snap to 8pt Grid.sketchplugin/Contents/Resources/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mheesakkers/sketch-plugin-snap-to-8pt-grid/9575329fd4b7bee105b372677797a509fe2f4ef6/Snap to 8pt Grid.sketchplugin/Contents/Resources/icon.png
--------------------------------------------------------------------------------
/Snap to 8pt Grid.sketchplugin/Contents/Resources/screengrab.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mheesakkers/sketch-plugin-snap-to-8pt-grid/9575329fd4b7bee105b372677797a509fe2f4ef6/Snap to 8pt Grid.sketchplugin/Contents/Resources/screengrab.gif
--------------------------------------------------------------------------------
/Snap to 8pt Grid.sketchplugin/Contents/Resources/snap-fontSize.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mheesakkers/sketch-plugin-snap-to-8pt-grid/9575329fd4b7bee105b372677797a509fe2f4ef6/Snap to 8pt Grid.sketchplugin/Contents/Resources/snap-fontSize.png
--------------------------------------------------------------------------------
/Snap to 8pt Grid.sketchplugin/Contents/Resources/snap-height.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mheesakkers/sketch-plugin-snap-to-8pt-grid/9575329fd4b7bee105b372677797a509fe2f4ef6/Snap to 8pt Grid.sketchplugin/Contents/Resources/snap-height.png
--------------------------------------------------------------------------------
/Snap to 8pt Grid.sketchplugin/Contents/Resources/snap-lineHeight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mheesakkers/sketch-plugin-snap-to-8pt-grid/9575329fd4b7bee105b372677797a509fe2f4ef6/Snap to 8pt Grid.sketchplugin/Contents/Resources/snap-lineHeight.png
--------------------------------------------------------------------------------
/Snap to 8pt Grid.sketchplugin/Contents/Resources/snap-width.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mheesakkers/sketch-plugin-snap-to-8pt-grid/9575329fd4b7bee105b372677797a509fe2f4ef6/Snap to 8pt Grid.sketchplugin/Contents/Resources/snap-width.png
--------------------------------------------------------------------------------
/Snap to 8pt Grid.sketchplugin/Contents/Resources/snap-x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mheesakkers/sketch-plugin-snap-to-8pt-grid/9575329fd4b7bee105b372677797a509fe2f4ef6/Snap to 8pt Grid.sketchplugin/Contents/Resources/snap-x.png
--------------------------------------------------------------------------------
/Snap to 8pt Grid.sketchplugin/Contents/Resources/snap-y.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mheesakkers/sketch-plugin-snap-to-8pt-grid/9575329fd4b7bee105b372677797a509fe2f4ef6/Snap to 8pt Grid.sketchplugin/Contents/Resources/snap-y.png
--------------------------------------------------------------------------------
/Snap to 8pt Grid.sketchplugin/Contents/Sketch/__snap.js:
--------------------------------------------------------------------------------
1 | var globalThis = this;
2 | var global = this;
3 | function __skpm_run (key, context) {
4 | globalThis.context = context;
5 | try {
6 |
7 | var exports =
8 | /******/ (function(modules) { // webpackBootstrap
9 | /******/ // The module cache
10 | /******/ var installedModules = {};
11 | /******/
12 | /******/ // The require function
13 | /******/ function __webpack_require__(moduleId) {
14 | /******/
15 | /******/ // Check if module is in cache
16 | /******/ if(installedModules[moduleId]) {
17 | /******/ return installedModules[moduleId].exports;
18 | /******/ }
19 | /******/ // Create a new module (and put it into the cache)
20 | /******/ var module = installedModules[moduleId] = {
21 | /******/ i: moduleId,
22 | /******/ l: false,
23 | /******/ exports: {}
24 | /******/ };
25 | /******/
26 | /******/ // Execute the module function
27 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
28 | /******/
29 | /******/ // Flag the module as loaded
30 | /******/ module.l = true;
31 | /******/
32 | /******/ // Return the exports of the module
33 | /******/ return module.exports;
34 | /******/ }
35 | /******/
36 | /******/
37 | /******/ // expose the modules object (__webpack_modules__)
38 | /******/ __webpack_require__.m = modules;
39 | /******/
40 | /******/ // expose the module cache
41 | /******/ __webpack_require__.c = installedModules;
42 | /******/
43 | /******/ // define getter function for harmony exports
44 | /******/ __webpack_require__.d = function(exports, name, getter) {
45 | /******/ if(!__webpack_require__.o(exports, name)) {
46 | /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
47 | /******/ }
48 | /******/ };
49 | /******/
50 | /******/ // define __esModule on exports
51 | /******/ __webpack_require__.r = function(exports) {
52 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
53 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
54 | /******/ }
55 | /******/ Object.defineProperty(exports, '__esModule', { value: true });
56 | /******/ };
57 | /******/
58 | /******/ // create a fake namespace object
59 | /******/ // mode & 1: value is a module id, require it
60 | /******/ // mode & 2: merge all properties of value into the ns
61 | /******/ // mode & 4: return value when already ns object
62 | /******/ // mode & 8|1: behave like require
63 | /******/ __webpack_require__.t = function(value, mode) {
64 | /******/ if(mode & 1) value = __webpack_require__(value);
65 | /******/ if(mode & 8) return value;
66 | /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
67 | /******/ var ns = Object.create(null);
68 | /******/ __webpack_require__.r(ns);
69 | /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
70 | /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
71 | /******/ return ns;
72 | /******/ };
73 | /******/
74 | /******/ // getDefaultExport function for compatibility with non-harmony modules
75 | /******/ __webpack_require__.n = function(module) {
76 | /******/ var getter = module && module.__esModule ?
77 | /******/ function getDefault() { return module['default']; } :
78 | /******/ function getModuleExports() { return module; };
79 | /******/ __webpack_require__.d(getter, 'a', getter);
80 | /******/ return getter;
81 | /******/ };
82 | /******/
83 | /******/ // Object.prototype.hasOwnProperty.call
84 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
85 | /******/
86 | /******/ // __webpack_public_path__
87 | /******/ __webpack_require__.p = "";
88 | /******/
89 | /******/
90 | /******/ // Load entry module and return exports
91 | /******/ return __webpack_require__(__webpack_require__.s = "./src/snap.js");
92 | /******/ })
93 | /************************************************************************/
94 | /******/ ({
95 |
96 | /***/ "./src/snap.js":
97 | /*!*********************!*\
98 | !*** ./src/snap.js ***!
99 | \*********************/
100 | /*! exports provided: snap, settings */
101 | /***/ (function(module, __webpack_exports__, __webpack_require__) {
102 |
103 | "use strict";
104 | __webpack_require__.r(__webpack_exports__);
105 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "snap", function() { return snap; });
106 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "settings", function() { return settings; });
107 | /* harmony import */ var sketch__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! sketch */ "sketch");
108 | /* harmony import */ var sketch__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(sketch__WEBPACK_IMPORTED_MODULE_0__);
109 |
110 | function snap(context) {
111 | // Document & Selection
112 | var document = sketch__WEBPACK_IMPORTED_MODULE_0__["Document"].getSelectedDocument();
113 | var selection = document.selectedLayers; // Run
114 |
115 | if (!selection.isEmpty) {
116 | // Get setting for grid type
117 | var amount_point_grid = sketch__WEBPACK_IMPORTED_MODULE_0__["Settings"].documentSettingForKey(document, 'gridType') || 8; // !important Specify type which gets snapped in manifests identifiers
118 |
119 | var commands = [context.command.identifier().replace('snap-', '')]; // Split up if there are multiple types to snap to
120 |
121 | commands = commands[0].split("-"); // Snap
122 |
123 | commands.forEach(function (type) {
124 | selection.layers.forEach(function (layer) {
125 | var key = "frame";
126 |
127 | if (type == "lineHeight" || type == "fontSize") {
128 | key = "style";
129 | }
130 |
131 | if (layer[key][type]) {
132 | var offset = layer[key][type] % amount_point_grid;
133 |
134 | if (offset < amount_point_grid * 0.5) {
135 | layer[key][type] -= offset;
136 | } else {
137 | layer[key][type] += amount_point_grid - offset;
138 | }
139 | }
140 | });
141 | }); // Message
142 |
143 | sketch__WEBPACK_IMPORTED_MODULE_0__["UI"].message("👌Snapped to " + amount_point_grid + "pt grid!");
144 | } else {
145 | sketch__WEBPACK_IMPORTED_MODULE_0__["UI"].message("It seems you haven't selected any layers");
146 | }
147 | }
148 | function settings(context) {
149 | var document = sketch__WEBPACK_IMPORTED_MODULE_0__["Document"].getSelectedDocument();
150 | sketch__WEBPACK_IMPORTED_MODULE_0__["UI"].getInputFromUser("Change point grid setting", {
151 | type: sketch__WEBPACK_IMPORTED_MODULE_0__["UI"].INPUT_TYPE.selection,
152 | possibleValues: ['2pt Grid', '4pt Grid', '6pt Grid', '8pt Grid', '10pt Grid', '12pt Grid', '16pt Grid'],
153 | initialValue: (sketch__WEBPACK_IMPORTED_MODULE_0__["Settings"].documentSettingForKey(document, 'gridType') || 8) + 'pt Grid'
154 | }, function (err, value) {
155 | if (err) {
156 | // most likely the user canceled the input
157 | return;
158 | }
159 |
160 | var point_value = value.split('pt Grid')[0];
161 | sketch__WEBPACK_IMPORTED_MODULE_0__["Settings"].setDocumentSettingForKey(document, 'gridType', point_value || 8);
162 | });
163 | }
164 |
165 | /***/ }),
166 |
167 | /***/ "sketch":
168 | /*!*************************!*\
169 | !*** external "sketch" ***!
170 | \*************************/
171 | /*! no static exports found */
172 | /***/ (function(module, exports) {
173 |
174 | module.exports = require("sketch");
175 |
176 | /***/ })
177 |
178 | /******/ });
179 | if (key === 'default' && typeof exports === 'function') {
180 | exports(context);
181 | } else if (typeof exports[key] !== 'function') {
182 | throw new Error('Missing export named "' + key + '". Your command should contain something like `export function " + key +"() {}`.');
183 | } else {
184 | exports[key](context);
185 | }
186 | } catch (err) {
187 | if (typeof process !== 'undefined' && process.listenerCount && process.listenerCount('uncaughtException')) {
188 | process.emit("uncaughtException", err, "uncaughtException");
189 | } else {
190 | throw err
191 | }
192 | }
193 | }
194 | globalThis['snap'] = __skpm_run.bind(this, 'snap');
195 | globalThis['onRun'] = __skpm_run.bind(this, 'default');
196 | globalThis['snap'] = __skpm_run.bind(this, 'snap');
197 | globalThis['snap'] = __skpm_run.bind(this, 'snap');
198 | globalThis['snap'] = __skpm_run.bind(this, 'snap');
199 | globalThis['snap'] = __skpm_run.bind(this, 'snap');
200 | globalThis['snap'] = __skpm_run.bind(this, 'snap');
201 | globalThis['snap'] = __skpm_run.bind(this, 'snap');
202 | globalThis['snap'] = __skpm_run.bind(this, 'snap');
203 | globalThis['settings'] = __skpm_run.bind(this, 'settings')
204 |
205 | //# sourceMappingURL=__snap.js.map
--------------------------------------------------------------------------------
/Snap to 8pt Grid.sketchplugin/Contents/Sketch/__snap.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack://exports/webpack/bootstrap","webpack://exports/./src/snap.js","webpack://exports/external \"sketch\""],"names":["snap","context","document","Document","getSelectedDocument","selection","selectedLayers","isEmpty","amount_point_grid","Settings","documentSettingForKey","commands","command","identifier","replace","split","forEach","type","layers","layer","key","offset","UI","message","settings","getInputFromUser","INPUT_TYPE","possibleValues","initialValue","err","value","point_value","setDocumentSettingForKey"],"mappings":"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","file":"__snap.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = \"./src/snap.js\");\n","import { Document, UI, Settings } from 'sketch'\n\nexport function snap (context) {\n\t// Document & Selection\n\tvar document = Document.getSelectedDocument()\n\tvar selection = document.selectedLayers\n\n\t// Run\n\tif (!selection.isEmpty) {\n\t\t// Get setting for grid type\n\t\tvar amount_point_grid = Settings.documentSettingForKey(document, 'gridType') || 8\n\n\t\t// !important Specify type which gets snapped in manifests identifiers\n\t\tlet commands = [ context.command.identifier().replace('snap-','') ]\n\n\t\t// Split up if there are multiple types to snap to\n\t\tcommands = commands[0].split(\"-\")\n\n\t\t// Snap\n\t\tcommands.forEach(type => {\n\t\t\tselection.layers.forEach(layer => {\n\t\t\t\tlet key = \"frame\"\n\t\t\t\t\n\t\t\t\tif (type == \"lineHeight\" || type == \"fontSize\") {\n\t\t\t\t\tkey = \"style\"\n\t\t\t\t}\n\n\t\t\t\tif (layer[key][type]) {\n\t\t\t\t\tlet offset = layer[key][type] % amount_point_grid\n\t\t\t\t\tif (offset < (amount_point_grid * 0.5)) {\n\t\t\t\t\t\tlayer[key][type] -= offset\n\t\t\t\t\t} else {\n\t\t \tlayer[key][type] += (amount_point_grid - offset)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t})\n\t\t})\n\n\t\t// Message\n\t\tUI.message(\"👌Snapped to \" + amount_point_grid + \"pt grid!\")\n\n\t} else {\n\t\tUI.message(\"It seems you haven't selected any layers\")\n\t}\n\n}\n\nexport function settings (context) {\n\tvar document = Document.getSelectedDocument()\n\n\tUI.getInputFromUser(\n\t \"Change point grid setting\",\n\t {\n\t type: UI.INPUT_TYPE.selection,\n\t possibleValues: ['2pt Grid', '4pt Grid', '6pt Grid', '8pt Grid', '10pt Grid', '12pt Grid', '16pt Grid'],\n\t initialValue: (Settings.documentSettingForKey(document, 'gridType') || 8) + 'pt Grid'\n\t },\n\t (err, value) => {\n\t if (err) {\n\t // most likely the user canceled the input\n\t return\n\t }\n\n\t let point_value = value.split('pt Grid')[0]\n\t Settings.setDocumentSettingForKey(document, 'gridType', point_value || 8);\n\t }\n\t)\n}","module.exports = require(\"sketch\");"],"sourceRoot":""}
--------------------------------------------------------------------------------
/Snap to 8pt Grid.sketchplugin/Contents/Sketch/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/sketch-hq/SketchAPI/develop/docs/sketch-plugin-manifest-schema.json",
3 | "name": "Snap to 8pt Grid",
4 | "version": "1.0.2",
5 | "description": "A Sketch plugin which helps with snapping layer properties to the 8 point grid.",
6 | "icon": "icon-square.png",
7 | "appcast": "https://raw.githubusercontent.com/mheesakkers/sketch-plugin-snap-to-8pt-grid/master/appcast.xml",
8 | "authorEmail": "misha.heesakkers@gmail.com",
9 | "author": "Misha Heesakkers",
10 | "commands": [
11 | {
12 | "name": "Snap X",
13 | "description": "Snap X position of layer to the 8 point grid",
14 | "identifier": "snap-x",
15 | "icon": "snap-x.png",
16 | "script": "__snap.js",
17 | "handler": "snap"
18 | },
19 | {
20 | "name": "Snap Y",
21 | "description": "Snap Y position of layer to the 8 point grid",
22 | "identifier": "snap-y",
23 | "icon": "snap-y.png",
24 | "script": "__snap.js",
25 | "handler": "snap"
26 | },
27 | {
28 | "name": "Snap Width",
29 | "description": "Snap width of layer to the 8 point grid",
30 | "identifier": "snap-width",
31 | "icon": "snap-width.png",
32 | "script": "__snap.js",
33 | "handler": "snap"
34 | },
35 | {
36 | "name": "Snap Height",
37 | "description": "Snap height of layer to the 8 point grid",
38 | "identifier": "snap-height",
39 | "icon": "snap-height.png",
40 | "script": "__snap.js",
41 | "handler": "snap"
42 | },
43 | {
44 | "name": "Snap Horizontal",
45 | "description": "Snap width and x position of layer to the 8 point grid",
46 | "identifier": "snap-width-x",
47 | "script": "__snap.js",
48 | "handler": "snap"
49 | },
50 | {
51 | "name": "Snap Vertical",
52 | "description": "Snap height and y position of layer to the 8 point grid",
53 | "identifier": "snap-height-y",
54 | "script": "__snap.js",
55 | "handler": "snap"
56 | },
57 | {
58 | "name": "Snap Font size",
59 | "description": "Snap font size of Text layer to the 8 point grid",
60 | "identifier": "snap-fontSize",
61 | "icon": "snap-fontSize.png",
62 | "script": "__snap.js",
63 | "handler": "snap"
64 | },
65 | {
66 | "name": "Snap Line-height",
67 | "description": "Snap line-height of Text layer to the 8 point grid",
68 | "identifier": "snap-lineHeight",
69 | "icon": "snap-lineHeight.png",
70 | "script": "__snap.js",
71 | "handler": "snap"
72 | },
73 | {
74 | "name": "⚙️ Settings",
75 | "description": "Change settings of the point grid",
76 | "identifier": "settings",
77 | "script": "__snap.js",
78 | "handler": "settings"
79 | }
80 | ],
81 | "menu": {
82 | "title": "Snap to 8pt Grid",
83 | "items": [
84 | "snap-x",
85 | "snap-y",
86 | "snap-width",
87 | "snap-height",
88 | "snap-width-x",
89 | "snap-height-y",
90 | "snap-fontSize",
91 | "snap-lineHeight",
92 | "settings"
93 | ]
94 | },
95 | "identifier": "SnapTo8ptGrid",
96 | "disableCocoaScriptPreprocessor": true
97 | }
--------------------------------------------------------------------------------
/appcast.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Sketch Plugin: Snap to 8pt Grid
5 | http://sparkle-project.org/files/sparkletestcast.xml
6 | A Sketch plugin which helps with snapping layer properties to the 8 point grid.
7 | en
8 | -
9 | Version 1.0.2
10 | Added a settings feature to change the point grid amount
11 |
12 |
13 | -
14 | Version 1.0.1
15 | Initial release of the plugin
16 |
17 |
18 | -
19 | Beta
20 | Beta release
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/assets/icon-square.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mheesakkers/sketch-plugin-snap-to-8pt-grid/9575329fd4b7bee105b372677797a509fe2f4ef6/assets/icon-square.png
--------------------------------------------------------------------------------
/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mheesakkers/sketch-plugin-snap-to-8pt-grid/9575329fd4b7bee105b372677797a509fe2f4ef6/assets/icon.png
--------------------------------------------------------------------------------
/assets/screengrab.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mheesakkers/sketch-plugin-snap-to-8pt-grid/9575329fd4b7bee105b372677797a509fe2f4ef6/assets/screengrab.gif
--------------------------------------------------------------------------------
/assets/snap-fontSize.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mheesakkers/sketch-plugin-snap-to-8pt-grid/9575329fd4b7bee105b372677797a509fe2f4ef6/assets/snap-fontSize.png
--------------------------------------------------------------------------------
/assets/snap-height.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mheesakkers/sketch-plugin-snap-to-8pt-grid/9575329fd4b7bee105b372677797a509fe2f4ef6/assets/snap-height.png
--------------------------------------------------------------------------------
/assets/snap-lineHeight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mheesakkers/sketch-plugin-snap-to-8pt-grid/9575329fd4b7bee105b372677797a509fe2f4ef6/assets/snap-lineHeight.png
--------------------------------------------------------------------------------
/assets/snap-width.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mheesakkers/sketch-plugin-snap-to-8pt-grid/9575329fd4b7bee105b372677797a509fe2f4ef6/assets/snap-width.png
--------------------------------------------------------------------------------
/assets/snap-x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mheesakkers/sketch-plugin-snap-to-8pt-grid/9575329fd4b7bee105b372677797a509fe2f4ef6/assets/snap-x.png
--------------------------------------------------------------------------------
/assets/snap-y.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mheesakkers/sketch-plugin-snap-to-8pt-grid/9575329fd4b7bee105b372677797a509fe2f4ef6/assets/snap-y.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "SnapTo8ptGrid",
3 | "description": "A Sketch plugin which helps with snapping layer properties to the 8 point grid.",
4 | "version": "1.0.0",
5 | "engines": {
6 | "sketch": ">=49.0"
7 | },
8 | "skpm": {
9 | "name": "SnapTo8ptGrid",
10 | "manifest": "src/manifest.json",
11 | "main": "Snap to 8pt Grid.sketchplugin",
12 | "assets": [
13 | "assets/**/*"
14 | ],
15 | "sketch-assets-file": "sketch-assets/icons.sketch"
16 | },
17 | "scripts": {
18 | "build": "skpm-build",
19 | "watch": "skpm-build --watch",
20 | "start": "skpm-build --watch --run",
21 | "postinstall": "npm run build && skpm-link"
22 | },
23 | "devDependencies": {
24 | "@skpm/builder": "^0.7.0"
25 | },
26 | "author": "Misha Heesakkers ",
27 | "repository": {
28 | "type": "git",
29 | "url": "https://github.com/mheesakkers/sketch-plugin-snap-to-8pt-grid"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/sketch-assets/icons.sketch:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mheesakkers/sketch-plugin-snap-to-8pt-grid/9575329fd4b7bee105b372677797a509fe2f4ef6/sketch-assets/icons.sketch
--------------------------------------------------------------------------------
/src/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/sketch-hq/SketchAPI/develop/docs/sketch-plugin-manifest-schema.json",
3 | "name" : "Snap to 8pt Grid",
4 | "version" : "1.0.2",
5 | "description": "A Sketch plugin which helps with snapping layer properties to the 8 point grid.",
6 | "icon": "icon-square.png",
7 | "appcast" : "https://raw.githubusercontent.com/mheesakkers/sketch-plugin-snap-to-8pt-grid/master/appcast.xml",
8 | "authorEmail" : "misha.heesakkers@gmail.com",
9 | "author" : "Misha Heesakkers",
10 | "commands": [
11 | {
12 | "name": "Snap X",
13 | "description": "Snap X position of layer to the 8 point grid",
14 | "identifier": "snap-x",
15 | "icon": "snap-x.png",
16 | "script": "./snap.js",
17 | "handler": "snap"
18 | },
19 | {
20 | "name": "Snap Y",
21 | "description": "Snap Y position of layer to the 8 point grid",
22 | "identifier": "snap-y",
23 | "icon": "snap-y.png",
24 | "script": "./snap.js",
25 | "handler": "snap"
26 | },
27 | {
28 | "name": "Snap Width",
29 | "description": "Snap width of layer to the 8 point grid",
30 | "identifier": "snap-width",
31 | "icon": "snap-width.png",
32 | "script": "./snap.js",
33 | "handler": "snap"
34 | },
35 | {
36 | "name": "Snap Height",
37 | "description": "Snap height of layer to the 8 point grid",
38 | "identifier": "snap-height",
39 | "icon": "snap-height.png",
40 | "script": "./snap.js",
41 | "handler": "snap"
42 | },
43 | {
44 | "name": "Snap Horizontal",
45 | "description": "Snap width and x position of layer to the 8 point grid",
46 | "identifier": "snap-width-x",
47 | "script": "./snap.js",
48 | "handler": "snap"
49 | },
50 | {
51 | "name": "Snap Vertical",
52 | "description": "Snap height and y position of layer to the 8 point grid",
53 | "identifier": "snap-height-y",
54 | "script": "./snap.js",
55 | "handler": "snap"
56 | },
57 | {
58 | "name": "Snap Font size",
59 | "description": "Snap font size of Text layer to the 8 point grid",
60 | "identifier": "snap-fontSize",
61 | "icon": "snap-fontSize.png",
62 | "script": "./snap.js",
63 | "handler": "snap"
64 | },
65 | {
66 | "name": "Snap Line-height",
67 | "description": "Snap line-height of Text layer to the 8 point grid",
68 | "identifier": "snap-lineHeight",
69 | "icon": "snap-lineHeight.png",
70 | "script": "./snap.js",
71 | "handler": "snap"
72 | },
73 | {
74 | "name": "⚙️ Settings",
75 | "description": "Change settings of the point grid",
76 | "identifier": "settings",
77 | "script": "./snap.js",
78 | "handler": "settings"
79 | }
80 | ],
81 | "menu": {
82 | "title": "Snap to 8pt Grid",
83 | "items": [
84 | "snap-x",
85 | "snap-y",
86 | "snap-width",
87 | "snap-height",
88 | "snap-width-x",
89 | "snap-height-y",
90 | "snap-fontSize",
91 | "snap-lineHeight",
92 | "settings"
93 | ]
94 | }
95 | }
--------------------------------------------------------------------------------
/src/snap.js:
--------------------------------------------------------------------------------
1 | import { Document, UI, Settings } from 'sketch'
2 |
3 | export function snap (context) {
4 | // Document & Selection
5 | var document = Document.getSelectedDocument()
6 | var selection = document.selectedLayers
7 |
8 | // Run
9 | if (!selection.isEmpty) {
10 | // Get setting for grid type
11 | var amount_point_grid = Settings.documentSettingForKey(document, 'gridType') || 8
12 |
13 | // !important Specify type which gets snapped in manifests identifiers
14 | let commands = [ context.command.identifier().replace('snap-','') ]
15 |
16 | // Split up if there are multiple types to snap to
17 | commands = commands[0].split("-")
18 |
19 | // Snap
20 | commands.forEach(type => {
21 | selection.layers.forEach(layer => {
22 | let key = "frame"
23 |
24 | if (type == "lineHeight" || type == "fontSize") {
25 | key = "style"
26 | }
27 |
28 | if (layer[key][type]) {
29 | let offset = layer[key][type] % amount_point_grid
30 | if (offset < (amount_point_grid * 0.5)) {
31 | layer[key][type] -= offset
32 | } else {
33 | layer[key][type] += (amount_point_grid - offset)
34 | }
35 | }
36 |
37 | })
38 | })
39 |
40 | // Message
41 | UI.message("👌Snapped to " + amount_point_grid + "pt grid!")
42 |
43 | } else {
44 | UI.message("It seems you haven't selected any layers")
45 | }
46 |
47 | }
48 |
49 | export function settings (context) {
50 | var document = Document.getSelectedDocument()
51 |
52 | UI.getInputFromUser(
53 | "Change point grid setting",
54 | {
55 | type: UI.INPUT_TYPE.selection,
56 | possibleValues: ['2pt Grid', '4pt Grid', '6pt Grid', '8pt Grid', '10pt Grid', '12pt Grid', '16pt Grid'],
57 | initialValue: (Settings.documentSettingForKey(document, 'gridType') || 8) + 'pt Grid'
58 | },
59 | (err, value) => {
60 | if (err) {
61 | // most likely the user canceled the input
62 | return
63 | }
64 |
65 | let point_value = value.split('pt Grid')[0]
66 | Settings.setDocumentSettingForKey(document, 'gridType', point_value || 8);
67 | }
68 | )
69 | }
--------------------------------------------------------------------------------