├── .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 |
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 |
--------------------------------------------------------------------------------