├── Frame Sequencer ├── FrameSequencer.sketchplugin │ └── Contents │ │ └── Sketch │ │ ├── manifest.json │ │ └── script.cocoascript ├── LICENSE └── sketchpack.json ├── README.md └── images ├── plugin_record.gif ├── plugin_record_2.gif └── sample_outcome.gif /Frame Sequencer/FrameSequencer.sketchplugin/Contents/Sketch/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "FrameSequencer", 3 | "version" : "1.0", 4 | "description" : "", 5 | "identifier" : "com.example.sketch.94fc6c23-d3fa-4aae-a8f5-de4bef0f03cb", 6 | "author" : "Dawid Woźniak", 7 | "authorEmail" : "dawid@plaind.pl", 8 | "homepage" : "https://github.com/dawidw/frame-sequencer", 9 | "commands" : [ 10 | { 11 | "script" : "script.cocoascript", 12 | "handler" : "onRun", 13 | "shortcut" : "", 14 | "name" : "Create sequence", 15 | "identifier" : "framesequencer" 16 | } 17 | ], 18 | "menu" : { 19 | "items" : [ 20 | "framesequencer" 21 | ], 22 | "title" : "FrameSequencer" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Frame Sequencer/FrameSequencer.sketchplugin/Contents/Sketch/script.cocoascript: -------------------------------------------------------------------------------- 1 | var onRun = function(context) { 2 | function showError(msg){ 3 | var app = NSApplication.sharedApplication(); 4 | return [app displayDialog:msg withTitle:"Yo!"]; 5 | } 6 | 7 | function addLayerToCurrentPage(layer) { 8 | document.currentPage().addLayers([layer]) 9 | } 10 | 11 | function setPosition(object, x, y) { 12 | log('position x = ' + x); 13 | log('position y = ' + y); 14 | object.setX(x); 15 | object.setY(y); 16 | } 17 | 18 | function setupBaseArtboard() { 19 | var temp_artboard = [MSArtboardGroup new]; 20 | var temp_frame = [temp_artboard frame]; 21 | [temp_frame setX:0]; 22 | [temp_frame setY:0]; 23 | [temp_frame setWidth:DRIBBBLE_CANVAS_WIDTH]; 24 | [temp_frame setHeight:DRIBBBLE_CANVAS_HEIGHT]; 25 | [temp_artboard setName: "FRAME 00"]; 26 | return temp_artboard; 27 | } 28 | 29 | function setupBaseLayer(layer) { 30 | var temp_selection = layer; 31 | var temp_selection_frame = [temp_selection frame]; 32 | if(temp_selection_frame.width() != DRIBBBLE_CANVAS_WIDTH) { 33 | var scale = DRIBBBLE_CANVAS_WIDTH / temp_selection_frame.width(); 34 | var midX=temp_selection_frame.midX(); 35 | var midY=temp_selection_frame.midY(); 36 | 37 | temp_selection.multiplyBy(scale); 38 | 39 | temp_selection_frame.midX = midX; 40 | temp_selection_frame.midY = midY; 41 | } 42 | setPosition(temp_selection_frame, 0, 0); 43 | return temp_selection; 44 | } 45 | 46 | function calculateStepHeight(layer) { 47 | return Math.round((layer.frame().height() - DRIBBBLE_CANVAS_HEIGHT)/FRAME_COUNT) 48 | } 49 | 50 | function addNextAnimationStep(step_number) { 51 | var temp_artboard = [base_artboard copy]; 52 | var temp_frame = [temp_artboard frame]; 53 | var name_count = step_number < 10 ? '0'+step_number : step_number; 54 | 55 | [temp_artboard setName: "FRAME "+ name_count]; 56 | [temp_frame setX: step_number * (DRIBBBLE_CANVAS_WIDTH + PADDING)]; 57 | 58 | addLayerToCurrentPage(temp_artboard); 59 | var temp_layer = temp_artboard.layers().firstObject(); 60 | setPosition(temp_layer.frame(), 0, -(step_number * sizeOfStep)); 61 | } 62 | 63 | if (context.selection.length() == 0) showError("Please select the base layer so I have something to work on :)"); 64 | 65 | const DRIBBBLE_CANVAS_WIDTH = 800; 66 | const DRIBBBLE_CANVAS_HEIGHT = 600; 67 | const PADDING = 100; 68 | var user_selected_layer = context.selection[0]; 69 | var document = context.document 70 | var FRAME_COUNT = [document askForUserInput:"How many frames should the animation have?" initialValue:"0"] 71 | var new_page = document.addBlankPage().setName('ANIMATION STEPS'); 72 | 73 | base_artboard = setupBaseArtboard(); 74 | base_layer = setupBaseLayer([user_selected_layer copy]); 75 | base_artboard.addLayers([base_layer]) 76 | addLayerToCurrentPage(base_artboard); 77 | 78 | var sizeOfStep = calculateStepHeight(base_layer); 79 | 80 | for(var i=1; i<=FRAME_COUNT-1; i++) { 81 | log("frame count = " + i); 82 | addNextAnimationStep(i); 83 | } 84 | }; 85 | -------------------------------------------------------------------------------- /Frame Sequencer/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Rodrigo Soares 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Frame Sequencer/sketchpack.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Frame sequencer", 3 | "description": "Let's you create a sequence of frames from given layer. Great in combination with 'Generate gif' plugin.", 4 | "tags": ["frame", "sequence", "gif", "creator"] 5 | } 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Frame Sequencer 2 | 3 | Sketch plugin that helps you prepare frame sequences to combine with [Generate Gif](https://github.com/nathco/Generate-GIF) plugin to generate animated gifs inside Sketch. Perfect for [Dribbble](https://dribbble.com). 4 | 5 | ## Instalation 6 | 1. Download plugin 7 | 2. Navigate the Sketch menu bar to `Plugins ▸ Reveal Plugins Folder...` 8 | 3. Place the `Frame sequencer` folder into the revealed plugins directory 9 | 4. That's it... 10 | 11 | ## Usage 12 | 1. Select a layer to animate 13 | 2. Frame sequencer > Create sequence 14 | 3. Enter how many frames you want to get 15 | 4. Check 'ANIMATION STEPS' page. 16 | 5. We use 'Generate GIF' name sequence so you can use it just like that to create a Gif. 17 | 18 | ## Perfect for dribbblers 19 | Frame sequencer takes selected layer and scales it to the size of Dribbble canvas (800px x 600px). 20 | 21 | ## Showcase 22 | ###How it works: 23 | ![Create sequence](./images/plugin_record.gif) 24 | 25 | ###Combine with [Generate Gif](https://github.com/nathco/Generate-GIF) plugin: 26 | ![Create gif with Generate-GIF plugin](./images/plugin_record_2.gif) 27 | 28 | ### Outcome 29 | ![Outcome](./images/sample_outcome.gif) 30 | 31 | ##Contact 32 | 33 | * Follow [@dawidwu](http://twitter.com/dawidwu) on Twitter 34 | * Email 35 | -------------------------------------------------------------------------------- /images/plugin_record.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dawidw/frame-sequencer/3f870761abc25e71bab3bde5ce06b571941e4563/images/plugin_record.gif -------------------------------------------------------------------------------- /images/plugin_record_2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dawidw/frame-sequencer/3f870761abc25e71bab3bde5ce06b571941e4563/images/plugin_record_2.gif -------------------------------------------------------------------------------- /images/sample_outcome.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dawidw/frame-sequencer/3f870761abc25e71bab3bde5ce06b571941e4563/images/sample_outcome.gif --------------------------------------------------------------------------------