前端三件套配合MarsCode实现钉钉官网动画 # 豆包MarsCode

devtools/2024/9/24 23:23:57/

文章目录

  • 如何固定动画区域
  • 创建项目
  • MarsCode 设置样式
  • js实现动画
    • 实现获取动画曲线的函数
    • 为什么实现这个函数?
    • 根据当前滚动位置,计算每一个元素不同的数值
      • 更新 dom 的 style
      • 更新 animationMap
      • getDomAnimation

@豆包MarsCode

要写出钉钉官网动画,首先第一步就是分析钉钉官网动画是怎么实现的!

在这里插入图片描述
滑动滚轮发现到了动画这里,界面是不会继续滚动的,而是等待动画执行完成后,才继续滚动!我们要实现的第一点就是:如何固定动画区域!只有搞定这个问题,下一个问题才是如何实现动画!

如何固定动画区域

在这里插入图片描述

这是一个解析图:灰色部分是网页内容比较长,蓝色部分是动画的执行区域,相对来说比较高(不然滚动条一滚动就被带走了),但是只有这两个是不行的,还需要红色这个粘性定位的内容,等内容滚动到红色区域时,会一直固定,等父元素(蓝色部分)滚动到最上面的时候,底部会将红色部分一起带走(保证了红色区域不管怎么滚动,有一段时间一直在可视区域内)!

不懂粘性定位可以异步:css Position(定位) [第八天]

创建项目

现在我们一步一步来,配合我们的 MarsCode 完成代码 !首先在vscode里准备好我们的前端三件套文件!

在这里插入图片描述

在这里插入图片描述

其中:body 是灰色部分,playground 是蓝色部分,红色部分是 animation_container,这里只是模仿钉钉这个动画,所以里面用的是小方格 list-item!

MarsCode__26">MarsCode 设置样式

使用 MarsCode 设置样式!

MarsCode_1_30">MarsCode 优点1

简单注释,MarsCode 生成的代码还是挺好用的

在这里插入图片描述

在这里插入图片描述

MarsCode__37">MarsCode 缺点

但是这种有多个需求的,MarsCode 就不能特别好的提示了

在这里插入图片描述

MarsCode_2_43">MarsCode 优点2

可以通过尝试换书写注释来生成正确的代码,但是比较难试!

通过菜鸟不断的尝试,MarsCode 居然真的自己写出来了:

在这里插入图片描述

效果如下:

在这里插入图片描述

然后我们自己优化一下:

/* 通配符取消margin、padding */
* {margin: 0;padding: 0;
}
body {height: 4000px;
}
/* 设置header占满屏幕,背景白色,文字黑色100px */
.header {height: 100vh;width: 100%;background-color: #fff;color: #000;font-size: 100px;text-align: center;line-height: 100vh;
}.playground {height: 2000px;width: 100%;background-color: #000;
}
/* 设置animation_container为粘性定位,并占满屏幕 */
.animation_container {position: sticky;top: 0;height: 100vh;width: 100%;
}/* 设置list在animation_container的中间,list-item排列成2行7列,均匀分布 */
.list {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);display: grid;grid-template-columns: repeat(7, 1fr);grid-template-rows: repeat(2, 1fr);grid-gap: 50px;
}/* 请设置list-item的宽高为100px,高宽比为1:1 */
.list-item {width: 100px;height: 100px;aspect-ratio: 1/1;border-radius: 5%;
}/* list-item有14个,请均匀分布在list中,且2行7列,颜色各不相同 */
.list-item:nth-child(1) {background-color: #f00;
}
.list-item:nth-child(2) {background-color: #0f0;
}
.list-item:nth-child(3) {background-color: #00f;
}
.list-item:nth-child(4) {background-color: #ff0;
}
.list-item:nth-child(5) {background-color: #0ff;
}
.list-item:nth-child(6) {background-color: #f0f;
}
.list-item:nth-child(7) {background-color: #fff;
}
.list-item:nth-child(8) {background-color: #f00;
}
.list-item:nth-child(9) {background-color: #0f0;
}
.list-item:nth-child(10) {background-color: #00f;
}
.list-item:nth-child(11) {background-color: #ff0;
}
.list-item:nth-child(12) {background-color: #0ff;
}
.list-item:nth-child(13) {background-color: #f0f;
}
.list-item:nth-child(14) {background-color: #fff;
}

结果

在这里插入图片描述

到此元素结构和样式搞定了!

js实现动画

现在到了实现动画的阶段了,首先要知道css动画是什么?css就是数值随时间的变化,但是这里没有时间,细心的同学就会发现虽然和时间无关,但是和滚动条相关了,所以要抽象成这个图

在这里插入图片描述

值随滚动条变化的图,而不是时间了!

实现获取动画曲线的函数

现在就是要写一个动画曲线函数,给我一个x,算出一个y,为了知道曲线函数需要传入scrollStart、scrollEnd、valueStart、valueEnd,然后剩下的就交给 MarsCode了!

写函数,然后输入几个参数后,MarsCode 自己就帮助我们生成好了!
在这里插入图片描述
自己想要完善一下(写的时候,MarsCode 也可以直接帮你,实在是牛)

在这里插入图片描述

function createAnimation(scrollStart, scrollEnd, valueStart, valueEnd) {return function (x) {if (x < scrollStart) return valueStart;if (x > scrollEnd) return valueEnd;return (valueStart +((valueEnd - valueStart) * (x - scrollStart)) / (scrollEnd - scrollStart));};
}

为什么实现这个函数?

就是用于备用,直接传值进函数,获得一个根据滚动条和属性直接的关系函数(MarsCode也直接帮你完成,但是暂时不需要)
在这里插入图片描述
这里解释一下

opacity 这个函数就是:滚动条从0 到 100,那么透明度就从 0 到 1的函数曲线!

当然这里的滚动值不是很对,这个就是后面我们按需求修改!

根据当前滚动位置,计算每一个元素不同的数值

既然是动态变化的值,那肯定是这样的数据结构

在这里插入图片描述

所以要建立映射关系,将对象给每一个 dom

// 为每一个元素映射一个动画
const animationMap = new Map();
const items = document.querySelectorAll(".list-item");
const playground = document.querySelector(".playground");
const list = document.querySelector(".list");

然后就是两件事:

  1. 更新 animationMap
  2. 更新 dom 的 style

所以写出这两个函数

// 更新动画隐射
function updateAnimationMap() {}// 将map结构用于元素
function updateStyle() {}

更新 dom 的 style

其中比较好写的就是 更新 dom 的 style

思路:获取整个界面的滚动距离,循环 Map 去获取上面的对象,再循环对象获取值并调用函数!

有了思路,MarsCode 会直接帮你写好(写两个for,自己就出来了)

// 将map结构用于元素
function updateStyle() {const scrollY = window.scrollY;for (const [element, animation] of animationMap) {for (const key in animation) {// 自己添加的注释// 调用每个dom对应的动画函数// 动画函数的参数是当前的scrollYelement.style.setProperty(key, animation[key](scrollY));}}
}

写完之后就调用,MarsCode 也会帮你完成

在这里插入图片描述

更新 animationMap

思路:循环dom节点,并设置Map

写一个for,MarsCode 直接就帮你写好了

在这里插入图片描述

只是这里没这么简单,设置的是那个数据结构的对象,所以我们只保留设置部分!

function getDomAnimation(dom) {}// 更新动画隐射
function updateAnimationMap() {for (const item of items) {animationMap.set(item, getDomAnimation(dom));}
}

getDomAnimation

返回的是一个对象

return {opacity,transform,
};

这里的 opacity,transform 又可以通过 createAnimation 来获取!然后发现 scrollStart,scrollEnd 所有的dom是一样的,所以直接当参数传入!

function getDomAnimation(scrollStart, scrollEnd, dom) {const opacity = createAnimation(scrollStart, scrollEnd, 0, 1);const transform = createAnimation(scrollStart, scrollEnd, 0, 100);return {opacity,transform,};
}// 更新动画隐射
function updateAnimationMap() {for (const item of items) {animationMap.set(item, getDomAnimation(scrollStart, scrollEnd, item));}
}

确定好什么时候滚动、以及什么时候滚动结束!

// 更新动画隐射
function updateAnimationMap() {const playgroundRect = playground.getBoundingClientRect();const scrollY = window.scrollY;const scrollStart = playgroundRect.top + scrollY;const scrollEnd = playgroundRect.bottom + scrollY - window.innerHeight;for (const item of items) {animationMap.set(item, getDomAnimation(scrollStart, scrollEnd, item));}
}

这个时候透明度的变化已经完成!

剩下的就是transform的一些属性,也可以按照 opacity 一样,不同的是这个 transformx\transformy ,需要计算

function getDomAnimation(scrollStart, scrollEnd, dom) {const opacity = createAnimation(scrollStart, scrollEnd, 0, 1);const scale = createAnimation(scrollStart, scrollEnd, 0.5, 1);const Xtransform = createAnimation(scrollStart, scrollEnd, ?, 0);const Ytransform = createAnimation(scrollStart, scrollEnd, ?, 0);const transform = (x) => {return `scale(${scale(x)}) translate(${Xtransform(x)}px, ${Ytransform(x)}px)`;};return {opacity,transform,};
}

都是从中间出来的,所以

function getDomAnimation(scrollStart, scrollEnd, dom) {const opacity = createAnimation(scrollStart, scrollEnd, 0, 1);const scale = createAnimation(scrollStart, scrollEnd, 0.5, 1);const { clientWidth, clientHeight, offsetTop, offsetLeft } = dom;console.log(clientWidth, clientHeight, offsetTop, offsetLeft);const listRect = list.getBoundingClientRect();const Xtransform = createAnimation(scrollStart,scrollEnd,listRect.width / 2 - clientWidth / 2 - offsetLeft,0);const Ytransform = createAnimation(scrollStart,scrollEnd,listRect.height / 2 - clientHeight / 2 - offsetTop,0);const transform = (x) => {return `translate(${Xtransform(x)}px, ${Ytransform(x)}px) scale(${scale(x)}) `;};return {opacity,transform,};
}

至此,效果基本实现,再就是动画需要延时,通过data-设置delay来实现

<div data-delay="0" class="list-item"></div>
<div data-delay="1" class="list-item"></div>
<div data-delay="2" class="list-item"></div>
<div data-delay="3" class="list-item"></div>
<div data-delay="2" class="list-item"></div>
<div data-delay="1" class="list-item"></div>
<div data-delay="0" class="list-item"></div>
<div data-delay="0" class="list-item"></div>
<div data-delay="1" class="list-item"></div>
<div data-delay="2" class="list-item"></div>
<div data-delay="3" class="list-item"></div>
<div data-delay="2" class="list-item"></div>
<div data-delay="1" class="list-item"></div>
<div data-delay="0" class="list-item"></div>
function getDomAnimation(scrollStart, scrollEnd, dom) {// 注意这个不要超过滚动距离,不然就会导致超过的动画瞬间完成scrollStart += dom.dataset.delay * 200;const opacity = createAnimation(scrollStart, scrollEnd, 0, 1);const scale = createAnimation(scrollStart, scrollEnd, 0.5, 1);const { clientWidth, clientHeight, offsetTop, offsetLeft } = dom;const listRect = list.getBoundingClientRect();const Xtransform = createAnimation(scrollStart,scrollEnd,listRect.width / 2 - clientWidth / 2 - offsetLeft,0);const Ytransform = createAnimation(scrollStart,scrollEnd,listRect.height / 2 - clientHeight / 2 - offsetTop,0);const transform = (x) => {return `translate(${Xtransform(x)}px, ${Ytransform(x)}px) scale(${scale(x)}) `;};return {opacity,transform,};
}

到此,钉钉官网动画基本上主要内容完成了,剩下的都是些图标什么的,还是比较简单的!

体验完 MarsCode ,感觉智能提示等都很不错,但是也有不足的地方,就是有些没有确定思路的地方,如果你不会,那么提示的大概率也是错误的!所以 AI 只是辅助,重要的还是自己的能力过关!


http://www.ppmy.cn/devtools/105481.html

相关文章

自然语言处理系列五十二》文本分类算法》BERT模型算法原理及文本分类

注&#xff1a;此文章内容均节选自充电了么创始人&#xff0c;CEO兼CTO陈敬雷老师的新书《自然语言处理原理与实战》&#xff08;人工智能科学与技术丛书&#xff09;【陈敬雷编著】【清华大学出版社】 文章目录 自然语言处理系列五十二文本分类算法》BERT模型算法原理及文本分…

DIFFUSION 系列笔记| Latent Diffusion Model、Stable Diffusion基础概念、数学原理、代码分析、案例展示

目录 Latent Diffusion Model LDM 主要思想 LDM使用示例 LDM Pipeline LDM 中的 UNET 准备时间步 time steps 预处理阶段 pre-process 下采样过程 down sampling 中间处理 mid processing 上采样 upsampling 后处理 post-process LDM Super Resolution Pipeline…

Docker续8:使用docker-compose部署nmt项目

[rootlocalhost ~]# tree -L 3 pes 文件目录结构 pes ├── docker-compose.yml ├── haproxy │ └── haproxy.cfg ├── java │ ├── Dockerfile │ ├── jdk │ │ ├── bin │ │ ├── conf │ │ ├── include │ │ ├── jm…

保姆级Maven安装、配置、版本查询教程(包含配置本地仓库、阿里云私服、环境变量)

文章目录 一、Maven安装1. 下载zip包2. 解压 zip包 二、配置1. 配置本地仓库2. 配置阿里云私服3. 配置环境变量 三、Maven验证 此教程摘选自我的笔记&#xff1a;黑马JavaWeb开发笔记11——Maven介绍、详细安装、环境配置步骤教程&#xff0c;想要了解Maven组成和作用可以移步此…

【赵渝强老师】大数据技术的理论基础

大数据平台所要解决的问题是数据的存储和数据的计算&#xff0c;其核心思想采用的是分布式集群的思想。另一方面&#xff0c;分布式集群的思想在Google的技术系统中得到了很好的应用。因此Google将其核心技术的思想以论文的形式公开发表出来&#xff0c;这就是"Google的三…

C#特性(Attribute)

特性(Attribute)是用于在运行时传递程序中各种元素(比如类,方法,结构,枚举,组件等)的行为信息的声明性标签.可以通过使用特性向程序添加声明性信息.一个声明性标签是通过放置在它所应用的元素前面的方括号[]来描述的. 特性(Attribute)用于添加元数据,如编译器指令和注释,描述,…

Android kotlin使用Netty网络框架实践(客户端、服务端)

开发工具&#xff1a;Android studio 语言:kotlin 设计原理&#xff1a;通讯协议&#xff1a;头类型长度数据尾&#xff0c;自定义编解码器&#xff0c;解析和包装发送数据流&#xff0c;以下贴出部分关键代码 说明&#xff1a;代码中封装了client和server端&#xff0c;可…

一些零碎的关于合约测试,ERC20调用的知识

文章目录 前言一、vm.startPrank&#xff08;user&#xff09;是什么&#xff1f;二、approve 方法场景设定步骤 1: 用户授权步骤 2: 合约使用授权步骤 3: 检查授权状态示例代码 ERC20 approve的源代码代码解释代码解释应用场景示例注意事项代码解释可能的重载版本 _approve事件…