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

本文主要是介绍前端三件套配合MarsCode实现钉钉官网动画 # 豆包MarsCode,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

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

@豆包MarsCode

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

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

如何固定动画区域

在这里插入图片描述

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

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

创建项目

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

在这里插入图片描述

在这里插入图片描述

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

MarsCode 设置样式

使用 MarsCode 设置样式!

MarsCode 优点1

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

在这里插入图片描述

在这里插入图片描述

MarsCode 缺点

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

在这里插入图片描述

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 只是辅助,重要的还是自己的能力过关!

这篇关于前端三件套配合MarsCode实现钉钉官网动画 # 豆包MarsCode的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1131058

相关文章

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

部署Vue项目到服务器后404错误的原因及解决方案

《部署Vue项目到服务器后404错误的原因及解决方案》文章介绍了Vue项目部署步骤以及404错误的解决方案,部署步骤包括构建项目、上传文件、配置Web服务器、重启Nginx和访问域名,404错误通常是... 目录一、vue项目部署步骤二、404错误原因及解决方案错误场景原因分析解决方案一、Vue项目部署步骤

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

如何通过Python实现一个消息队列

《如何通过Python实现一个消息队列》这篇文章主要为大家详细介绍了如何通过Python实现一个简单的消息队列,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录如何通过 python 实现消息队列如何把 http 请求放在队列中执行1. 使用 queue.Queue 和 reque

Python如何实现PDF隐私信息检测

《Python如何实现PDF隐私信息检测》随着越来越多的个人信息以电子形式存储和传输,确保这些信息的安全至关重要,本文将介绍如何使用Python检测PDF文件中的隐私信息,需要的可以参考下... 目录项目背景技术栈代码解析功能说明运行结php果在当今,数据隐私保护变得尤为重要。随着越来越多的个人信息以电子形

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景