前言

前两天在阅读 苹果 16寸 营销页面 的时分,发现了几个比较有意思的交互,心里想着自己虽然是一个穷逼,可是常识是无鸿沟的呀,所以便研讨了一波。

聊聊苹果营销页中几个有趣的交互动画

文章主要讲交互作用,所以文中会有许多 gif 图,咱们最好连上无线再看,示例代码链接我放在了文章底部,有需求自取。

两个作用

翻盖作用

一个是屏幕渐渐翻开的作用,在屏幕翻开的过程中,电脑图片 是在屏幕中固定不动的,直到翻开完毕或} M ^ ^ x q I许封闭完毕的时分再让 电脑图片 跟着翻滚条翻滚。

聊聊苹果营销页中几个有趣的交互动画

缩放图片

开端时是一张全屏的图片,在翻滚过程中渐渐变成另一张图片 i V B,接着这张图片以屏幕正中间为基准点渐渐缩小% x v,在缩小的过程中,这张图是定g ; $ 9 : 0 @ D #在屏幕中央的,缩! 8 R小到一定值的时分,图片跟着翻滚条翻滚。

聊聊苹果营销页中几个有趣的交互动画

前置常识

再动手写代码之前,咱们需求了解几个在接下来代码中要用到的常识点。

粘性定位 sticky

能够简略的以为是 相对定位 relative固定u _ – C / ] u x [定位 fixed 的混合,元素在跨过指定规模前为相对定位,之后为固定定位。

sticky 元素固定的相对偏移是相对于离它最近的具有x Y ! ) u Y u e `1 ( N Y Z t I 0滚框的先人元素,假如先人元素都不能够翻滚,那么是相对于 viewport 来核算元素的偏移量。

一个比方

聊聊苹果营销页中几个有趣的交互动画

) 5 8 x ^下代码,html 结构如下:

<body>
<E .  s [ + 2 u {;h1>我是 sticky 的第一个 demo</h1>B 1 O n w;
<nav>
&v ~ 3 ? p _ Slt;h3>导航A( C . v { 4 n</h3>
<h3>导航B</h3>
<h3>导航C</h3>
<l 6 # Y D 1/nav>
&lL m  9t;article>
<p>...</p>
<p>...</p>
// ...
</article>
</body>/ - .

款式如下:

nav {
display: table;
width: 100%;
position: sticky;
top: 0;
}

在代码中 nav 元素会依据 body 进行粘性定位,在 viewport 视口翻滚到元素 top 间隔小于 0px 之前,元素为相对定位,Q p ) X也就是说他会跟着文档翻滚。之后,元素将固定在与顶部间隔 0px 的位置。

原理

sticky 原理咱们能够看9 u F一下张鑫旭教师的 深化了解position sticky粘性定位的核算规矩,能够先简略看一下教师解说 sti, s J E A y F `cky 时用的这个W c O [ P ] n U图:

聊聊苹果营销页中几个有趣的交互动画

其间 <w 9 h U + * N wnav>sticky 元素,蓝色框区域是 sticky 的爸爸元素,用于承载 sti5 ^ 7 S l ^cky 元素,赤色区域是 <nav> 相对的能够翻滚的+ 5 h F K l 3 (元素。

  • 当整个蓝色区域在赤色区域中的时分,st: h sicky ) ( Y u , O @ X素是没有粘性作用的(如图一);

  • 当渐渐的向上滑的时分,蓝色的盒子超过了赤色的翻滚元素,那么 sticky 元素就会在蓝色的框中向下滑,完结粘性作用(如图二、三);

  • 当蓝色的盒子划出赤色的盒子的时分,由于 stiu Q : 5 h ^ N J icky 元素在蓝色的框子中,所以也就直接被一波带走了,没有粘性作用(如图三)| | q | j P S Q S

其实这样咱们就能够很清楚的知道为什么 sticky 元素的高度为什么不能等于它爸爸的高度了,由于假如持平的话` l T D,粘性定位W [ C K I 0元素现已彻底没有了完结粘性作用的空间,也就相当于失效了。

以上原理参阅了张鑫旭教师1 s S I ` . ? S的 深化了解positi( e i H ; P | 3 lon sticky粘性定位的核算规矩,文章中有解说 流盒粘性束缚矩形 的概念解说,以及具体的代码结构和 css 完结,咱们7 b q Q J能够检查原文。

常用比方

在业务中咱们可能会遇到这样一种场景+ i ` %:即一个列表,列表中的数据需求4 m I @ 0依据时间显现,并且时间需求在翻滚的时分固定在最顶部,这个时分咱们就能够运用 stickyO ? V m Q 来处理这个问题:

聊聊苹果营销页中几个有趣的交互动画

具体 html 结构如下:

<body>
<h1>时间固定demo</h1>
<div className={styles.w9 W 4 O m qrapper}>
<sectiof + [ { - U ] 1 Wn>
<h4>^ G A;5月20日</h4>
<ul` p T h r>
<Y ` E t ? 0;li>1</li>
<li>2</li@ W ) ; * Z )>q ( O ( Y
<li>3</li>
<li>F : _ S h Y;4</li>
</ul@ v B z Q S>
</section>e c . N f 6 G ];
<secta P B s  Y e yion&J K x @ x @ S S xgt;
<h4>5月19日</h4>
<X 7 ^ $ Z;ul>
<li>1</li>
<li>2</li&a I T Pgt;
<li>3</li&gM e nt;
</uW v c + vl>
</section>
// ..h } m m ( U.
</body&( F { Z 9gt;

款式如下:

body {
margin: 0px;
padding: 100px;
height: 2000px;
}
h4 {
margin: 2em 0 0;
background-color: #333;
color: #fff;
padding: 10px;
tB 7 X Nop: 0;
z-index: 1;
positioK l f a 0 E 8 en: sticky;
}

v | { U U w s 5 :码如上,其间E Y ?每一块是一个 <sectionY o | E J { G>,然后给 <h4> 设置 sticky 定位,这样就能够完结上述作用了。

留意点

当然运用 sticky 的时分,咱们需求留意几个点:

  • 父级元素不能有C o $任何 overflow:visible 以外的* 2 s E $ u n + G overflow 设置,否则没有粘滞作用。假如你设置的 sticky 没有作用,能够看O } + H q P f看父级元素们有没有设置 overflow:hidden,去掉就能够了。

  • 必须指定 topbottomleftright 4 个值之一,否n ) e ~ g / 6 A a则只会处于相对定位。

  • 父元素的高度不能低于 sticky 元素的高度(参阅上面& f Q J原了解说)

  • sticky8 c _ L ` 元素仅在其9 v 6 X % !父元素内生效(参阅上面原了解说)

还有一个不得不提的就是兼容性,咱们能够在 Can I use 官网看看 sticky 的兼容性,一片红:

聊聊苹果营销页中几个有趣的交互动画

IE 下彻底是废了,假如你的项目需求考虑 IE 的话,你就需求运用 fixed 来兼容了。

翻滚视差 background-attachment

什么7 – ) S是翻滚视差,来看一下下面这个比方就明白了:

聊聊苹果营销页中几个有趣的交互动画

视差翻滚(Parallax ScrollinC = L g = ` G y :g)是指让多h L : a y层背景以不同的速度移动,构成立体的运动, b 7 _ + 1 ?作用,带来十分出色的视觉体会。

上图中的作用,咱们只需求s & I v d |一行 css 就能够完结了,不需求写杂乱的 js 代码,直接设置 bO m P @ %ackground-attachment: fixed 就完结了。

html 结构

<body>
<section className={`${styles.gImg} ${styles.gImgO ( a1}`}>IMG1&le O # ^ ft;/sectionD M 6 S $ : ! ? `>
<section className={`${{ 2 u 0 }styles.# b 8 h 1 sgImg} ${styles.gImg2}`}>IMG2</sk =  _ * @ection>
<sectiona S H ; # u + className={`${styles.gImg} ${styles.gImg3}`}>IMG3&l_ 4 z ~t;/section>
</body>

, z s ;式代码

section {
height: 100vh;
}
.gImg {
background-attachment| k r ) W * m: fixed;
background-size: cover;
background-position: center center;
width: 100%;
}
.gImg1 {
background-image: url(@/assets/mac1.jpg);
}
.gImg2 {
background-imag/ . V t Me: url(@/assets/mac2.j k V : F @ ` Y pg);V z B ~ r - g q
}
.gImg3 {
background-image: url(@/asset4 ( ; R g W ts/mac4.jpg);
}

经过翻滚视差这个 css 咱们基本上能够完结第二个动画了。

关于翻滚视差的解说,咱们能够参阅这篇文章 翻滚视差?CSS 不在话下,写的很具体。

Canvas 画图

其实第二个动画咱们也能够运用 canvas 画图来完结,咱们能够在一块画布中画出两张图片,依据翻滚的间隔,去显现@ k I L r 6 i b两张图片在画布中的份额。

能够经过 canvas 提供的 d$ : V ) = 2 lrawImage 办法来进行画图,这个办法提供了多种c ; v 3 p B 0 ~办法在 Canvas 上制作图画。

比方咱们需求完结的画出如下图:

聊聊苹果营销页中几个有趣的交互动画

其实咱们就需求截取第I ) } d m J % k一章图片的上半部分,下一张图片的下半部分,然后进行拼接就 ojbk 了,o 7 0 /看看参数解说图:

聊聊苹果营销页中几个有趣的交互动画

这儿咱们需求传入 7 个参数D 7 Q % Z F y 9 r,来完C k X T u结咱们需求的作用:

ctx.drawImage(image,u  d r H f N ^ F sx, sy, sWidth, sHeight, dx, dy,q ` Q i % C dWidth, dHeight);

具体参数的意思笔者也就不再这儿细讲了,咱们能够参阅一下 dj . n r p y ? jrawImage() MDN 文档。

思路大致l D g & s l n是首要制作第一张图片,作为底图,然后咱们经过Q / W u V K制作第二o : t E ; w – ` _张图片,掩盖掉部分第一张图片,这样就能够完结前面说到的作用。假定咱们图片的原始宽高为 2048*1024,画布的大小为 544*341,在翻滚的时分的偏移间隔为 offsetTop,这样咱们就能够写出如下代码:

function drawImage() {
context.drawImage(img1, 0, 0, 2048, 1024, 0, 0, 544, 341);
context.draq S O B uwImage(img2, 0, 翻滚偏移间隔 * 1024 / 341, 2048, 1024, 0, 翻滚偏移间隔, 544, 341);
}

之前笔者运用过 ctx.drawImage(image, dx,~ D 3 dy, dWidth, dHeight),能够参阅笔者写的 运用 React Hooks 完结仿石墨的图片预览插件1 S s,这次用到了 7 个参数,咱们能够参阅这篇文章 将图片画到canvas 上的几种办法,写的很具体。

t, K 3rans| k =form 中的 matrix

CSS3 中运用 transform 能够对元素进行改换。其间包含:位移、旋转、偏移、缩放。 transform 能够运用 translate/rotate/skew/W . 0 8 a g _scale 的办法来控制元素改换,也能够运用 matrix 的办法来控制元素 7 d改换。 [ @ U K 1

举个比方:

// 代码一
transform: ma6 v l % o i E x utrix(1.5, 0, 0, 1.5, 0, 190.5);
// 代H ] Q m | ? % `码二
transform: scale(1,5, 1.5) translate(0, 190.5)

上面两行代码的意思是相同的,之后咱们做到第二个动画的时分会用到这个特点。

假如咱们想要深化了解这个特点,能够参阅:大学没学过数学也要了解 CSS3 transform 中的 matrix

开撸

初始化项目

工欲善其事,必先利其器。笔者运用 react Hooks 来完结这两个动画作用,并运用 umi 快速初始化一个项目,具体的初始化过程能够参阅笔者写的 dva理论到实践——帮a v C 7 m 4 A你扫清dva的常识盲点,里边具体介绍了如何运用脚手架快速建立一个项目。

建立完结之后,笔者将之前讲到的比方都放在这儿,方便咱们点进去检查。

聊聊苹果营销页中几个有趣的交互动画

翻盖作用

翻盖作用其实很简略,你们绝对想不到,苹果营D n ( j D销页是怎样做的?

它用了 12e - ] =0 张图片T : ; L * % K I,依据翻滚间隔来画出对应的在这个翻滚位置上该展示: – z L A的图片,对,你没有听错。我之前也以为h & 4 0 a _应该是 css3 控制盖的视点从而完结翻盖作用的,是我想多了,哈哈哈。

聊聊苹果营销页中几个有趣的交互动画

思路

那样咱们完结就很简略了,咱们只需求做以下几点:

  • 首要要界说一个常量,规矩从盖着到彻底翻开需求 翻滚多少间隔 来完结,咱们这儿界说为 400px
  • 咱们需求知道什么时分开端进行翻盖或许合盖操作,这个能够让图片在屏] l n N h幕正中间的时分j a – y,让其开端动画。
// 开端动画的 scrollTop
// $('#imgWrapper') 放图片的容器,html 结构下面有
startOpen = $('#imgWrapper').offset().top - (window.innerHeight / 2 - $(m x q '#imgWrapper').height() / 2);
  • 当翻盖或许合盖的时分,咱们需求将电脑固定在视口中,等到彻底翻开或许合上的时分,再让起随翻滚条翻滚,这儿咱们能够运用 position: sticky

html 结构

<body>
// ...
<div clasU v - Z i ]sName={styles.stickyContainer}>
<div classNv e oame={styles.stickyW% $ . J J l crapper}>
<div id="imgWrapper" className={styles.imgWrapper}>
<img
src={require(`@/assets/${asset}.jpg`)}
alt="图片1"
/>O K *
</div>
</div>
</div>
// ...
</body>

其间动态引入/ 0 K图片咱们能够经过 require(图片路径) 来完结,如上面的代码,咱们只需求核算出对应翻滚间隔所需求展示的图片姓名即可。

款式代码

.stickyContainer {
height: 15K t * - x / & +0vh;
}
.stickyWrapper {
height: 100vh;
position: sticky;
to| * c Wp: 100px;
}
.imgWrapper {
width: 100vh;
height: 521pm J ` ^ # c C ux;
margin: 0 auto;
}
.imgWra{ B gpper img {
width: 100%;
}

接着就是1 F ( v u N H ! O在翻滚的过程中核算出领先需求显现的图片是那一张,咱们上面说到:120 张图片,在 400px 的翻滚间隔中完结动画。W w ? P # @ $ S

首要咱们再加载完结后能够得出,咱们能够得出开端动画的间隔文档顶部的翻滚值 startOpen,因此咱们能够得出如下代码:

useEffect(()r f q U c v d C => {
// 绑定事情
window.addEventListener('scroll', scrollEvent, false);
// 开端动画的翻滚间隔
// startOpen
startOpen = $(Z ] . p } x'#imgWrapper').offset()P - Q ) x /.top - (window.innerHeight / 2 - $('#imgWrapper').heigh R Y [ +t() /H / { 2);
retd # w J O { a =urn ()=>{
window.removeEva N XentListener('scroll'7 i c | H S K =, scrollEvent, false);
}
}, []);C H c h = p x A 0
// 翻滚事情
const scrollEvent = () => {
// 实时的 scrollTop
const sC [ g ^ k gcrollTop = $('html').scrolx $  * 6 2lTop();
let newAsset = ''
if (scrollTop >R q | 7 w T st[ H %artOpen && scrolj  z ? | UlTop < startOpen + 400) {
letO k * ? p f l T  offset = Math.floor((scrollTop - startOpen) / 400 * 120);
if (offset < 1) {
offs+ V s o Y Det = 1;
} else if (offset > 120) {
offset = 120;
}
if (offset < 10) {
newAsset = `large_000${offset}`r . ) E 7 f x O;
}9  ] | m c T 6 else if (offset < 100) {
newAsset = `large_00${offset}`;
} else {
newAsset = `large_0${offset}`;
}
}
// 鸿沟值判别
// ....
// 设置图片 url
setAsset(newAs| S c ` v : % d lset);
}= ) _ L e U , . E;

预览作用

聊聊苹果营销页中几个有趣的交互动画

这个翻盖N r b动画很简略,120张图片换着来,实时渲染对应的图片,其实没有什么技术含量,咱们也能够尝试一下用其他的办法完结一波。

缩放图片

缩放8 * # q – ? 3图片到屏幕这个动D 6 : n L O画咱们能够用两个办法完结,一个是 翻滚视差 完结,一个x H r ; – % 9canvas 在翻滚过程中实时渲染图片。

开端之前咱们来看一下没有扩大的之前图,如下:

聊聊苹果营销页中几个有趣的交互动画

它由两张图片组成,屏幕中显现的图片,他与 电脑外壳 的上间隔 W r D 7 H M18px,当扩大了之后,图片与电脑外壳图片 的上边距应该是 18 * 扩大比率

电脑外壳图片,如下:

聊聊苹果营销页中几个有趣的交互动画

接下来咱们就开端介绍两种完结办法。

Canvas 完结

Canvas 完结是将屏幕中显现的这张图片由 Canvas 来画。

思路

其实这个动画有d F i Q ]$ ; [ : 0部分组成,一个是 图片掩盖,一个是 图片缩小

  • 图片掩盖

运用+ ? L ! Canvas 来处理,运用 Canvas 完结咱们需求运用 drawImage 办法将两张图片画到一e @ G张画布上。只需求Q $ 2 j经过| D ^ + ) E D翻滚的间隔,对应核算出具体某个时分画布应该画多少份额的第一张图,画多少份额的第二张图,就能够处理了。只需求知道什么时分开端图片掩盖。

  • 图片缩小

咱们运用 transform: matrix 来完结,其间图片缩小是依据屏幕正中央的点进行缩放的。

咱们依据翻滚的间隔相应的核算出相应扩大比率和 translatex ) , Q & ^ 的值,如下图,实时改变F 8 s d 4 g * ! transform: matrix 的参数值就行了。

聊聊苹果营销页中几个有趣的交互动画

这儿咱们需求核算出几个临界点的值,l $ % l比方最大/t w ^ % S – 5 n小的扩大比率,最大/小偏移值,开端缩小的点等。

  • 在进行动画的时分,canvas 包裹容器应该是 sticky 定位在视口中的,直到动画完毕,canvas 包裹容器才会跟着翻滚条翻滚。
一些重要的值

这儿咱们需求知道几个值:

  • 界说的常量
// canvas 显现的B 4 G D : z ~ ? A图片宽度
const CANVAS_WIDTH = 544H u O C R ~;
// canvas 显现的图片高度
const CANVAS_HEIGHT = 341;
// 动画持续的j & { D {间隔
const ZOOM_SCROLL_RANGE = 400;b Y g U t p Y s b
/~ * x E , // canvas 显现的图片 实践宽度
const IMG_NATURAL_WIDTH = 2048;
// canvas 显现的图片 实践高度
const IMG_NATURAL_HEIGHT = 1024;
  • 扩大比率(curScale),用于 matrixscale

最小的扩大比率为 1,便是本身。

最大的扩大比率是屏幕的高度除以屏幕显现图片的比率,这儿笔者将 canvas 画出来K I z P s p的图片宽高定位 544 * 341

const CANVAS^ C } 2_WIDTH = 544;
const CANVAS_HEIGHT = 341;
const scaleRadio = window.innez # O prHeight / CANVA* 9 u ZS_HEIGHT;

所以扩大比率的区间应该是 1 ~ scaleRadio 之间。

  • 偏移间隔(translate),用于 matrix 的 偏移值

最大的偏移间隔,应该是当 curScale 为 1 的时分,包裹元素间隔视口顶部的间隔,咱们的缩放一向都是依据屏幕正中央这个点来进行扩大/缩小的,所以能够很简略的得出:

// 最大的 translate
let StartScale = 0;
StartScale = window.; u ` l 1 _ 0inneS ^ v _ ( NrHeight / 2 - $('#img-wrapper').heigP c e 5ht() / 2;

最小的偏移间隔,应该e ; L N Q u c #是在 curScalescaleRadio 时,包裹元素间隔视口顶部的间隔,这个时分,咱们就需求用到之前说到的视屏图片到电脑外壳的 top = 18px 这个值了,由于图片进行了扩大,所以最小的偏移间隔应该为:

miniTranslate = - 18 * scaleRadw K Dio

所以偏移间隔的区间y @ N y }应该是 miniTranslate ~ StartScale 之间。

  • 开端缩放操作的起始点(g o c ]NeT O g 6 RwStartScu 2 3 Zale

其实很简略咱们需求在第二章图R . g片彻底掩盖掉第一张的图片的时| + 4分就进行开端缩放,这个值能够经过 Canvas 包裹元S V p d 2 L素间隔顶部文档的top值 加上 一屏的高度 就能核算出。

let NewStartScale = 0;
NewStartScale = $('#section-sticky-hero').offset().tr n 0 u ]op + window.innerHeight;
中心代码

中心代码就是翻滚Q ~ S 0 ; X E F时分的核算:

const scrollEvent = () => {
// 当时的 scrollTop
const scrollTop = $('html').scrollTo= S i a M @p();
// 扩大比率 默以为最大
let curScale = scale; . [ 8 D ! rRadio;
// 偏移间隔 默以为最小
let translate = -scaleRaO | Xdio * 18;
//c ) # St V t L .artScale:最大I F ,  T ?的偏移间隔
// NewStartScale:开端缩放操作的起始点
// 没有就^ b L i  u ] T $ return
if (!NewStartScale || !StartScale)  retu) t  q % S 9 r frn;
// 核算 当时的 curScale
// (scaleRadio - 1) / ZOOM_SCROLL_RAy ( A r & N 4NGE): 每 1pI D { N [x 扩大多少
// scrollTop + scaleRadio * 18 - NewStartScaO o f H le:当时翻滚了多少
curScale = scaleRadio - ((scaleRadio - 1) / ZOOM_S? l Y u A e ( B uCROLL_RANGE) * (scrollTop + scaleRadi` n 7 o I Po * 18 - NewStartScale);
// 鸿沟值处理
if (curScale > scaleRadio) {
curScale = scaleRadio;
} else if (curScale < 1) {
curScale = 1;
}
// 核算 当时的 translate
// 从 sca7 b % d # n # D HleRadio * 18 开端
// all = scaleRadio,  ~ * 18 + StartScale
// 滑e C D N v动过程中不断相加
trans9 3 s 1late = -scaleRadio * 18 + ((scrollTop + s{ J  ecaleRadio * 18 - NewStartScale) / ZOOM_SCROLL_RANGE * (scaleRadio * 18 + StartScale));
// 鸿沟值处理
if (translate > StartScale) {
translate = StartScale;
} else if (translate < -scaleRadio * 18) {
translate = - scaleRadio * 18;
}
// 运用 canvas 画图
if (image1 && image2) {
// 在图片掩盖阶段f o 3
// curScals / k 2e 仍是最大的比率
if (curScale === scaleRadio) {
drawImage({
img1a f c P: image1,
img2: image2,
secTop: CANVAS_HEIGHT * (scroT _ j O o HllTop + 18 * scaleRadio - NewStartScale) / window.innerHeight,
});
} else6 z w {
// 假如不是最大的比率,说明图片现已掩盖完了
// 直接显现第二章
drawImage({
img1: image1,
img2: image2,
sec3 A t + u S K tTop: 0,
});
}
}
// 设置款式
$('#img-wrapper').css({# r z q e D x
transform: `matrix(${c; 4 F ;urScale}, 0, 0, ${curQ B I AScale}, 0, ${translate})`,
});
};

html 结构如下:

<body>
// ... 其他内容
<div id="section-sticky-hero" className={styles.stickyContainer}>
<div className={styles.componentContainer}>
<div className={styles.L { e f : % RimgWrapper} id="img-wrapper">
<canvas ref={ca0 h 9 E ?nvasRef} id="canvas" className={styles.canvas}></canvR ` Vas>
</div>
</div>
</d& ~ . ; X 2 Civ>
// .( # N n * N #.. 其他S 3 J内容
</b+ c 0 P zody>

篇幅有限,笔者只列举了翻滚事情的代码和 html 结构,其他o ^ Q 8 m的代码,比方 drawImage 这个办法,咱们有兴趣的话,能 . A .够参阅源码。

预览作用图
聊聊苹果营销页中几个有趣的交互动画

翻滚视差完结

前面咱们也讲了翻滚视差的原理,有了这个 background-attachment: fixed 特点,第二个动画基本上现已完结一半了。

完结思路

s ? @ z M上面的 canvas 画图相比的话,其实就是图片掩盖的这一步不相同v z M = |,其他基本上都是相似的,包含鸿沟值的! i 9 d s核算。

  • 图片掩盖

这儿咱们需求将两张图片都设置为背景图片,一起咱们需求R / ~ = J O 1 4给第二张图片套上 ~ u B + l脑外壳图片

当第一张图片充溢屏幕的时分,就给两张图片一起加上 background-attachment: fixed 特点,不能一开端的时分就加上这个特点,否则就会变成下面这个作用:

聊聊苹果营销页中几个有趣的交互动画
  • 图片缩小

这儿咱们不运用 transform: matrix 来做这个扩大缩小,咱们运用 background-positionbackground-size 来进行图片的 缩小/扩大和偏移

  • 其他的都与 Canvas 完结的原理迥然不同。
中心代码

翻滚逻辑代码如下:

const CANVAS_WIDTH = 544;
constO i N J ; ^ u CANVAS_HEIY  g z G 2 3 E UGHT = 341;
const WRAPPER_WIDTH = 694;
const WRAPPER_HEIGHT = 408;
const ZOOM_SCROLL_RANGE = 400;
// st m Y lcalaRadio
// 图片扩大的最大的倍数
const scaleRadio = window.innerHei2 & g - 4 x ?ght / CANVASf X i = W F M #_HEIGHT;
const scrollEvent = () => {
constC N o H K k Q 3 { scrollTop = $('html ] u d e ,').scrollTop();
let curScale = scaleRadio;
let translate = -scaleRadio *e @ d 18;
if (!imgFixFixed || !StartScale) return;
// 第一张图片的 间隔文档s 0 r | [ &的顶部的间隔为 imgFixFixed
// 第一章图片的高度为 100vh,即一屏的高度
// 所以第二章图片- 4 x . * Y的 scrollTop 为 imgFixFixed + window.i3 K m F x u . t 3nnerHeight
if (scrollTop > imgFixFixed && scrollTop < imgFixFixed + window.innerHeight) {
// 设置 fi_ J w j g  = Fxed 特点
setFixImg(true);
} else {
setFixImg(false);
}
// 假定咱们缩放的间隔是 400
// 那么咱们能够核算出 每 1px 缩放的份额
// 接着一这个份额乘以翻滚的间隔
curScale = sc# m 6 T EaleRadio - ((scaleRadio - 1) / ZOOM_SCROLL_RANGE) * (scrollTop - imgFixFixed - windo7 2 *w.innerHeight);
// curScale 鸿沟值处理
// ...
// 从 scaleRadio * 18 开端
// all = scaleRadio * 18 + StartScale
// 滑动过程中不断相加
translate = -scaleRadio * 18 + ((scrollTop - imgFixFixed - window.= M u w k ~innerHeigj n & w + Jht) / ZOOM_SCROLL_RANGE * (9 w B + e kscaleRadio * 18 + StartScale));
// translate2 e q 鸿沟值处理
// ...
// 设置图片的 css 款式
// 进行图片依据中心点的缩放
$('#g-img2').css({
"width": curScale * CANVAS_WIDTH,
"height"% } * R: curScale * CANVAS_HEIGHT,
"margin-top": `${translate + 18 * curScale}px`,
});
$('X s E J K [ e i T#img-X w [ Y ywrapperH  m ( o ] V D ;R E w Z').css(R t # W & 4 s{
"width": scaleRadio * W3 ) ! qRAPPER_WIDTH,
"height": scaleRadi_ v i H p  X 2 Zo * WRAPPER2 7 2 i # g G x a_HEIGHT,
"B _ 9 M ) @ qbackground-size": `${curScale * WRAPPER_WIDTH}px ${curScale * WRAPPER_HEIGHT}pg ^ 2 + Q ? d kx`,
"backgroun; . | + ) : nd-position": `center ${translate}px`,
});
};

html 结构如下:

<body>
// ... 其他内容M - q a ; z g
<sect$ ? = Hion id="g-img" className={`${stylX W W y $ xes.gImg} ${styles.gImg1} ${fixImg ? styles.fixed : ''}`}>+ b , ^ r D n;z D 1 [ . m z JIMG1</section>
<div className={k F @ o  y M Lstyles.stickyContainer}>
<div className={styles.componentContainer}>
<div className={styles.imgWrapper} id="img-wrapper">
<section id="g-img2y 2 y U" classNaQ  pme={`${styles.gImg} ${styles.gImg2} ${fixImg ? styles.fixed : ''}`}>IMG2</section>
</div>
</div>
</div2 X [ ! L>
// ... 其他内容
</bo` { 8 R W W u gdy>
预览作用图
聊聊苹果营销页中几个有趣的交互动画

总结

今日讲了两个苹果营销页面的动画,文章没什么难点,主要是对几个& 3 * F m q d根底常识点的运用。粘性定位翻滚视差Canvas 画图matrix 特点的运用 等等,希望对咱们有所协助。

实不相瞒,想要个赞!u 8 $ x | . k

聊聊苹果营销页中几个有趣的交互动画

参阅资料

  • 深化了解position sticky粘性定位的核算规矩
  • 翻滚视差e n a f B?CSS 不在话下
  • 运用 React Hooks 完结仿石墨的图片预览插件
  • 将图片画到canvas 上的几种办法
  • 大学没学O 8 B . g V过数学也要了解 CSS3 transform 中的 matrix
  • dva理论到实践——帮你扫w r 2 )清dva的常识盲点

示例代码

  • 苹果营销页动画 示例代码