Skip to content

Commit

Permalink
feat: improved reactivity for data
Browse files Browse the repository at this point in the history
  • Loading branch information
Simon Milfred committed Jun 19, 2024
1 parent 60b1f44 commit 9092762
Showing 1 changed file with 64 additions and 12 deletions.
76 changes: 64 additions & 12 deletions components/LongRead/LongReadController.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
</template>

<script>
import { reactive } from 'vue';
import { reactive, watch } from 'vue';
/** Data */
export const data = reactive({
_controllers: new Set(),
_targets: {},
_activeTarget: null,
_latest: null,
get controllers() {
Expand All @@ -36,39 +37,89 @@ export const data = reactive({
},
get activeTarget() {
return this._activeTarget;
},
/* Trigger an update manually */
update() {
// Update relation to viewport
data.targets.forEach((target) => {
const targetEl = target?.id && document.getElementById(target.id);
if (targetEl) {
const targetRect = targetEl.getBoundingClientRect();
const isIntersecting =
(targetRect.top >= 0 &&
targetRect.top < window.innerHeight) ||
(targetRect.bottom >= 0 &&
targetRect.bottom < window.innerHeight) ||
(targetRect.top < 0 &&
targetRect.bottom >= window.innerHeight);
if (!isIntersecting) {
const { bottom = 0 } =
targetEl.getBoundingClientRect?.() || {};
target.visibility = 0;
target.aboveViewport = bottom < window.innerHeight / 2;
target.inViewport = false;
} else {
const percentage =
(targetRect.top < 0
? targetRect.bottom
: window.innerHeight - targetRect.top) /
(targetRect.height || 1);
target.visibility = Math.max(0, Math.min(1, percentage));
target.aboveViewport = false;
target.inViewport = true;
}
}
});
},
});
watch(
() => data.targets,
() => {
// Remove any lingering targets from other pages
if (this._latest && this.targets.indexOf(this._latest) === -1) {
this._latest = null;
if (data._latest && data.targets.indexOf(data._latest) === -1) {
data._latest = null;
}
let target = [...this.targets].reverse().reduce((acc, target) => {
let target = [...data.targets].reverse().reduce((acc, target) => {
return (target?.visibility ?? 0) >= (acc?.visibility ?? 0.00001) &&
target?.title?.length
? target
: acc;
}, null);
if (!target) {
// Find first target above the viewport
target = [...this.targets].reverse().find((target) => {
target = [...data.targets].reverse().find((target) => {
return target?.aboveViewport && target?.title?.length;
});
}
target = target ?? this._latest ?? this.targets[0];
this._latest = target;
return target;
target = target ?? data._latest ?? data.targets[0];
data._latest = target;
data._activeTarget = target;
},
});
{ immediate: true, deep: true }
);
/** Component */
export default {
name: 'LongReadController',
provide() {
return {
longReadController: { data, actions: {
scrollToTarget: this.scrollToTarget,
} },
longReadController: {
data,
actions: {
scrollToTarget: this.scrollToTarget,
update: this.update,
},
},
};
},
Expand Down Expand Up @@ -96,6 +147,7 @@ export default {
actions: {
scrollToTarget: this.scrollToTarget,
update: data.update,
},
};
},
Expand Down

0 comments on commit 9092762

Please sign in to comment.