11import KeyHandler , { KEYDOWN } from 'react-key-handler'
22import ReactCSSTransitionGroup from 'react-transition-group/CSSTransitionGroup'
33import React from 'react'
4+ import Swipeable from 'react-swipeable'
5+ import Head from 'next/head'
46
57const width = 500
68
@@ -26,12 +28,12 @@ const Dot = ({x, y, type, floating}) => (
2628 style = { {
2729 position : 'absolute' ,
2830 transition : ! floating ? 'top 0.4s, left 0.06s linear' : '0.1s' ,
29- left : `${ width / 7 * x } px ` ,
30- top : `${ width / 7 * y } px ` ,
31+ left : `${ 100 / 7 * x } % ` ,
32+ top : `${ 100 / 7 * y } % ` ,
3133 background : colors [ type ] ,
3234 borderRadius : '50%' ,
33- width : `${ width / 7 } px ` ,
34- height : `${ width / 7 } px `
35+ width : `${ 100 / 7 } % ` ,
36+ height : `${ 100 / 7 } % `
3537 } }
3638 />
3739)
@@ -41,10 +43,12 @@ const Levels = ({current}) => {
4143 < div
4244 style = { {
4345 position : 'absolute' ,
44- left : `-${ width / colors . length + 10 } px` ,
45- top : 0 ,
46+ left : 0 ,
47+ top : '100%' ,
48+ width : '100%' ,
49+ height : `${ 100 } %` ,
4650 display : 'flex' ,
47- flexDirection : 'column -reverse'
51+ flexDirection : 'row -reverse'
4852 } }
4953 >
5054 { colors . map ( ( c , i ) => {
@@ -54,8 +58,8 @@ const Levels = ({current}) => {
5458 style = { {
5559 background : c ,
5660 opacity : current >= i ? 1 : 0.2 ,
57- width : `${ width / colors . length } px ` ,
58- height : `${ width / colors . length } px `
61+ width : `${ 100 / colors . length } % ` ,
62+ height : `${ 100 / colors . length } % `
5963 } }
6064 />
6165 )
@@ -170,7 +174,7 @@ class Page extends React.Component {
170174 { x : 10 , y : - 2 }
171175 )
172176
173- if ( newColoredDot . type !== colors . length - 1 ) {
177+ if ( newColoredDot . type < colors . length - 1 ) {
174178 freshDots . push (
175179 this . newDotAt (
176180 newColoredDot . x ,
@@ -273,36 +277,30 @@ class Page extends React.Component {
273277 rotateDots ( ) {
274278 const dots = this . state . floatingDots
275279 if ( ! dots . length ) return
280+ var newFloatingDots
276281 if ( dots [ 0 ] . y === dots [ 1 ] . y ) {
277282 if ( dots [ 0 ] . x < dots [ 1 ] . x ) {
278- return this . setState ( {
279- ...this . state ,
280- floatingDots : [
281- {
282- ...dots [ 0 ] ,
283- y : dots [ 1 ] . y - 1 ,
284- x : dots [ 1 ] . x
285- } ,
286- dots [ 1 ]
287- ]
288- } )
289- }
290- return this . setState ( {
291- ...this . state ,
292- floatingDots : [
283+ newFloatingDots = [
284+ {
285+ ...dots [ 0 ] ,
286+ y : dots [ 1 ] . y - 1 ,
287+ x : dots [ 1 ] . x
288+ } ,
289+ dots [ 1 ]
290+ ]
291+ } else {
292+ newFloatingDots = [
293293 dots [ 0 ] ,
294294 {
295295 ...dots [ 1 ] ,
296296 y : dots [ 0 ] . y - 1 ,
297297 x : dots [ 0 ] . x
298298 }
299299 ]
300- } )
301- }
302- if ( dots [ 0 ] . y < dots [ 1 ] . y ) {
303- return this . setState ( {
304- ...this . state ,
305- floatingDots : [
300+ }
301+ } else {
302+ if ( dots [ 0 ] . y < dots [ 1 ] . y ) {
303+ newFloatingDots = [
306304 {
307305 ...dots [ 0 ] ,
308306 x : dots [ 1 ] . x ,
@@ -314,41 +312,82 @@ class Page extends React.Component {
314312 y : dots [ 1 ] . y
315313 }
316314 ]
317- } )
315+ } else {
316+ newFloatingDots = [
317+ {
318+ ...dots [ 0 ] ,
319+ x : dots [ 0 ] . x - 1 ,
320+ y : dots [ 0 ] . y
321+ } ,
322+ {
323+ ...dots [ 1 ] ,
324+ x : dots [ 0 ] . x ,
325+ y : dots [ 0 ] . y
326+ }
327+ ]
328+ }
329+ }
330+ if ( newFloatingDots [ 0 ] . x < 0 || newFloatingDots [ 1 ] . x < 0 ) {
331+ newFloatingDots = newFloatingDots . map ( d => ( {
332+ ...d ,
333+ x : d . x + 1
334+ } ) )
318335 }
319336 this . setState ( {
320337 ...this . state ,
321- floatingDots : [
322- {
323- ...dots [ 0 ] ,
324- x : dots [ 0 ] . x - 1 ,
325- y : dots [ 0 ] . y
326- } ,
327- {
328- ...dots [ 1 ] ,
329- x : dots [ 0 ] . x ,
330- y : dots [ 0 ] . y
331- }
332- ]
338+ floatingDots : newFloatingDots
333339 } )
334340 }
341+
342+ isCloseToAngle ( angle , target ) {
343+ const tolerance = 0.6
344+ return target - tolerance < angle && angle < target + tolerance
345+ }
346+
347+ swiped ( e , deltaX , deltaY , isFlick , velocity ) {
348+ if ( ! isFlick ) return
349+ e . preventDefault ( )
350+
351+ const angle = Math . atan2 ( deltaY , deltaX )
352+ console . log ( angle )
353+ if ( this . isCloseToAngle ( angle , 0 ) ) {
354+ this . moveDotsLeft ( )
355+ } else if ( this . isCloseToAngle ( angle , Math . PI ) ) {
356+ this . moveDotsRight ( )
357+ } else if ( this . isCloseToAngle ( angle , Math . PI / 2 ) ) {
358+ this . rotateDots ( )
359+ } else if ( this . isCloseToAngle ( angle , - Math . PI / 2 ) ) {
360+ this . pushDots ( )
361+ }
362+ }
335363 render ( ) {
336364 return (
337- < div
338- style = { {
339- display : 'flex' ,
340- alignItems : 'center' ,
341- justifyContent : 'center' ,
342- position : 'fixed' ,
343- background : '#f5f5f5' ,
344- margin : 0 ,
345- top : 0 ,
346- bottom : 0 ,
347- left : 0 ,
348- right : 0
349- } }
350- >
351- < style jsx global > { `
365+ < Swipeable onSwiped = { this . swiped . bind ( this ) } >
366+
367+ < Head >
368+ < title > Combine!</ title >
369+ < meta charSet = 'utf-8' />
370+ < meta
371+ name = 'viewport'
372+ content = 'initial-scale=1.0, width=device-width'
373+ />
374+ </ Head >
375+
376+ < div
377+ style = { {
378+ display : 'flex' ,
379+ alignItems : 'center' ,
380+ justifyContent : 'center' ,
381+ position : 'fixed' ,
382+ background : '#f5f5f5' ,
383+ margin : 0 ,
384+ top : 0 ,
385+ bottom : 0 ,
386+ left : 0 ,
387+ right : 0
388+ } }
389+ >
390+ < style jsx global > { `
352391.example-enter {
353392 transform: scale(1.7);
354393 border-radius: 0% !important;
@@ -376,68 +415,71 @@ class Page extends React.Component {
376415}
377416 ` } </ style >
378417
379- < KeyHandler
380- keyEventName = { KEYDOWN }
381- keyValue = 'ArrowDown'
382- onKeyHandle = { ( ) => this . pushDots ( ) }
383- />
384- < KeyHandler
385- keyEventName = { KEYDOWN }
386- keyValue = 'ArrowLeft'
387- onKeyHandle = { ( ) => this . moveDotsLeft ( ) }
388- />
389- < KeyHandler
390- keyEventName = { KEYDOWN }
391- keyValue = 'ArrowRight'
392- onKeyHandle = { ( ) => this . moveDotsRight ( ) }
393- />
394- < KeyHandler
395- keyEventName = { KEYDOWN }
396- keyValue = 'ArrowUp'
397- onKeyHandle = { ( ) => this . rotateDots ( ) }
398- />
418+ < KeyHandler
419+ keyEventName = { KEYDOWN }
420+ keyValue = 'ArrowDown'
421+ onKeyHandle = { ( ) => this . pushDots ( ) }
422+ />
423+ < KeyHandler
424+ keyEventName = { KEYDOWN }
425+ keyValue = 'ArrowLeft'
426+ onKeyHandle = { ( ) => this . moveDotsLeft ( ) }
427+ />
428+ < KeyHandler
429+ keyEventName = { KEYDOWN }
430+ keyValue = 'ArrowRight'
431+ onKeyHandle = { ( ) => this . moveDotsRight ( ) }
432+ />
433+ < KeyHandler
434+ keyEventName = { KEYDOWN }
435+ keyValue = 'ArrowUp'
436+ onKeyHandle = { ( ) => this . rotateDots ( ) }
437+ />
399438
400- < div
401- style = { {
402- position : 'relative' ,
403- border : '1px solid #ddd' ,
404- width : `${ width } px` ,
405- height : `${ width } px` ,
406- background : '#fff'
407- } }
408- >
409439 < div
410440 style = { {
411- display : this . state . gameover ? 'block' : 'none' ,
412- position : 'absolute' ,
413- left : '50%' ,
414- top : '50%' ,
415- transform : 'translate(-50%, -50%)' ,
416- fontSize : '50px' ,
417- fontFamily : 'Open sans, sans-serif' ,
418- whiteSpace : 'nowrap' ,
419- color : '#d50000' ,
420- fontWeight : 'bold'
441+ position : 'relative' ,
442+ border : '1px solid #ddd' ,
443+ width : `${ width } px` ,
444+ paddingBottom : '100%' ,
445+ height : 0 ,
446+ maxWidth : '100%' ,
447+ background : '#fff'
421448 } }
422449 >
423- GAME OVER
450+ < div
451+ style = { {
452+ display : this . state . gameover ? 'block' : 'none' ,
453+ position : 'absolute' ,
454+ left : '50%' ,
455+ top : '50%' ,
456+ transform : 'translate(-50%, -50%)' ,
457+ fontSize : '50px' ,
458+ fontFamily : 'Open sans, sans-serif' ,
459+ whiteSpace : 'nowrap' ,
460+ color : '#d50000' ,
461+ fontWeight : 'bold'
462+ } }
463+ >
464+ GAME OVER
465+ </ div >
466+ < Levels current = { this . state . level } />
467+ < ReactCSSTransitionGroup
468+ transitionName = 'example'
469+ transitionEnterTimeout = { 300 }
470+ transitionLeaveTimeout = { 400 }
471+ >
472+ { this . state . dots
473+ . concat (
474+ this . state . floatingDots . map ( i => ( { ...i , floating : true } ) )
475+ )
476+ . map ( params => {
477+ return < Dot { ...params } />
478+ } ) }
479+ </ ReactCSSTransitionGroup >
424480 </ div >
425- < Levels current = { this . state . level } />
426- < ReactCSSTransitionGroup
427- transitionName = 'example'
428- transitionEnterTimeout = { 300 }
429- transitionLeaveTimeout = { 400 }
430- >
431- { this . state . dots
432- . concat (
433- this . state . floatingDots . map ( i => ( { ...i , floating : true } ) )
434- )
435- . map ( params => {
436- return < Dot { ...params } />
437- } ) }
438- </ ReactCSSTransitionGroup >
439481 </ div >
440- </ div >
482+ </ Swipeable >
441483 )
442484 }
443485}
0 commit comments