Created
June 10, 2014 20:44
-
-
Save john45traver/53649a9531f9d4a3b1a4 to your computer and use it in GitHub Desktop.
Rearrangeable Grid Coffeescript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Engine = require 'famous/core/Engine' | |
Surface = require 'famous/core/Surface' | |
View = require 'famous/core/View' | |
Transform = require 'famous/core/Transform' | |
RenderNode = require 'famous/core/RenderNode' | |
StateModifier = require 'famous/modifiers/StateModifier' | |
Easing = require 'famous/transitions/Easing' | |
Transitionable = require 'famous/transitions/Transitionable' | |
SpringTransition = require 'famous/transitions/SpringTransition' | |
WallTransition = require 'famous/transitions/WallTransition' | |
SnapTransition = require 'famous/transitions/SnapTransition' | |
EventHandler = require 'famous/core/EventHandler' | |
EventFilter = require 'famous/events/EventFilter' | |
Scrollview = require 'famous/views/Scrollview' | |
ImageSurface = require 'famous/surfaces/ImageSurface' | |
ContainerSurface = require 'famous/surfaces/ContainerSurface' | |
SequentialLayout = require 'famous/views/SequentialLayout' | |
ScrollContainer = require 'famous/views/ScrollContainer' | |
Timer = require 'famous/utilities/Timer' | |
Draggable = require 'famous/modifiers/Draggable' | |
GridLayout = require 'famous/views/GridLayout' | |
ModifierChain = require 'famous/modifiers/ModifierChain' | |
Transitionable.registerMethod 'wall', WallTransition | |
Transitionable.registerMethod 'spring', SpringTransition | |
Transitionable.registerMethod 'snap', SnapTransition | |
wall = { method :'wall', period: 300, dampingRatio: 0.3 } | |
spring = { method:'spring', period: 300, dampingRatio: 0.4 } | |
snap = { method :'snap', period: 400, dampingRatio: 0.6 } | |
button_snap = { method :'snap', period: 300, dampingRatio: 0.4 } | |
@event_handler = new EventHandler() | |
@context = Engine.createContext() | |
@context.setPerspective(1000) | |
@context_size = @context.getSize() | |
@end_event = if Modernizr.touch then 'touchend' else 'mouseup' | |
@move_event = if Modernizr.touch then 'touchmove' else 'mousemove' | |
@start_event = if Modernizr.touch then 'touchstart' else 'mousedown' | |
background_surface = new Surface({ | |
size: [undefined,undefined] | |
properties: { | |
backgroundColor: 'black' | |
} | |
}) | |
@context.add(background_surface) | |
@num_cells = 12 | |
@min_width = 180 | |
@cells_x = Math.floor(@context_size[0] / @min_width) | |
@cells_y = Math.ceil(@num_cells / @cells_x) | |
@grid = new GridLayout({ | |
dimensions: [@cells_x,@cells_y] | |
}) | |
@grid_cells = [] | |
@grid.sequenceFrom @grid_cells | |
@grid_view_grid = new ContainerSurface({ | |
size:[undefined,@cells_y*200] | |
}) | |
@grid_view = new View({size:[undefined,@cells_y*200]}) | |
scroll_content = [] | |
@grid_scroll = new Scrollview({ | |
size:[undefined,undefined] | |
}) | |
@grid_scroll.sequenceFrom scroll_content | |
@grid_view_grid.add(@grid) | |
@grid_view.pipe(@grid_scroll) | |
@grid_view_grid.pipe(@grid_scroll) | |
@surfaces = [] | |
@surface_selected = null | |
for i in [0..@num_cells-1] | |
color = "hsl(#{i * 360 / 16},100%,50%)" | |
surface = new Surface({ | |
size: [undefined,undefined], | |
properties: { | |
backgroundColor: color | |
border: '4px solid white' | |
cursor: 'move' | |
} | |
}) | |
surface.pipe(@grid_scroll) | |
surface.in_front = new StateModifier({ | |
transform: Transform.inFront | |
}) | |
surface.chain = new ModifierChain() | |
surface.state = new StateModifier({ | |
size: [160,160], | |
origin: [0.5,0.5], | |
transform: Transform.translate(0,0,0) | |
}) | |
surface.chain.addModifier(surface.state) | |
surface.draggable = new Draggable({ | |
xRange: [0, @context_size[0]], | |
yRange: [0, @context_size[1]] | |
}) | |
surface.draggable.surface = surface | |
surface.on 'mousedown', (e) => | |
e.preventDefault() | |
e.stopPropagation() | |
surface.draggable.on 'start', (e) => | |
if !@surface_selected | |
@surface_selected = e.origin.surface | |
@surface_selected.unpipe(@grid_scroll) | |
@surface_selected.view.chain.addModifier(@surface_selected.in_front) | |
@surface_selected.chain.addModifier(@surface_selected.in_front) | |
grid_size = @grid_view.getSize() | |
@surface_selected.draggable.setOptions({ | |
xRange: [0, @context_size[0]] | |
yRange: [0, grid_size[1]] | |
}) | |
@cleared_position = @surface_selected.index | |
for surface in @surfaces | |
if surface != @surface_selected | |
surface.setProperties({pointerEvents:'none'}) | |
@surface_selected.state.halt() | |
@surface_selected.state.setSize([140,140],snap) | |
surface.draggable.on 'update', (e) => | |
determine_collision(@surface_selected,false) | |
surface.draggable.on 'end', (e) => | |
if @surface_selected | |
@surface_selected.pipe(@grid_scroll) | |
@surface_selected.view.chain.removeModifier(@surface_selected.in_front) | |
for surface in @surfaces | |
surface.setProperties({pointerEvents:'all'}) | |
surface = @surface_selected | |
@surface_selected.state.halt() | |
@surface_selected.state.setSize([160,160],snap) | |
@surface_selected = null | |
determine_collision(surface,true) | |
surface.index = i | |
surface.view = new ContainerSurface({size:[160,160]}) | |
surface.view.pipe(@grid_scroll) | |
surface.pipe(surface.draggable) | |
surface.view.add(surface.state).add(surface) | |
surface.view.chain = new ModifierChain() | |
surface.view.state = new StateModifier({ origin: [0,0] }) | |
surface.view.chain.addModifier(surface.view.state) | |
@grid_view.add(surface.draggable).add(surface.view.chain).add(surface.view) | |
@surfaces.push surface | |
scroll_content.push(@grid_view) | |
@context.add(@grid_view_grid) | |
@context.add(@grid_scroll) | |
check_for_modifiers = () => | |
if (@grid._modifiers && @grid._modifiers.length > 0) | |
cell_size = @grid._modifiers[0].getSize() | |
for surface in @surfaces | |
move_to_point(surface,surface.index) | |
Engine.removeListener 'prerender', check_for_modifiers | |
Engine.on 'prerender', check_for_modifiers | |
Engine.on 'resize', () => | |
if (@grid._modifiers && @grid._modifiers.length > 0) | |
@context_size = @context.getSize() | |
@cells_x = Math.floor(@context_size[0] / @min_width) | |
@cells_y = Math.ceil(@num_cells / @cells_x) | |
@grid_view_grid.setSize([undefined,@cells_y*200]) | |
@grid_view.setOptions({size:[undefined,@cells_y*200]}) | |
@grid.setOptions({dimensions:[@cells_x,@cells_y]}) | |
for surface in @surfaces | |
move_to_point(surface,surface.index,{duration:0}) | |
move_to_point = (surface, p,transition) => | |
transition = snap if !transition | |
modifier = @grid._modifiers[p] | |
translate = Transform.interpret(modifier.getTransform())['translate'] | |
size = modifier.getSize() | |
center = [translate[0] + Math.round(size[0] / 2.0),translate[1] + Math.round(size[1] / 2.0),0] | |
surface_size = [160,160] | |
center_offset = [center[0] - Math.round(surface_size[0]/2.0),center[1] - Math.round(surface_size[1]/2.0),0] | |
surface.draggable.setPosition(center_offset,transition,(() -> | |
this.state.setTransform(Transform.translate(0,0,0))).bind(surface) ) | |
determine_collision = (surface,move=false) => | |
surface_size = [160,160] | |
surface_position = surface.draggable.getPosition() | |
scroll_pos = @grid_scroll.getPosition() | |
surface_center = [surface_position[0] + (surface_size[0]/2.0),surface_position[1] + (surface_size[1]/2.0)] | |
index = 0 | |
for modifier in @grid._modifiers | |
translate = Transform.interpret(modifier.getTransform())['translate'] | |
size = modifier.getSize() | |
x_fit = surface_center[0] > translate[0] && surface_center[0] < (translate[0] + size[0]) | |
y_fit = surface_center[1] > translate[1] && surface_center[1] < (translate[1] + size[1]) | |
if x_fit && y_fit | |
clear_cell_position(index) | |
move_to_point(surface,index) if move | |
break | |
else | |
index += 1 | |
clear_cell_position = (index) => | |
if index != @cleared_position | |
for surface in @surfaces | |
if surface.index > @cleared_position && surface.index <= index | |
if surface.index == 0 | |
surface.index = @num_cells - 1 | |
else | |
surface.index = surface.index - 1 | |
move_to_point(surface,surface.index) | |
else if surface.index < @cleared_position && surface.index >= index | |
if surface.index == (@num_cells - 1) | |
surface.index = 0 | |
else | |
surface.index = surface.index + 1 | |
move_to_point(surface,surface.index) | |
@surface_selected.index = index | |
@cleared_position = index |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment