1
- import { AnimateFunctionParams } from "../types"
1
+ import { AnimateFunctionParams , AnimationStep } from "../types"
2
2
import {
3
3
changeBarsColor ,
4
4
getNumberValueFromElementHeight ,
5
5
postSortAnimation ,
6
6
} from "../utils"
7
7
8
- interface animationHolder {
9
- compare ?: [ number , number ]
10
- idxToInsertTo ?: number
11
- moveFromIdx ?: number
12
- shift ?: number
13
- }
14
-
15
8
interface mergeSortParams {
16
9
array : number [ ]
17
10
start : number
18
11
end : number
19
- animationHolder : animationHolder [ ]
12
+ animationStepsHolder : AnimationStep [ ]
20
13
}
21
14
22
15
interface mergeParams extends mergeSortParams {
23
16
mid : number
24
17
}
25
18
26
19
const merge = ( params : mergeParams ) => {
27
- let { array, start, mid, end, animationHolder : animations } = params
20
+ let { array, start, mid, end, animationStepsHolder } = params
28
21
let start2 = mid + 1
29
22
30
23
while ( start <= mid && start2 <= end ) {
31
- animations . push ( { compare : [ start , start2 ] } )
24
+ animationStepsHolder . push ( { compare : [ start , start2 ] } )
32
25
if ( array [ start ] < array [ start2 ] ) {
26
+ animationStepsHolder . push ( { correctOrder : [ start , start2 ] } )
33
27
start ++
34
28
} else {
35
- animations . push ( {
36
- idxToInsertTo : start ,
37
- moveFromIdx : start2 ,
38
- shift : start2 - start ,
39
- } )
29
+ animationStepsHolder . push ( { wrongOrder : [ start , start2 ] } )
30
+ animationStepsHolder . push ( { swap : [ start , start2 ] } )
40
31
const valueToMove = array [ start2 ]
41
32
let idxToShiftFrom = start2
42
33
@@ -54,50 +45,77 @@ const merge = (params: mergeParams) => {
54
45
}
55
46
56
47
const mergeSort = ( params : mergeSortParams ) => {
57
- const { array, start, end, animationHolder } = params
48
+ const { array, start, end, animationStepsHolder } = params
58
49
if ( start >= end ) return
59
50
60
51
const mid = Math . floor ( start + ( end - start ) / 2 )
61
- mergeSort ( { array, start, end : mid , animationHolder } )
62
- mergeSort ( { array, start : mid + 1 , end, animationHolder } )
63
- merge ( { array, start, mid, end, animationHolder } )
52
+ mergeSort ( {
53
+ array,
54
+ start,
55
+ end : mid ,
56
+ animationStepsHolder : animationStepsHolder ,
57
+ } )
58
+ mergeSort ( {
59
+ array,
60
+ start : mid + 1 ,
61
+ end,
62
+ animationStepsHolder : animationStepsHolder ,
63
+ } )
64
+ merge ( { array, start, mid, end, animationStepsHolder : animationStepsHolder } )
64
65
}
65
66
66
67
const animateMergeSort = ( params : AnimateFunctionParams ) => {
67
68
const { bars, palette, sortingSpeed, callback } = params
68
- const array = bars . map ( ( bar ) => getNumberValueFromElementHeight ( bar . style . height ) )
69
- // TODO: Add more key to the animation steps. E.g: correctOrder, wrongOrder, etc.
70
- const animations = [ ]
71
- mergeSort ( { array, start : 0 , end : array . length - 1 , animationHolder : animations } )
69
+ const array = bars . map ( ( bar ) =>
70
+ getNumberValueFromElementHeight ( bar . style . height )
71
+ )
72
+
73
+ const animationSteps : AnimationStep [ ] = [ ]
74
+ mergeSort ( {
75
+ array,
76
+ start : 0 ,
77
+ end : array . length - 1 ,
78
+ animationStepsHolder : animationSteps ,
79
+ } )
72
80
73
81
let previousOp : "compare" | "swap" = "compare"
74
- let previousActiveBars : HTMLElement [ ] = [ ]
75
- animations . forEach ( ( animation : animationHolder , idx ) => {
82
+ let previousActiveBars : HTMLElement [ ]
83
+ animationSteps . forEach ( ( animation , idx ) => {
76
84
setTimeout ( ( ) => {
77
- if ( idx > 0 && previousOp === "compare" ) {
78
- setTimeout ( ( ) => {
79
- const [ idx1 , idx2 ] = animations [ idx - 1 ] . compare
80
- changeBarsColor ( [ bars [ idx1 ] , bars [ idx2 ] ] , palette . idle )
81
- } , 5 )
85
+ if ( idx > 0 ) {
86
+ changeBarsColor ( previousActiveBars , palette . idle )
82
87
}
83
88
84
89
if ( animation . compare ) {
85
90
previousOp = "compare"
86
- const [ idx1 , idx2 ] = animation . compare
87
- const barsToOperate = [ bars [ idx1 ] , bars [ idx2 ] ]
91
+ const barsToOperate = animation . compare . map ( ( idx ) => bars [ idx ] )
88
92
changeBarsColor ( barsToOperate , palette . compare )
89
93
previousActiveBars = barsToOperate
90
- } else {
91
- const { idxToInsertTo, moveFromIdx } = animation
92
- previousOp = "swap"
93
- const barToMoveHeight = bars [ moveFromIdx ] . style . height
94
- for ( let x = moveFromIdx ; x > idxToInsertTo ; x -- ) {
95
- bars [ x ] . style . height = bars [ x - 1 ] . style . height
94
+ } else if ( animation . wrongOrder ) {
95
+ const barsToOperate = animation . wrongOrder . map ( ( idx ) => bars [ idx ] )
96
+ changeBarsColor ( barsToOperate , palette . wrongOrder )
97
+ previousActiveBars = barsToOperate
98
+ } else if ( animation . correctOrder ) {
99
+ const barsToOperate = animation . correctOrder . map ( ( idx ) => bars [ idx ] )
100
+ changeBarsColor ( barsToOperate , palette . correctOrder )
101
+ previousActiveBars = barsToOperate
102
+ } else if ( animation . swap ) {
103
+ const [ idx1 , idx2 ] = animation . swap
104
+ const movedBarHeight = bars [ idx2 ] . style . height
105
+ const barsToOperate = bars . slice ( idx1 , idx2 + 1 )
106
+
107
+ for ( let i = idx2 ; i > idx1 ; i -- ) {
108
+ bars [ i ] . style . backgroundColor = palette . correctOrder
109
+ bars [ i ] . style . height = bars [ i - 1 ] . style . height
96
110
}
97
- bars [ idxToInsertTo ] . style . height = barToMoveHeight
111
+
112
+ bars [ idx1 ] . style . backgroundColor = palette . swap
113
+ bars [ idx1 ] . style . height = movedBarHeight
114
+
115
+ previousActiveBars = barsToOperate
98
116
}
99
117
100
- if ( idx === animations . length - 1 && callback ) {
118
+ if ( idx === animationSteps . length - 1 && callback ) {
101
119
changeBarsColor ( previousActiveBars , palette . idle )
102
120
callback ( )
103
121
postSortAnimation ( bars , palette . correctOrder )
0 commit comments