├── .gitignore
├── README.md
├── Skew.sketchplugin
└── Contents
│ ├── Resources
│ ├── icon-main.png
│ ├── icon-skew-horizontal.png
│ └── icon-skew-vertical.png
│ └── Sketch
│ ├── manifest.json
│ └── script.cocoascript
├── appcast.xml
└── screengrab.gif
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Sketch Plugin: Skew!
4 |
5 | A Sketch plugin for skewing (or shearing) shapes horizontally or vertically.
6 |
7 |
8 |
9 | ## To do
10 |
11 | - Functionality for skewing beziers
12 |
13 | ## Installation
14 |
15 | #### Install from repo
16 |
17 | 1. Download the latest *.zip and unzip
18 | 2. Double click on the .sketchplugin
19 | 3. If all went well Sketch just installed the plugin!`
20 |
21 | Or simply install via Sketch Runner
22 |
23 | #### Usage
24 |
25 | 1. Select some shapes or groups of shapes
26 | 2. Select one of the Skew options via the menu (or use Runner)
27 | 3. A window pops up and asks for a skew degree between -90 and 90 degrees. Hit enter.
28 | 4. Boom! Your shapes are skewed by given degrees. 😎
29 |
30 | ---
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Skew.sketchplugin/Contents/Resources/icon-main.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mheesakkers/sketch-plugin-skew/a24cf1ecc89c5374f8967dc36571c7493a4c8d67/Skew.sketchplugin/Contents/Resources/icon-main.png
--------------------------------------------------------------------------------
/Skew.sketchplugin/Contents/Resources/icon-skew-horizontal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mheesakkers/sketch-plugin-skew/a24cf1ecc89c5374f8967dc36571c7493a4c8d67/Skew.sketchplugin/Contents/Resources/icon-skew-horizontal.png
--------------------------------------------------------------------------------
/Skew.sketchplugin/Contents/Resources/icon-skew-vertical.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mheesakkers/sketch-plugin-skew/a24cf1ecc89c5374f8967dc36571c7493a4c8d67/Skew.sketchplugin/Contents/Resources/icon-skew-vertical.png
--------------------------------------------------------------------------------
/Skew.sketchplugin/Contents/Sketch/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "author" : "Misha Heesakkers",
3 | "identifier" : "com.mishaheesakkers.sketch.skew",
4 | "version" : "3.0",
5 | "description" : "Skew (or shear) shapes horizontally or vertically.",
6 | "authorEmail" : "misha.heesakkers@gmail.com",
7 | "name" : "Skew!",
8 | "icon" : "icon-main.png",
9 | "appcast" : "https://raw.githubusercontent.com/mheesakkers/sketch-plugin-skew/master/appcast.xml",
10 | "commands" : [
11 | {
12 | "script" : "script.cocoascript",
13 | "name" : "Skew horizontally...",
14 | "handler" : "skewHorizontalHandler",
15 | "identifier" : "skew-horizontally",
16 | "icon" : "icon-skew-horizontal.png"
17 | },
18 | {
19 | "script" : "script.cocoascript",
20 | "name" : "Skew vertically...",
21 | "handler" : "skewVerticalHandler",
22 | "identifier" : "skew-vertically",
23 | "icon" : "icon-skew-vertical.png"
24 | }
25 |
26 | ],
27 | "menu" : {
28 | "isRoot": false,
29 | "items" : [
30 | "skew-horizontally",
31 | "skew-vertically"
32 | ]
33 | }
34 | }
--------------------------------------------------------------------------------
/Skew.sketchplugin/Contents/Sketch/script.cocoascript:
--------------------------------------------------------------------------------
1 | var onRun = function(context, skewHorizontal = true) {
2 | var sketch = require('sketch')
3 | var UI = require('sketch/ui')
4 | var doc = context.document
5 | var selection = sketch.getSelectedDocument().selectedLayers
6 |
7 | var inputSkewAngle = parseFloat( [doc askForUserInput:"Define a skew angle (Range: -90 - 90)?" initialValue:"10"] ).toFixed(1)
8 | inputSkewAngle = checkInputSkewAngle(inputSkewAngle)
9 |
10 | if (selection.length > 0) {
11 |
12 | // Loop through selection and get all shape layers
13 | var shapeLayers = [];
14 | selection.forEach( function iterate(layer) {
15 | layer.type === 'ShapePath' && shapeLayers.push(layer.sketchObject);
16 | layer.type === 'Text' && UI.message('This plugins works only for shape layers.')
17 | layer.type === 'Image' && UI.message('This plugins works only for shape layers.')
18 | if (layer.layers) {
19 | layer.layers.forEach(iterate)
20 | }
21 | // log(layer.type);
22 | });
23 |
24 | // Loop over shape layers
25 | shapeLayers.forEach(layer => {
26 | const shape = layer.isMemberOfClass(MSShapeGroup) ? layer.layers()[0] : layer
27 | // shape.flattenedLayer();
28 |
29 | var shapeWidth = shape.absoluteRect().width()
30 | var shapeHeight = shape.absoluteRect().height()
31 | var points = shape.points()
32 |
33 | if (points.length > 0) {
34 | if (skewHorizontal) {
35 | const skewAngleFactor = shapeHeight / shapeWidth
36 | // log(skewAngleFactor)
37 | points.forEach(p => {
38 | p.point = skewX( p.point(), inputSkewAngle, skewAngleFactor)
39 | })
40 | UI.message('Skewed horizontally by ' + inputSkewAngle + '°')
41 | } else {
42 | const skewAngleFactor = shapeWidth / shapeHeight
43 | // log(skewAngleFactor)
44 | points.forEach(p => {
45 | const skewAngleFactor = shapeWidth / shapeHeight
46 | p.point = skewY( p.point(), inputSkewAngle, skewAngleFactor)
47 | })
48 | UI.message('Skewed vertically by ' + inputSkewAngle + '°')
49 | }
50 | }
51 |
52 | var flattened = shape.flattenedLayer(); // Converts custom shapes into MSShapePathLayer
53 |
54 | var flattener = MSLayerFlattener.alloc().init();
55 | flattener.flattenLayer_options(flattened, 2);// includes removing duplicate points
56 |
57 | var group = shape.parentGroup();
58 | group.insertLayer_afterLayer(flattened, shape);
59 | group.removeLayer(shape);
60 |
61 | })
62 |
63 | } else {
64 | UI.message('No shape layers selected.')
65 | }
66 | }
67 |
68 | // Skew functionality
69 | function skewX (point, angle, factor) {
70 | const skewedX = point.x + point.y * (1 / Math.tan( -toRadians( 270.0 - angle)) ) * factor // 270 degrees is the base angle & I invert the radians to match Illustrators orientation
71 | return { x: skewedX, y: point.y } // Return horizontal skew
72 | }
73 |
74 | function skewY (point, angle, factor) {
75 | const skewedY = point.y + point.x * (1 / Math.tan( toRadians( 270.0 - angle)) ) * factor
76 | return { x: point.x, y: skewedY } // Return vertical skew
77 | }
78 |
79 | function checkInputSkewAngle (angle) {
80 | var UI = require('sketch/ui')
81 | var maxmin = 89
82 |
83 | if (angle < -maxmin) {
84 | angle = -maxmin
85 | UI.message('Skew angle is set to -' + maxmin + ', the min limit to skew. Otherwise the artwork gets too big.')
86 | }
87 | if (angle > maxmin) {
88 | angle = maxmin
89 | UI.message('Skew angle is set to ' + maxmin + ', the max limit to skew. Otherwise the artwork gets too big.')
90 | }
91 |
92 | return angle;
93 | }
94 |
95 | // Helpers //
96 | function toRadians (angle) {
97 | return angle * (Math.PI / 180);
98 | }
99 |
100 | // Command handlers
101 | var skewHorizontalHandler = function (context) {
102 | onRun(context, true)
103 | }
104 |
105 | var skewVerticalHandler = function (context) {
106 | onRun(context, false)
107 | }
108 |
109 | // Doesn't work with:
110 | // 1. Bezier points give wrong results
111 | // 2. Multiple shapes
--------------------------------------------------------------------------------
/appcast.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Sketch Plugin: Skew!
5 | http://sparkle-project.org/files/sparkletestcast.xml
6 | A Sketch plugin for skewing (or shearing) shapes horizontally or vertically.
7 | en
8 | -
9 | Version 3.0
10 |
11 |
13 | Made compatible with Sketch v53.1
14 |
15 | ]]>
16 |
17 |
18 |
19 | -
20 | Version 2.0
21 |
22 |
24 | Improved skewing/shearing that matches Adobe Illustrator.
25 |
26 | ]]>
27 |
28 |
29 |
30 | -
31 | Version 1.1
32 |
33 |
35 | Made compatible with Sketch v52
36 |
37 | ]]>
38 |
39 |
40 |
41 | -
42 | Version 1.0
43 |
44 |
46 | First release
47 |
48 | ]]>
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/screengrab.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mheesakkers/sketch-plugin-skew/a24cf1ecc89c5374f8967dc36571c7493a4c8d67/screengrab.gif
--------------------------------------------------------------------------------