话不多说先直接上源码
//以下代码使用vue3框架setup组合式开发
<template>
<div class="home" ref="homeScroll" @scroll="getScroll">
<div class="imac">
<h2 ref="h2element">only 11.5mm. Now that's thin.</h2>
<div class="images">
<img
src="https://www.apple.com/105/media/us/imac-24/2021/5e004d75-3ad6-4bb9-ab59-41f891fc52f0/anim/design-hero/large/flow/flow_startframe.jpg"
alt
/>
</div>
</div>
</div>
</template>
<script>
import { ref, onMounted } from "vue";
export default {
setup() {
//h2节点
let h2element = ref(null)
// 滑动框节点
let homeScroll = ref(null)
// 测试是否触发IntersectionObserver回调
let isPinned = ref(false)
// 获取滚动时候的缩放参数
let returnscrolled = ref(1)
//IntersectionObserver用来监测指定节点的显示属性
let observer = new IntersectionObserver((e) => {
e.forEach(function (element) {
isPinned.value = (element.intersectionRatio < 1)
//intersectionRatio:显示比例即被遮挡的比例的反比
console.log(element.intersectionRatio);
element.target.classList.toggle('pinned', isPinned.value);
});
}, {
//指定根节点
root: null,
//指定何时触发 intersectionRatio=1 和第一次不等于1时候
threshold: [1]
})
const getScroll = () => {
//除去margintop的高度
let height = parseInt(getComputedStyle(h2element.value).getPropertyValue('height')) +
parseInt(getComputedStyle(h2element.value).getPropertyValue('margin-bottom'))
//margintop
let marginTop = parseInt(getComputedStyle(h2element.value).getPropertyValue('margin-top'))
// 实时滚动比例
let scrolled = (homeScroll.value.scrollTop - marginTop) / height
// h2element.value.style.setProperty('')
returnscrolled.value = 1-scrolled
}
onMounted(() => {
//绑定监测目标
observer.observe(h2element.value)
})
return {
h2element,
homeScroll,
getScroll,
returnscrolled
}
},
}
</script>
<style lang="less" scoped>
.home {
height: 100vh;
overflow: auto;
}
h2 {
font-weight: normal;
font-size: 72px;
width: 290px;
left: 50%;
position: sticky;
top: -1px;
margin: 100px 0;
padding: 0;
/*clamp()函数指定当变量小于0.15时候为0.15 大于1的时候为1*/
transform: scale( clamp(0.15, v-bind("returnscrolled"), 1) );
transform-origin: 0 0;
}
.images {
width: 100%;
// overflow: hidden;
img {
width: 100%;
position: relative;
display: block;
top: 50%;
left: 50%;
transform: translate(calc(-50% - 30px), 0);
}
}
.pinned {
/*color: red;*/
}
</style>
效果如下: