Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
61 lines
2.5 KiB
Plaintext
61 lines
2.5 KiB
Plaintext
import { clamp } from '../../../../utils/clamp.mjs';
|
|
import { interpolate } from '../../../../utils/interpolate.mjs';
|
|
import { defaultOffset } from '../../../../utils/offsets/default.mjs';
|
|
import { calcInset } from './inset.mjs';
|
|
import { resolveOffset } from './offset.mjs';
|
|
import { ScrollOffset } from './presets.mjs';
|
|
|
|
const point = { x: 0, y: 0 };
|
|
function getTargetSize(target) {
|
|
return "getBBox" in target && target.tagName !== "svg"
|
|
? target.getBBox()
|
|
: { width: target.clientWidth, height: target.clientHeight };
|
|
}
|
|
function resolveOffsets(container, info, options) {
|
|
const { offset: offsetDefinition = ScrollOffset.All } = options;
|
|
const { target = container, axis = "y" } = options;
|
|
const lengthLabel = axis === "y" ? "height" : "width";
|
|
const inset = target !== container ? calcInset(target, container) : point;
|
|
/**
|
|
* Measure the target and container. If they're the same thing then we
|
|
* use the container's scrollWidth/Height as the target, from there
|
|
* all other calculations can remain the same.
|
|
*/
|
|
const targetSize = target === container
|
|
? { width: container.scrollWidth, height: container.scrollHeight }
|
|
: getTargetSize(target);
|
|
const containerSize = {
|
|
width: container.clientWidth,
|
|
height: container.clientHeight,
|
|
};
|
|
/**
|
|
* Reset the length of the resolved offset array rather than creating a new one.
|
|
* TODO: More reusable data structures for targetSize/containerSize would also be good.
|
|
*/
|
|
info[axis].offset.length = 0;
|
|
/**
|
|
* Populate the offset array by resolving the user's offset definition into
|
|
* a list of pixel scroll offets.
|
|
*/
|
|
let hasChanged = !info[axis].interpolate;
|
|
const numOffsets = offsetDefinition.length;
|
|
for (let i = 0; i < numOffsets; i++) {
|
|
const offset = resolveOffset(offsetDefinition[i], containerSize[lengthLabel], targetSize[lengthLabel], inset[axis]);
|
|
if (!hasChanged && offset !== info[axis].interpolatorOffsets[i]) {
|
|
hasChanged = true;
|
|
}
|
|
info[axis].offset[i] = offset;
|
|
}
|
|
/**
|
|
* If the pixel scroll offsets have changed, create a new interpolator function
|
|
* to map scroll value into a progress.
|
|
*/
|
|
if (hasChanged) {
|
|
info[axis].interpolate = interpolate(info[axis].offset, defaultOffset(offsetDefinition), { clamp: false });
|
|
info[axis].interpolatorOffsets = [...info[axis].offset];
|
|
}
|
|
info[axis].progress = clamp(0, 1, info[axis].interpolate(info[axis].current));
|
|
}
|
|
|
|
export { resolveOffsets };
|