├── .gitignore ├── draggable.css ├── Makefile ├── component.json ├── History.md ├── test.html ├── styles.css ├── Readme.md └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | components 2 | build 3 | -------------------------------------------------------------------------------- /draggable.css: -------------------------------------------------------------------------------- 1 | 2 | .draggable[draggable] { 3 | cursor: move; 4 | } 5 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | build: components index.js draggable.css 3 | @component build --dev 4 | 5 | components: component.json 6 | @component install --dev 7 | 8 | clean: 9 | rm -fr build components 10 | 11 | .PHONY: clean 12 | -------------------------------------------------------------------------------- /component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "draggable", 3 | "repo": "stephenmathieson/draggable", 4 | "description": "Make an element draggable", 5 | "version": "0.1.1", 6 | "keywords": ["dragable", "drag", "drop"], 7 | "dependencies": { 8 | "gjohnson/uuid": "*" 9 | }, 10 | "license": "MIT", 11 | "main": "index.js", 12 | "scripts": ["index.js"], 13 | "styles": ["draggable.css"] 14 | } 15 | -------------------------------------------------------------------------------- /History.md: -------------------------------------------------------------------------------- 1 | 2 | 0.1.1 / 2014-11-06 3 | ================== 4 | 5 | * index: Ignore image ondragstart 6 | * test: Add an example containing images 7 | 8 | 0.1.0 / 2014-05-15 9 | ================== 10 | 11 | * Adds support for bottom and right style properties 12 | 13 | 0.0.1 / 2014-03-06 14 | ================== 15 | 16 | * Fix license 17 | 18 | 0.0.0 / 2014-02-11 19 | ================== 20 | 21 | * Initial commit 22 | -------------------------------------------------------------------------------- /test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Draggable 7 | 8 | 9 | 10 | 11 |

Draggable

12 |
13 |
14 | 15 | 16 | 17 | 18 |
19 |
20 |
21 | 22 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /styles.css: -------------------------------------------------------------------------------- 1 | 2 | html { 3 | height: 100%; 4 | width: 100%; 5 | font-family: Helvetica, sans-serif; 6 | background-color: #eee; 7 | color: #bbb; 8 | } 9 | 10 | body { 11 | height: calc(100% - 40px); 12 | margin: 0; 13 | padding: 20px; 14 | } 15 | 16 | h1 { 17 | margin: 0; 18 | font-weight: 300; 19 | } 20 | 21 | .draggable[draggable] { 22 | position: absolute; 23 | height: 200px; 24 | width: 200px; 25 | background-color: #bbb; 26 | color: #eee; 27 | font-size: 1.4em; 28 | } 29 | 30 | #top-left { 31 | top: 100px; 32 | left: 100px; 33 | } 34 | 35 | #top-left:before { 36 | position: absolute; 37 | top: 10px; 38 | left: 10px; 39 | content: 'TL'; 40 | } 41 | 42 | #top-right { 43 | top: 100px; 44 | right: 100px; 45 | } 46 | 47 | #top-right:before { 48 | position: absolute; 49 | top: 10px; 50 | right: 10px; 51 | content: 'TR'; 52 | } 53 | 54 | #bottom-left { 55 | bottom: 100px; 56 | left: 100px; 57 | } 58 | 59 | #bottom-left:before { 60 | position: absolute; 61 | bottom: 10px; 62 | left: 10px; 63 | content: 'BL'; 64 | } 65 | 66 | #bottom-right { 67 | bottom: 100px; 68 | right: 100px; 69 | } 70 | 71 | #bottom-right:before { 72 | position: absolute; 73 | bottom: 10px; 74 | right: 10px; 75 | content: 'BR'; 76 | } 77 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | 2 | # draggable 3 | 4 | Make an element draggable. 5 | 6 | ## Installation 7 | 8 | Install with [component(1)](http://component.io): 9 | 10 | $ component install stephenmathieson/draggable 11 | 12 | ## API 13 | 14 | ### draggable(element, [container]) 15 | 16 | Make `element` draggable within `container`, defaulting to the body. 17 | 18 | ## License 19 | 20 | (The MIT License) 21 | 22 | Copyright (c) 2014 Stephen Mathieson <me@stephenmathieson.com> 23 | 24 | Permission is hereby granted, free of charge, to any person obtaining 25 | a copy of this software and associated documentation files (the 26 | 'Software'), to deal in the Software without restriction, including 27 | without limitation the rights to use, copy, modify, merge, publish, 28 | distribute, sublicense, and/or sell copies of the Software, and to 29 | permit persons to whom the Software is furnished to do so, subject to 30 | the following conditions: 31 | 32 | The above copyright notice and this permission notice shall be 33 | included in all copies or substantial portions of the Software. 34 | 35 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 36 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 37 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 38 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 39 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 40 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 41 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var uuid = require('uuid'); 7 | 8 | module.exports = draggable; 9 | 10 | /** 11 | * Make `element` draggable within `container`, 12 | * defaulting to the body. 13 | * 14 | * Uses `top` and `left` positions by default. 15 | * Uses `bottom` and `right` in lieu of their 16 | * counterparts. 17 | * 18 | * @api public 19 | * @param {HTMLElement} element 20 | * @param {HTMLElement} [container] 21 | */ 22 | 23 | function draggable(element, container) { 24 | container = container || document.body; 25 | var id = uuid(); 26 | 27 | element.classList.add('draggable'); 28 | element.draggable = true; 29 | 30 | element.addEventListener('dragstart', ondragstart); 31 | container.addEventListener('dragover', ondragover); 32 | container.addEventListener('drop', ondrop); 33 | 34 | function ondragstart(e) { 35 | if ('IMG' == e.target.nodeName) return; 36 | var o = offset(e); 37 | e.dataTransfer.setData(id, JSON.stringify(o)); 38 | } 39 | 40 | function ondragover(e) { 41 | e.preventDefault(); 42 | } 43 | 44 | function ondrop(e) { 45 | var data = e.dataTransfer.getData(id); 46 | if (!data) return; 47 | data = JSON.parse(data); 48 | 49 | if (data.left) { 50 | element.style.left = (e.clientX + data.left) + 'px'; 51 | } else { 52 | element.style.right = ((window.innerWidth - e.clientX) + data.right) + 'px'; 53 | } 54 | 55 | if (data.top) { 56 | element.style.top = (e.clientY + data.top) + 'px'; 57 | } else { 58 | element.style.bottom = ((window.innerHeight - e.clientY) + data.bottom) + 'px'; 59 | } 60 | 61 | e.preventDefault(); 62 | } 63 | } 64 | 65 | /** 66 | * Get the offset for the given `e`. 67 | * 68 | * @api private 69 | * @param {Event} e 70 | * @return {Object} 71 | */ 72 | 73 | function offset(e) { 74 | var style = getComputedStyle(e.target, null); 75 | return { 76 | left: parseValue(style, 'left') - e.clientX, 77 | right: parseValue(style, 'right') - (window.innerWidth - e.clientX), 78 | top: parseValue(style, 'top') - e.clientY, 79 | bottom: parseValue(style, 'bottom') - (window.innerHeight - e.clientY) 80 | }; 81 | } 82 | 83 | /** 84 | * Get the value of the CSS property `name` as an int. 85 | */ 86 | 87 | function parseValue(style, name) { 88 | return parseInt(style.getPropertyValue(name), 10); 89 | } 90 | --------------------------------------------------------------------------------