(instance, scrollTop = getScrollTop())
| 228 | * @returns {Object} Calculated props and the element to apply styles to. |
| 229 | */ |
| 230 | const getProps = function(instance, scrollTop = getScrollTop()) { |
| 231 | |
| 232 | const data = instance.getData() |
| 233 | |
| 234 | // 100% in pixel |
| 235 | const total = data.to.value - data.from.value |
| 236 | |
| 237 | // Pixel scrolled |
| 238 | const current = scrollTop - data.from.value |
| 239 | |
| 240 | // Percent scrolled |
| 241 | const precisePercentage = current / (total / 100) |
| 242 | const normalizedPercentage = Math.min(Math.max(precisePercentage, 0), 100) |
| 243 | |
| 244 | // Get the element that should be used according to direct |
| 245 | const elem = mapDirectToProperty(data.direct, { |
| 246 | global: document.documentElement, |
| 247 | elem: data.elem, |
| 248 | direct: data.direct |
| 249 | }) |
| 250 | |
| 251 | // Generate an object with all new props |
| 252 | const props = Object.keys(data.props).reduce((acc, key) => { |
| 253 | |
| 254 | const prop = data.props[key] |
| 255 | |
| 256 | // Use the unit of from OR to. It's valid to animate from '0' to '100px' and |
| 257 | // '0' should be treated as 'px', too. Unit will be an empty string when no unit given. |
| 258 | const unit = prop.from.unit || prop.to.unit |
| 259 | |
| 260 | // The value that should be interpolated |
| 261 | const diff = prop.from.value - prop.to.value |
| 262 | |
| 263 | // All easing functions only remap a time value, and all have the same signature. |
| 264 | // Typically a value between 0 and 1, and it returns a new float that has been eased. |
| 265 | const time = prop.timing(normalizedPercentage / 100) |
| 266 | |
| 267 | const value = prop.from.value - diff * time |
| 268 | |
| 269 | // Round to avoid unprecise values. |
| 270 | // The precision of floating point computations is only as precise as the precision it uses. |
| 271 | // http://stackoverflow.com/questions/588004/is-floating-point-math-broken |
| 272 | const rounded = Math.round(value * 10000) / 10000 |
| 273 | |
| 274 | acc[key] = rounded + unit |
| 275 | |
| 276 | return acc |
| 277 | |
| 278 | }, {}) |
| 279 | |
| 280 | // Use precise percentage to check if the viewport is between from and to. |
| 281 | // Would always return true when using the normalized percentage. |
| 282 | const isInside = (precisePercentage >= 0 && precisePercentage <= 100) |
| 283 | const isOutside = (precisePercentage < 0 || precisePercentage > 100) |
| 284 | |
| 285 | // Execute callbacks |
| 286 | if (isInside === true) data.inside(instance, precisePercentage, props) |
| 287 | if (isOutside === true) data.outside(instance, precisePercentage, props) |
no test coverage detected