Lomiri
carousel.js
1 /*
2  * Copyright (C) 2013 Canonical Ltd.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 3.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  */
16 
17 .pragma library
18 
19 /*! get the element which is selected accordingly to x, the hero of the view
20  @param x contentX of the ListView
21  @param tileWidth width of a single tile
22  @param gapToMiddlePhase gap in pixels between beginning and middle phase
23  @param gapToEndPhase gap in pixels between middle and end phase
24  @param kGapEnd
25  @param kMiddleIndex
26  @param kXBeginningEnd
27 */
28 function getContinuousIndex(x, tileWidth, gapToMiddlePhase, gapToEndPhase, kGapEnd, kMiddleIndex, kXBeginningEnd) {
29  if (x < gapToMiddlePhase) {
30  // beginning
31  return x * kXBeginningEnd
32  } else if (x > gapToEndPhase) {
33  // end
34  return x * kXBeginningEnd + kGapEnd
35  }
36 
37  // middle
38  return x / tileWidth + kMiddleIndex
39 }
40 
41 /*! obtain x position relative to an index, essentially an inverse of getContinuousIndex()
42  @param index index of the item to calcualte the proper X value for
43  @param viewWidth visible width of the view
44  @param contentWidth width off all items in the view
45  @param tileWidth width of one item
46  @param gapToMiddlePhase
47  @param gapToEndPhase
48  @param drawBuffer width of the drawBuffer
49 */
50 function getXFromContinuousIndex(index, viewWidth, contentWidth, tileWidth, gapToMiddlePhase, gapToEndPhase, drawBuffer) {
51  var middleX = (index + 0.5) * tileWidth - viewWidth / 2
52 
53  if (middleX < gapToMiddlePhase) {
54  // inverse of 'middleIndex - kGap' of getContinuousIndex()
55  return index /
56  ((1 / tileWidth) +
57  (viewWidth / (2 * tileWidth * gapToMiddlePhase)) -
58  1 / (2 * gapToMiddlePhase))
59  - drawBuffer
60  } else if (middleX > gapToEndPhase) {
61  // inverse of 'middleIndex + kGap' of getContinuousIndex()
62  return (index +
63  1 -
64  viewWidth / tileWidth +
65  (contentWidth * viewWidth - viewWidth * viewWidth) / (2 * tileWidth * gapToMiddlePhase) +
66  (viewWidth - contentWidth) / (2 * gapToMiddlePhase)) /
67  (1 / tileWidth +
68  viewWidth / (2 * tileWidth * gapToMiddlePhase) -
69  1 / (2 * gapToMiddlePhase))
70  - drawBuffer
71  }
72 
73  // inverse of 'middleIndex' of getContinuousIndex()
74  return middleX - drawBuffer
75 }
76 
77 /*! get translation of the whole view, adds gaps on sides
78  @param x contentX of the ListView
79  @param gapToMiddlePhase
80  @param gapToEndPhase
81  @param translationXViewFactor
82 */
83 function getViewTranslation(x, tileWidth, gapToMiddlePhase, gapToEndPhase, translationXViewFactor) {
84  if (x < gapToMiddlePhase) {
85  // beginning
86  return (gapToMiddlePhase - x) * translationXViewFactor
87  } else if (x > gapToEndPhase) {
88  // end
89  return (gapToEndPhase - x) * translationXViewFactor
90  }
91 
92  // middle
93  return 0
94 }
95 
96 /*! item scale
97  @param distance is the difference of the item's index to the continuousIndex
98  @param continuousIndex the current index in real number
99  @param numberOfItems the total number of items in the model
100  @param scaleFactor if bigger than 1, the scaling is done slower (more distance needed)
101 */
102 function getItemScale(distance, continuousIndex, numberOfItems, scaleFactor) {
103  var distanceAbs = Math.abs(distance)
104  var distanceToBounds = Math.min(continuousIndex, numberOfItems - continuousIndex)
105  var k = Math.max(200 + 100 * (-distanceToBounds / (3 * scaleFactor)), 50)
106  return Math.max(0.01, 1 - Math.pow(distanceAbs, 2.5) / (k * scaleFactor))
107 }
108 
109 /*! item translation
110  @param index index of the current item
111  @param selectedIndex index of the selected item
112  @param distance controls the direction wich is left/negative and right/positive
113  @param scale is the current scale factor of the item
114  @param maxScale the maximum scale factor (the one used when the index is on that item
115  @param maxTranslation the maximum translation length in pixel
116 */
117 function getItemTranslation(index, selectedIndex, distance, scale, maxScale, maxTranslation) {
118  if (index === selectedIndex) return 0
119  var sign = distance > 0 ? 1 : -1
120  return sign * (maxScale - scale) * maxTranslation
121 }