Created
June 10, 2014 20:44
-
-
Save john45traver/53649a9531f9d4a3b1a4 to your computer and use it in GitHub Desktop.
Rearrangeable Grid Coffeescript
This file contains hidden or 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