wenmo8 发布的文章

包英文单词是 package ,代表了一组特定功能的源码集合

管理包的应用软件,可以对包进行 下载安装 , 更新 , 删除 , 上传 等操作

借助包管理工具,可以快速开发项目,提升开发效率

前端常用的包管理工具有npm、yarn、cnpm

npm

node.js 在安装时会 自动安装 npm

npm基本使用
  1. 初始化


    npm init 命令的作用是将文件夹初始化为一个包, 交互式创建 package.json 文件

    package.json 是包的配置文件,每个包都必须要有 package.json


    npm init
    

    之后命令行根据提示交互式输入,全部运行完之后会创建package.json

    {
      "name": "test", // 包名字
      "version": "1.0.0", // 包版本
      "description": "test", // 包描述
      "main": "index.js", // 包入口文件
      "scripts": { // 脚本配置
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "author": "", // 作者
      "license": "ISC" // 开源证书
    }
    

    可以使用使用 npm init -y 或者 npm init --yes 极速创建package.json,包名字不能使用中文和大写,如果不写默认值则是文件夹名称

  2. 搜索工具包

    # 命令行
    npm search 关键字
    

    也可以去
    npm包网址
    搜索

  3. 下载安装包

    npm install 包名
    npm i 包名 #简写
    # 安装完之后,安装的包就是当前包的一个依赖包
    

    运行之后文件夹下会增加两个资源


    • node_modules 文件夹 存放下载的包
    • package-lock.json 包的锁文件 ,用来锁定包的版本
  4. require导入npm模块的基本流程

    const fs = require('fs')
    

    • 在当前文件夹下 node_modules 中寻找对应的同名的文件夹
    • 如果没有找到,在上级目录中下的 node_modules 中寻找同名的文件夹,直至找到磁盘根目录
开发依赖与生产依赖
  1. 生产依赖,包信息保存在 package.json 中 dependencies 属性

    npm --save 包名
    npm i -S 包名 #简写
    
  2. 开发依赖,包信息保存在 package.json 中 devDependencies 属性

    npm i --save dev 包名
    npm -D 包名 #简写
    
  3. 开发依赖 是只在开发阶段使用的依赖包,而 生产依赖 是开发阶段和最终上线运行阶段都用到

    的依赖包

npm全局安装

全局安装的命令不受工作目录位置影响,可以通过 npm root -g 可以查看全局安装包的位置

npm i 包名 # 局部安装,包只能在对应的工作目录里面使用
npm i -g 包名  # 全局安装
# nodemon的作用是自动重启Node应用程序
npm i -g nodemon


nodemon test.js # 代替 node 去运行js文件,代码发生改变时不需要手动重启服务,自动重启
安装所有依赖

该命令可以依据 package.json 和 package-lock.json 的依赖声明安装项目依赖

npm install
npm i # 简写
安装指定版本的包
npm i 包名@版本号
删除包
npm remove 包名
npm r 包名 #简写

npm r -g 包名 #全局删除
配置命令别名

通过配置命令别名可以更简单的执行命令,package.json中的scripts属性

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "server": "node ./index.js" // 配置命令别名
    
  },
# 执行该命令,就会去scripts找对应的Server,然后执行Server的代码 node运行代码
npm run server 

如果在scripts中配置了start属性,运行的时候不需要加run,直接npm start

npm start 是项目中常用的一个命令,一般用来启动项目

npm run 有自动向上级目录查找的特性,跟 require 函数也一样

cnpm

cnpm 是一个淘宝构建的 npmjs.com 的完整镜像,也称为淘宝镜像,网址https://npmmirror.com/

cnpm 服务部署在国内 阿里云服务器上 , 可以提高包的下载速度

官方也提供了一个全局工具包 cnpm ,操作命令与 npm 大体相同

安装cnpm
# 安装cnpm
npm install -g cnpm --registry=https://registry.npmmirror.com

cnpm初始化、增删改查等操作命令方式与npm一致

npm配置淘宝镜像
  1. 直接配置

    npm config set registry https://registry.npmmirror.com/
    
  2. 工具配置,使用nrm配置npm的镜像地址

    #安装nrm
    npm i -g nrm
    
    # 修改镜像
    nrm use taobao
    
    # 检查是否配置成功
    npm config list
    

yarn

yarn 是由 Facebook 在 2016 年推出的新的 Javascript 包管理工具,
官方网址

特点:

  • 速度:yarn 缓存了每个下载过的包,所以再次使用时无需重复下载。 同时利用并行下载以最大化资源利用率,因此安装速度更快

  • 安全:在执行代码之前,yarn 会通过算法校验每个安装包的完整性

  • 可靠:使用详细、简洁的锁文件格式和明确的安装算法,yarn 能够保证在不同系统上无差异的工作

  1. 安装yarn

    npm i -g yarn
    
  2. 初始化

yarn init
yar init -y # 快捷初始化
  1. 安装依赖

    yarn add 包名 # 生产依赖
    yarn add 包名 --dev # 开发依赖
    yarn global add 包名 #全局安装
    
  2. 删除依赖

    yarn remove 包名 # 局部删除
    yarn global remove 包名 # 全局删除
    
  3. 安装项目依赖

    yarn
    
  4. 配置方式一致,运行使用下面命令

    yarn 别名
    
  5. yarn配置淘宝镜像

    # 可以通过 yarn config list 查看 yarn 的配置项
    yarn config set registry https://registry.npmmirror.com/
    
  6. npm 的锁文件为 package-lock.json ,yarn 的锁文件为 yarn.lock

管理发布包

可以将自己开发的工具包发布到 npm 服务上,方便自己和其他开发者使用

  1. 创建文件夹,并创建文件 index.js, 在文件中声明函数,使用 module.exports 暴露
  2. npm 初始化工具包,package.json 填写包的信息 (包的名字是唯一的)
  3. 注册账号
    https://www.npmjs.com/signup
  4. 激活账号
  5. 修改为官方的官方镜像 (命令行中运行 nrm use npm )
  6. 命令行下 npm login 填写相关用户信息
  7. 命令行下 npm publish 提交包
  8. 修改包:修改 package.json 中的版本号,然后使用npm publish发布更新
  9. 可以使用npm unpublish --force 删除包

第三方登录是一种常见的身份验证机制,允许用户使用他们在其他平台(如社交媒体、电子邮件服务或开发平台)的账号来登录你的应用或网站,而不需要创建新的用户名和密码。这种方式不仅简化了用户的登录过程,还提高了用户体验和安全性。
第三方登录的主要特点
简化注册和登录:
用户无需创建新的账户,只需使用已有的第三方账户即可快速登录。
减少了用户忘记密码和管理多个账户的问题。
提高安全性:
用户的密码不会存储在你的系统中,减少了密码泄露的风险。
第三方平台通常有更严格的安全措施来保护用户数据。
增加用户信任:
用户对知名第三方平台的信任度较高,使用这些平台的账号登录可以增加用户对你的应用或网站的信任

第三方登录(Gitee)

  1. 注册应用
    在Gitee开发者平台注册一个应用,获取client_id和client_secret
    配置回调地址(callback url),这是用户授权后将被重定向到的地址

  2. 引导用户到授权页面
    构建一个授权请求url,引导用户到gitee的授权页面
    请求url格式如下

    https://gitee.com/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_type=code
    
    #client_id: 你的应用 ID。
    #redirect_uri: 回调地址,必须与应用配置中的回调地址一致。
    #response_type: 响应类型,通常是 code。
    #scope: 请求的权限范围,例如 user_info。
    
  3. 用户授权
    用户点击链接后会被重定向到gitee的授权页面
    用户选择是否授权你的应用访问其数据
    如果用户同意授权,gitee将会重定向回你配置的回调地址,并附带一个授权码(code)

  4. 获取访问令牌
    使用授权码(code)向gitee发送请求,获取访问令牌(access_token)
    请求url格式如下

    https://gitee.com/oauth/token?grant_type=authorization_code&code={code}&client_id={client_id}&redirect_uri={redirect_uri}&client_secret={client_secret}
    
  5. 使用访问令牌
    获取到access_token后,你可以使用它来访问gitee api 获取用户信息或其它资源
    例如获取用户信息url

    https://gitee.com/api/v5/user?access_token=7be75844c5439749f367c27cdbb96790
    

新建应用

gitee oauth

OAuth2 获取 AccessToken 认证步骤
** 授权码模式**
应用通过 浏览器 或 Webview 将用户引导到码云三方认证页面上( GET请求 )

https://gitee.com/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_type=code
``
用户对应用进行授权
注意: 如果之前已经授权过的需要跳过授权页面,需要在上面第一步的 URL 加上 scope 参数,且 scope 的值需要和用户上次授权的勾选的一致。如用户在上次授权了user_info、projects以及pull_requests。则步骤A 中 GET 请求应为:
```python
https://gitee.com/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_type=code&scope=user_info%20projects%20pull_requests

码云认证服务器通过回调地址{redirect_uri}将 用户授权码 传递给 应用服务器 或者直接在 Webview 中跳转到携带 用户授权码的回调地址上,Webview 直接获取code即可({redirect_uri}?code=abc&state=xyz)
应用服务器 或 Webview 使用 access_token API 向 码云认证服务器发送post请求传入 用户授权码 以及 回调地址( POST请求 )
注:请求过程建议将 client_secret 放在 Body 中传值,以保证数据安全。

https://gitee.com/oauth/token?grant_type=authorization_code&code={code}&client_id={client_id}&redirect_uri={redirect_uri}&client_secret={client_secret}

码云认证服务器返回 access_token
应用通过 access_token 访问 Open API 使用用户数据。
当 access_token 过期后(有效期为一天),你可以通过以下 refresh_token 方式重新获取 access_token( POST请求 )

https://gitee.com/oauth/token?grant_type=refresh_token&refresh_token={refresh_token}

注意:如果获取 access_token 返回 403,可能是没有设置User-Agent的原因。

工具类

third_login = {
    'gitee':'Gitee'
}
# 封装工厂类
class SimpleFactory:
    @staticmethod
    def product(name):
        return eval(third_login[name]+"()")

class Gitee:
    def __init__(self):
        self.redirect_uri = 'http://localhost:5000/gitee_back/'
        self.client_id = 'db129dabb36711081dc7273f1cb174d051a68eb4f8e041ecda32b7d2dcb60203'
        self.client_secret = '7d4d60b0c9b2d89e04ddf802a32a103768976143f4ede832645b7bc442cbf7ed'
        # token
        self.token_api = 'https://gitee.com/oauth/token'

       #获取三方登录链接
    def get_url(self):
        return f"https://gitee.com/oauth/authorize?client_id={self.client_id}&redirect_uri={self.redirect_uri}&response_type=code"


    # 获取用户信息
    def get_info(self, code):
        # 换token

        res = requests.post(
            f"https://gitee.com/oauth/token?grant_type=authorization_code&code={code}&client_id={self.client_id}&redirect_uri={self.redirect_uri}&client_secret={self.client_secret}")

        token = res.json()["access_token"]
        # 获取用户信息
        res = requests.get(f"https://gitee.com/api/v5/user?access_token={token}")
        name = res.json()["name"]

        avatar_url = res.json()["avatar_url"]

        return name,avatar_url


视图层


# 回调
class GiteeBack(MethodView):
    # 回调接口
    def get(self):
        code = request.args.get('code', None)

        gitee = SimpleFactory.product('gitee')
        data = gitee.get_info(code)

        return jsonify({'code':Code.OK,'msg':code_desc[Code.OK],'data':data})
    # 返回url
    def post(self):
        return jsonify({'code':Code.OK,'msg':code_desc[Code.OK],'url':SimpleFactory.product('gitee').get_url()})

讲个故事先:
一个晴朗的日子,Alex 把远程版本库的修改拉到他的本地版本库。
他修改了名为 abc.txt 的文件,将其暂存(staged),提交(committed),最后推送(pushed)回远程版本库。
同时,Tina 不知道 Alex 对abc.txt文件的修改,在该文件的 相同区域 做了一些修改,并尝试将其推送到远程仓库。
Git是一个版本控制系统,所以它警告 Tina,她修改的版本比远程中的版本要早(因为 Alex 的修改已经在远程中)。
现在,Tina 需要先从远程拉出修改,更新文件,然后再尝试推送。
Tina 这样做了。然而,在她最疯狂的噩梦中,她得到了 "自动合并(auto-merge)" 失败的警告,所以她现在需要解决合并冲突。
这个故事有什么印象吗?上述故事与你有关吗?有可能你过去曾站在 Tina 的位置上。如果没有,你最终会遇到这种情况!

什么是Git合并冲突?

Git合并冲突是指当 Git 无法自动解决两次提交之间的代码差异时发生的事件。仅当提交位于不同的行或分支上时,Git 才能自动合并更改。

如何解决Git合并冲突?

首先,要说明的是,Git合并过程的冲突是团队开发过程中无法避免的。只能尽量减少冲突,但是不可能完全杜绝冲突。

方法一:创建短期分支

为了减少合并冲突的风险,建议创建短期的分支进行开发。长期分支会导致大量的合并冲突,特别是在feature分支开发数天甚至数周的情况下。
如果创建的分支仅存在数小时或一天,出现合并冲突的可能性将大大降低。即使出现冲突,解决的时间和风险也会相对较低。这是因为短期分支的变更较少,与其他分支的变更重叠的可能性较小,从而减少了冲突的发生几率,降低了合并风险。

方法二:小类

在代码开发中,应遵循单一职责原则,即一个类应只负责一个功能,这有助于避免多个开发人员同时修改同一代码块的情况,从而减少合并冲突。通过采用模块化架构和小类设计,不仅可以提高代码质量,还有助于降低合并冲突的风险。

方法三: 有效的沟通

沟通在团队开发中至关重要。通过加强团队成员之间的沟通,确保每个人都了解其他成员的工作内容和可能的代码改动,可以减少同时修改相同代码的情况。如果多个开发人员需要改动相同的代码部分,建议进行协同工作,以降低冲突风险。

方法四:结对编程

结对编程特别适用于涉及相同代码改动的场景。通过让两位开发人员共同构思和编码相同的代码部分,可以避免因同时修改而产生的代码冲突问题。这种方式有助于提升代码质量,并减少合并冲突的发生。

方法五:及时Rebase

为了保持与master分支的同步,建议定期进行Rebase操作。每天至少对master分支进行一次Rebase是很有必要的。这有助于及时将其他团队成员的改动合并到自己的分支中,避免引入过多的变更和潜在的冲突。这种做法与创建短期分支的目的相一致。

在 OpenAI 举办的「12天12场」发布会上,ChatGPT 的多项新功能正式亮相,包括 GPT-o1 正式版和 ChatGPT Pro(200 美元/月)、强化微调(Reinforcement Fine-Tuning)、Sora(视频生成)、增强版 Canvas(支持多模态创作与 Python 代码执行)、ChatGPT 扩展功能、ChatGPT Vision(语音视觉功能)、以及 Projects(项目管理)。这些功能使 ChatGPT 再次成为关注焦点,在此期间部分服务甚至一度中断达 4 小时。不知道 OpenAI 后面还有什么大招,小编也将持续关注,为您带来最新动态。

近日,吴恩达教授在 GitHub 上发布了一个名为 aisuite 的 Python 开源项目,旨在帮助开发者轻松接入多种生成式 AI 服务。同时,一款名为 PDFMathTranslate 的双语对照 PDF 翻译工具也备受关注,这两个项目均在 Python 热榜上占据了一席之地。令人眼前一亮、创新的开源终端 waveterm 通过内置图形小部件和 Web 浏览器,为开发者带来了全新的终端使用体验。最后,微软开源的 3D 生成模型 TRELLIS,由于其出色的生成效果,在一周内狂揽 2000+ Star。

  • 本文目录
    • 1. 热门开源项目
      • 1.1 内置小部件的终端:waveterm
      • 1.2 轻松接入多种生成式 AI 服务的 Python 库:aisuite
      • 1.3 多功能的服务器和网站监控平台:Checkmate
      • 1.4 双语对照的 PDF 翻译工具:PDFMathTranslate
      • 1.5 生成 3D 作品的开源模型:TRELLIS
    • 2. HelloGitHub 热评
      • 2.1 跨平台的机器学习模型可视化工具:Netron
      • 2.2 端到端的云原生数据库:SurrealDB
    • 3. 结尾

1. 热门开源项目

1.1 内置小部件的终端:waveterm

主语言:Go、TypeScript

Star:6.4k

周增长:1.3k

该项目是采用 Go 和 TypeScript 开发的跨平台终端工具,集成了 Web 浏览器和小部件功能。它能够在终端里运行图形化小部件,提高了终端的操作性和可视化体验,支持目录浏览器、编辑器、文件预览等功能,并允许用户在终端直接访问网页内容,比如 AI 聊天等。

GitHub 地址→
github.com/wavetermdev/waveterm

1.2 轻松接入多种生成式 AI 服务的 Python 库:aisuite

主语言:Python

Star:8.3k

周增长:800

这是一个帮助开发者通过简洁的 Python 代码,轻松集成多种生成式人工智能(Generative AI)服务的 Python 库。它易于安装、统一的 API 接口,可以轻松接入各种 LLM 服务,支持 OpenAI、Anthropic、Azure、Google、AWS 等多个供应商。

import aisuite as ai
client = ai.Client()

models = ["openai:gpt-4o", "anthropic:claude-3-5-sonnet-20240620"]

messages = [
    {"role": "system", "content": "Respond in Pirate English."},
    {"role": "user", "content": "Tell me a joke."},
]

for model in models:
    response = client.chat.completions.create(
        model=model,
        messages=messages,
        temperature=0.75
    )
    print(response.choices[0].message.content)

GitHub 地址→
github.com/andrewyng/aisuite

1.3 多功能的服务器和网站监控平台:Checkmate

主语言:JavaScript

Star:2.5k

周增长:1.7k

该项目是用 React.js、Node.js 和 MongoDB 构建的可视化监控平台,专为监控服务器、服务和网站运行状态而设计。它完全开源,可以轻松部署在自己的服务器上,支持对服务器硬件、网站、页面速度、基础设施、Docker 容器、端口等进行监控,以及提供邮件通知等功能。

GitHub 地址→
github.com/bluewave-labs/checkmate

1.4 双语对照的 PDF 翻译工具:PDFMathTranslate

主语言:Python

Star:8k

周增长:3.8k

这是一个基于 AI 的 PDF 文档翻译工具,专门用于翻译科学论文。它能够完整保留 PDF 文档的原始排版,确保译文与原文排版一致,实现双语对照翻译,支持 Google、DeepL、Ollama 和 OpenAI 等多种翻译服务。

GitHub 地址→
github.com/Byaidu/PDFMathTranslate

1.5 生成 3D 作品的开源模型:TRELLIS

主语言:Python

Star:4.2k

周增长:2.6k

该项目是微软开源的 3D 生成模型,可通过文本或图像提示生成具有复杂形状和纹理细节的 3D 作品。由于采用了 CUDA 技术,运行该模型至少需要 16GB 内存的 NVIDIA 显卡,适用于 3D 设计、建模和游戏开发等场景。

GitHub 地址→
github.com/Microsoft/TRELLIS

2. HelloGitHub 热评

在此章节中,我们将为大家介绍本周 HelloGitHub 网站上的热门开源项目,我们不仅希望您能从中收获开源神器和编程知识,更渴望“听”到您的声音。欢迎您与我们分享使用这些
开源项目的亲身体验和评价
,用最真实反馈为开源项目的作者注入动力。

2.1 跨平台的机器学习模型可视化工具:Netron

主语言:JavaScript

这是一个神经网络、深度学习和机器学习模型的可视化工具,支持多种模型格式,包括 ONNX、TensorFlow Lite、Core ML、Keras、Caffe、Darknet 和 PyTorch 等。

项目详情→
hellogithub.com/repository/2a682a1e2b5347b1a52999db34ff173c

2.2 端到端的云原生数据库:SurrealDB

主语言:Rust

这是一个用 Rust 开发的多模型数据库,支持表格(Table)、文档(Documents)和图(Graph)数据模型。它既可以作为数据库使用,也可作为 API 后端服务,支持 SQL、GraphQL、ACID 事务、图查询和全文索引等多种查询方式。

项目详情→
hellogithub.com/repository/0930e0d32d8248b3ae46c475f7d179cb

3. 结尾

以上就是本期「GitHub 热点速览」的全部内容,希望你能够在这里找到自己感兴趣的开源项目,如果你有其他好玩、有趣的 GitHub 开源项目想要分享,欢迎来
HelloGitHub
与我们交流和讨论。

往期回顾

本篇介绍
Manim
中的
渐变生长类
的动画。

这类动画的特点是可以清晰地展示图形的生成过程、物体的运动变化,帮助我们更好地理解抽象概念和复杂结构。

渐变生长类
的动画的主要有:

  1. GrowArrow
    :让箭头从起始点按设定路径(如直线或弧线)和速度动态生长
  2. GrowFromCenter
    :使对象以自身中心为起点,向四周按指定比例和速度均匀扩展生长
  3. GrowFromEdge
    :让对象从指定边缘开始,按照设定的速度和程度向内部或外部生长
  4. GrowFromPoint
    :从一个点开始,按照自定义的生长函数和速度来使对象生长
  5. SpinInFromNothing
    :结合旋转和渐显效果,使对象从无到有并伴随着旋转而出现

1. 动画概述

1.1. GrowArrow

GrowArrow
主要用于箭头(
Arrow
)对象的动画效果,能够让箭头从无到有地生长出来,给人一种动态的引导视觉效果。

它的动画过程比较平滑,能够很好地控制箭头生长的速度和方向,主要用于展示矢量相关内容的动画。

它的主要参数有:

参数名称 类型 说明
arrow Arrow类型 进行动画的箭头对象
point_color Color 箭头在生长到完整大小之前的初始颜色

主要方法有:

名称 说明
create_starting_mobject 用于创建动画起始时的对象状态

1.2. GrowFromCenter

GrowFromCenter
以对象的中心为起点,向四周扩展生长。

这种生长方式给人一种对称、均匀的视觉感受,使得对象的出现更加自然和美观。

对于具有中心对称性的对象,能够很好地突出其对称性,它适合用于展现图形从中心构建过程的动画。

它的主要参数有:

参数名称 类型 说明
mobject Mobject 要进行动画的对象
point_color Color 对象在生长到完整大小之前的初始颜色

1.3. GrowFromEdge

GrowFromEdge
以对象的边缘为起始点进行生长,能够很好地体现图形的边界扩展过程。

这种方式与
GrowFromCenter
形成对比,更侧重于展示图形是如何从边界开始构建的。

它可以根据需要选择不同的边缘作为生长起始边,常用于突出图形边界扩展的效果。

它的主要参数有:

参数名称 类型 说明
mobject Mobject 要进行动画的对象
edge np.ndarray 指定生长的起始边缘方向
point_color Color 对象在生长到完整大小之前的初始颜色

edge
参数可以使用预定义的方向常量(如
DOWN

RIGHT

UR
等)来指定对象的边界框边缘方向,

从而确定从哪个边缘开始生长。

1.4. GrowFromPoint

GrowFromPoint
从指定的一个点开始生长,这个点可以是对象内部或外部的任意一点。

这种方式提供了高度的定制性,能够聚焦于对象在某个特定位置的生长过程。

它可以用于创建一些具有创意的动画效果,比如让多个对象从不同的点同时生长,形成一个复杂的场景。

它的主要参数有:

参数名称 类型 说明
mobject Mobject 要进行动画的对象
point np.ndarray 指定对象生长的起始点
point_color Color 对象在生长到完整大小之前的初始颜色

主要方法有:

名称 说明
create_starting_mobject 创建动画起始时的对象状态
create_target 创建动画的目标对象状态

1.5. SpinInFromNothing

SpinInFromNothing
结合了旋转和从无到有的出现效果。

对象在旋转的同时逐渐显现,给人一种从虚无中旋转诞生的感觉

可以控制旋转的角度、方向和速度,以及对象出现的速度,从而实现各种不同的入场效果。

它的主要参数有:

参数名称 类型 说明
mobject Mobject 要进行动画的对象
angle float 指定对象在生长到完整大小之前旋转的角度
point_color Color 对象在生长到完整大小之前的初始颜色

angle
参数设置
2 * PI
表示对象将完整旋转一周(
360
度)后完全出现。

2. 使用示例

下面通过示例来演示各个生长类动画的使用。

2.1. GrowArrow 示例

在这个示例中,创建了三个不同方向的箭头。

对于每个箭头,使用
GrowArrow
动画并设置不同的初始颜色(
point_color
),为了能看出初始颜色,设置了箭头的最终颜色和初始颜色不一样。

# 创建不同方向的箭头
a1 = Arrow(LEFT * 2, RIGHT * 2, color=RED)
a2 = Arrow(UP * 2, DOWN * 2, color=BLUE)
a3 = Arrow(UR * 2, DL * 2, color=GREEN)

# 以不同颜色和路径弧度展示GrowArrow动画
self.play(
    GrowArrow(a1, point_color=BLUE),
)
self.play(
    GrowArrow(a2, point_color=GREEN),
)
self.play(
    GrowArrow(a3, point_color=RED),
)

2.2. GrowFromCenter 示例

此示例创建了圆形、正方形和三角形。在
GrowFromCenter
动画中,为每个图形设置不同的初始颜色(
point_color
)。

# 创建不同形状的对象
circle = Circle()
square = Square(color=BLUE)
triangle = Triangle(color=YELLOW)

# 以不同缩放比例和中心点展示GrowFromCenter动画
self.play(
    GrowFromCenter(circle, point_color=BLUE),
)
self.play(
    GrowFromCenter(square, point_color=YELLOW),
)
self.play(
    GrowFromCenter(triangle, point_color=RED),
)

2.3. GrowFromEdge 示例

在这个例子中,创建三个矩形。针对每个矩形的
GrowFromEdge
动画,指定了不同的起始边缘(
edge
)和不同的初始颜色(
point_color
)。

通过不同的边缘生长,可以看到矩形从边缘开始生长的多样化效果。

# 创建多个矩形
r1 = Rectangle(color=BLUE).shift(UP)
r2 = Rectangle(color=RED)
r3 = Rectangle(color=YELLOW).shift(DOWN)

# 从不同边缘和以不同速度展示GrowFromEdge动画
self.play(
    GrowFromEdge(r1, DOWN, point_color=BLUE),
)
self.play(
    GrowFromEdge(r2, RIGHT, point_color=RED),
)
self.play(
    GrowFromEdge(r3, UP, point_color=YELLOW),
)

2.4. GrowFromPoint 示例

该示例先创建了三个点,然后在通过不同的起始点和自定义生长函数,展示了
GrowFromPoint
动画在灵活指定生长起始点和控制生长方式方面的强大功能。

# 创建一个点和多个正方形
p1 = Dot(point=LEFT * 2, color=BLUE)
p2 = Dot(point=UP * 2, color=RED)
p3 = Dot(point=RIGHT * 2 + DOWN * 2, color=YELLOW)
s1 = Square(color=BLUE).shift(LEFT * 2)
s2 = Square(color=RED)
s3 = Square(color=YELLOW).shift(RIGHT * 2)

self.add(p1, p2, p3)
self.play(
    GrowFromPoint(s1, p1.get_center()),
)
self.play(
    GrowFromPoint(s2, p2.get_center(), 
                  grow_function=lambda t: t**2,
    ),
)
self.play(
    GrowFromPoint(s3, p3.get_center()),
)

2.5. SpinInFromNothing 示例

这里创建了三个不同边数的多边形。


SpinInFromNothing
动画中,为每个多边形设置了不同的旋转角度(
angle
)和初始颜色(
point_color
)。

通过不同的旋转角度和颜色设置,可以看到多边形从无到有并伴随着旋转和颜色变化的生长效果。

# 创建多个多边形
p1 = RegularPolygon(5).shift(LEFT * 2)
p2 = RegularPolygon(6, color=RED)
p3 = RegularPolygon(8, color=YELLOW).shift(RIGHT * 2)

# 以不同旋转角度和颜色展示SpinInFromNothing动画
self.play(
    SpinInFromNothing(p1),
)
self.play(
    SpinInFromNothing(p2, angle=np.pi),
)
self.play(
    SpinInFromNothing(p3, angle=3 * np.pi / 2, point_color=PINK),
)

3. 附件

文中的代码只是关键部分的截取,完整的代码共享在网盘中(
grow.py
),

下载地址:
完整代码
(访问密码: 6872)