PDA

View Full Version : Drag and Drop Image Reorder



tibberous
September 22nd, 2008, 04:12 AM
I am trying to make a drag and drop image gallery, with limited success. Here is what I have so far:

trenttompkins.com/Gallery.rar

It has dragable icons that snap to grid. I am trying to make it so when you drag an icon over top another icon, it slides the rest of the icons down.

I'm posting in hopes that someone will find it useful, and that maybe someone can get the last part working. A few of the algorithms, like snap-to-grid, drag-and-drop and dynamic row/column placement are worth taking a look at if you haven't seen them before.

nortago
September 22nd, 2008, 08:40 AM
It's pretty unreliable as it is tibberous, I was getting weird placements all over the place... It's a neat concept - something I tried a while ago to implement into a flash cms... I've got code somewhere, I'll route out...

*routes*

Here you go.. if it's any help... it only works on a single axis, but if you can pull anything from it






package com.liamr.display{

import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.*;

import gs.TweenLite;

public class lrMenu extends Sprite {

private var itemsNum:int;

private var contentXML:XMLList;

private var boxes:Array;

private var container:MovieClip;

private var b:MovieClip;

private var menuOrientation:String;

private var menuSpeed:Number;

private var menuSpacing:Number;

private var originalSize:Number;

private var openedSize:Number;

public function lrMenu(menuXML:XMLList) {

contentXML = menuXML;

boxes = new Array();

originalSize = 60;

openedSize = 400;

container = new MovieClip();

menuOrientation = "vertical";

menuSpeed = 0.5;

menuSpacing = 10;

itemsNum = menuXML.length();

initMenu();

}
public function initMenu():void {
container.x = 0;
container.y = 90;
addChild(container);

addEventListener(MouseEvent.MOUSE_UP, onStageUp, false, 0, true);

addEventListener(Event.ENTER_FRAME, onLoop, false, 0, true);

for (var i:int = 0; i < itemsNum; i++) {
b = new menuItem();
if (menuOrientation == "horizontal") {
//Doesn't slide in
b.x = 50 + b.width * i;
}
if (menuOrientation == "vertical") {
b.y = 0 + b.height * i;
}

b.title_txt.text = contentXML[i].@id.toUpperCase();
//b.alpha = 0.5;
//Add drag drop functionality...
setupDraggableBox(b);
setupRollOver(b);
container.addChild(b);
}
}
private function setupRollOver(mc:MovieClip):void {

mc._opened = false;
mc._scaleDest = originalSize;
b.buttonMode = true;
b.mouseChildren = false;
mc.addEventListener(MouseEvent.ROLL_OVER, onOver, false, 0, true);
mc.addEventListener(MouseEvent.ROLL_OUT, onOut, false, 0, true);
mc.addEventListener(MouseEvent.CLICK, onClick, false, 0, true);
mc.addEventListener(Event.ENTER_FRAME, onScale, false, 0, true);
}
private function onScale(evt:Event):void {
var mc:MovieClip = MovieClip(evt.target);

if(menuOrientation == "horizontal"){
TweenLite.to(mc.bg, menuSpeed, {width:mc._scaleDest});
}

if(menuOrientation == "vertical"){
TweenLite.to(mc.bg, menuSpeed, {height:mc._scaleDest});
}

}

//Automatic resizin
/*private function onOver(evt:MouseEvent):void {
evt.target._scaleDest = openedSize;
}
private function onOut(evt:MouseEvent):void {
evt.target._scaleDest = originalSize;
}*/


private function onClick(evt:MouseEvent):void {
trace("hello");
evt.target._scaleDest = openedSize;
if(!evt.target._opened){
evt.target._opened = true;
evt.target._scaleDest = openedSize;
} else if (evt.target._opened){
evt.target._opened = false;
evt.target._scaleDest = originalSize;
}

stage.dispatchEvent(new Event(Event.RESIZE));
}

private function onOver(evt:MouseEvent):void {
//evt.target._scaleDest = openedSize;
}
private function onOut(evt:MouseEvent):void {
//evt.target._scaleDest = originalSize;
}




private function setupDraggableBox(mc:MovieClip):void {
if (menuOrientation == "horizontal") {
// local variable for use with zeno's paradox
mc.xDest = mc.x;
// randomize the width to illustrate flexibility
}
if (menuOrientation == "vertical") {
// local variable for use with zeno's paradox
mc.yDest = mc.y;
// randomize the width to illustrate flexibility
}
//Add Drag drop Function
mc.buttonMode = true;
mc.mouseChildren = false;
mc.addEventListener(MouseEvent.MOUSE_DOWN, onDown, false, 0, true);

boxes.push(mc);
}

private function onDown(evt:MouseEvent):void {
removeEventListener(Event.ENTER_FRAME, onLoop);
container.addChild(MovieClip(evt.currentTarget));
evt.target._scaleDest = originalSize;
evt.currentTarget.startDrag();
}

private function onStageUp(evt:MouseEvent):void {
stopDrag();
addEventListener(Event.ENTER_FRAME, onLoop, false, 0, true);
}
private function onLoop(evt:Event):void {
// sort the boxes array by the x property
// of each clip
if (menuOrientation == "horizontal") {
boxes.sortOn("x", Array.NUMERIC);
}
if (menuOrientation == "vertical") {
boxes.sortOn("y", Array.NUMERIC);
}

// make sure the first box always eases to
// the same position (50, 200);
boxes[0].x += (0 - boxes[0].x) / 2;
boxes[0].y += (0 - boxes[0].y) / 2;
boxes[0].currentIndex = 0;

// align boxes
for (var i:int = 1; i < itemsNum; i++) {
var b:MovieClip = boxes[i];
var prev:MovieClip = boxes[i - 1];
b.currentIndex = i;
if (menuOrientation == "horizontal") {
b.xDest = prev.x + prev.width + menuSpacing;
b.x += (b.xDest - b.x) / 2;
b.y += (0 - b.y) / 2;
}
if (menuOrientation == "vertical") {
b.yDest = prev.y + prev.height + menuSpacing;
b.y += (b.yDest - b.y) / 2 ;
b.x += (0 - b.x) / 2;
}
}
}
}
}

tibberous
September 22nd, 2008, 09:34 AM
I'll take another crack at it now that I've slept. What I really need to be able to do is return the images to a set state, or quit using i to calculate anything.

gui
September 22nd, 2008, 12:44 PM
Maybe this helps you http://blog.soulwire.co.uk/flash/actionscript-2/prototypes/dynamic-stacking/ , check out.

tibberous
September 23rd, 2008, 01:26 AM
I reupdated my code. Basically, I've VERY close - I think there is a race condition with the way the events are fired, because if you just click and drag stuff really fast, it breaks. I tried adding a frozen variable to fix this, but it hasn't.

Basically, I tried to separate the positioning and the order aspects. I gave everything a positionIndex, then treated the order linearly - so instead of worrying about an x and y, I just had to worry about what position in the list an item was.

gui, your example was cool, but it was in as2, and a lot simpler since it was just a line -- transitions are cool =)

dail
September 23rd, 2008, 01:39 AM
This is done in AS3, similar to soulwires

http://www.learningactionscript3.com/2008/05/13/the-power-of-relative-positioning/

I've thought about making a drag n drop grid a few times, but its one of those projects I never seem to start.

nortago
September 23rd, 2008, 09:25 AM
@dail... that's where the basis of my code came from - learned a lot from that tutorial...
actually, I learned a hell of a lot from your blog too...

nortago
September 23rd, 2008, 09:36 AM
Tibberous - Much better! - runs really good!

tibberous
September 23rd, 2008, 10:24 AM
If you want to see it without downloading:

http://www.trenttompkins.com/tribute/

stuluk28
November 4th, 2008, 06:48 AM
Hi tibberous,

the final version is looking cool. I'm actually try to achieve the same thing to see if I can figure it out. Is it possible that you can supply your source code for this? or simply give a little exlaination of how you managed to sort the items and re-order once an item had been moved and dragged?

Nikhil257
August 12th, 2009, 05:25 PM
If you want to see it without downloading:

http://www.trenttompkins.com/tribute/

Hey,is there a way we can download this script ?