Draggable elements that have been styled to indicate draggability to users
<svg viewBox="0 0 32 32"> | |
<rect height="4" width="4" y="4" x="0"> | |
<rect height="4" width="4" y="12" x="0"> | |
<rect height="4" width="4" y="20" x="0"> | |
<rect height="4" width="4" y="28" x="0"> | |
<rect height="4" width="4" y="4" x="8"> | |
<rect height="4" width="4" y="12" x="8"> | |
<rect height="4" width="4" y="20" x="8"> | |
<rect height="4" width="4" y="28" x="8"> | |
<rect height="4" width="4" y="4" x="16"> | |
<rect height="4" width="4" y="12" x="16"> | |
<rect height="4" width="4" y="20" x="16"> | |
<rect height="4" width="4" y="28" x="16"> | |
<rect height="4" width="4" y="4" x="24"> | |
<rect height="4" width="4" y="12" x="24"> | |
<rect height="4" width="4" y="20" x="24"> | |
<rect height="4" width="4" y="28" x="24"> | |
</svg> |
/** | |
* Styles for the main 'things' we are dragging | |
* | |
* - Give the cursor a specific state when hovering over the draggable elements | |
* - Give the elements a solid background | |
* - Create a basic rectangular shape for the draggable elements with plenty of space | |
* - Set the z-index to 1 as a baseline | |
* - Use a slight box shadow around the edges of the draggable elements | |
* - A solid 1px border is a good alternative if box-shadow is not your cup of tea | |
*/ | |
.thing { | |
/** | |
* Setting the cursor state to 'move' or 'grab' is key to indicating draggability | |
* for desktop users | |
*/ | |
cursor: move; | |
/** | |
* If no background is given, the draggable elements are see-through and thus will not cover | |
* one another when stacked, or when one is dragged over the other. | |
*/ | |
background: #fcfcfc; | |
height: 2em; | |
width: 300px; | |
max-width: 100%; | |
padding: 0.5em; | |
margin-bottom: 0.5em; | |
z-index: 1; | |
box-shadow: rgba( 0, 0, 0, 0.3 ) 0px 0px 1px 1px; | |
} /* .thing */ | |
/** | |
* Elements inside of each draggable .thing (such as the label) need to have the same cursor | |
* property as the .thing's themselves | |
*/ | |
.thing * { | |
cursor: move; | |
} | |
/** | |
* Make sure that an element actively being dragged has a higher z-index than | |
* the others. The class 'ui-draggable-dragging' is automatically added by jQuery UI. | |
*/ | |
.thing.ui-draggable-dragging { | |
z-index: 100; | |
} | |
/** | |
* The text labels for the draggable elements | |
* | |
* We're mainly styling these to make them vertically centered, so we're using absolute positioning | |
* combined with the `margin: auto` rule to achive this | |
*/ | |
.thing label { | |
height: 1em; | |
position: absolute; | |
left: 1em; | |
top: 0; | |
bottom: 0; | |
margin: auto; | |
} | |
/** | |
* The group of dots which indicate draggability for each 'thing' | |
* | |
* Here, we are just declaring the dimensions and positioning. The actual dots themselves are an SVG graphic | |
* which is generated via JavaScript in js/draggable.js | |
*/ | |
.draggable-indicator { | |
width: 16px; | |
height: 16px; | |
position: absolute; | |
right: 0.5em; | |
top: 0; | |
bottom: 0; | |
margin: auto; | |
} | |
/* coloring the individual dots within each group */ | |
.draggable-indicator rect { | |
fill: #ccc; | |
} |
<!-- CSS Stylesheet --> | |
<link rel='stylesheet' type='text/css' href='css/draggable.css' /> | |
<!-- The things we are dragging --> | |
<div class='thing'><label>Thing 1</label></div> | |
<div class='thing'><label>Thing 2</label></div> | |
<div class='thing'><label>Thing 3</label></div> | |
<!-- jQuery and jQuery-UI --> | |
<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> | |
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"></script> | |
<!-- Our own JavaScripts --> | |
<script type='text/javascript' src='js/draggable.js'></script> |
/** | |
* Draggable main routine | |
* | |
* - Make our things draggable | |
* - Append a draggable indicator to each draggable 'thing' | |
*/ | |
$('.thing').draggable(); | |
$('.thing').append( '<div class="draggable-indicator">' + getDraggableIndicator() + '</div>' ); | |
/** | |
* Subroutines | |
* | |
* - getDraggableIndicator() | |
*/ | |
/** | |
* Return the SVG element for the draggable indicator | |
* | |
* @param object args Arguments for the svg element | |
* | |
* int sideLength The length of one side of the outer square (default: 32) | |
* int dotWidth The height/width of a single dot (default: 4) | |
* int initialX The initial x value for the first dot (default: 4) | |
* int initialY The initial y value for the first dot (default: 4) | |
* int offset The distance between dots (default: 8) | |
* | |
* @return string | |
*/ | |
function getDraggableIndicator( args ) { | |
args = args || {}; | |
// get the default values | |
var sideLength = args.sideLength || 32, | |
dotWidth = args.dotWidth || 4, | |
offset = args.offset || 8, | |
// zero is a legit value for the initial X and Y values, so allow for this | |
initialX = ( undefined === args.initialX ) ? 4 : args.initialX, | |
initialY = ( undefined === args.initialY ) ? 4 : args.initialY; | |
// build the HTML element string | |
var svg = '<svg viewBox="0 0 ' + sideLength + ' ' + sideLength + '">'; | |
// do a 4x4 loop and create the <rect /> elements | |
for ( var i = 0; i < 4; i++ ) { | |
for( var j = 0; j < 4; j++ ) { | |
svg += '<rect x="' + ( initialX + i*offset ) + '" ' + | |
'y="' + ( initialY + j*offset ) + '"' + | |
' width="' + dotWidth + '" height="' + dotWidth + '" ' + | |
' />'; | |
} | |
} | |
svg += '</svg>'; | |
return svg; | |
} // end: getDraggableIndicator() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment