0

0

使用 Two.js 创建 2D 图形入门:初学者指南

王林

王林

发布时间:2023-09-01 08:41:05

|

2014人浏览过

|

来源于php中文网

原创

使用 two.js 创建 2d 图形入门:初学者指南

Two.js 是一个 API,可让您轻松使用代码创建 2D 形状。继续学习,您将学习如何通过 JavaScript 创建形状并为其设置动画。

Two.js 与渲染器无关,因此您可以依靠相同的 API 使用 Canvas、SVG 或 WebGL 绘制 2D。该库有很多方法,可用于控制不同形状在屏幕上的显示方式或它们的动画方式。

  • 创建基本形状
  • 操作组中的对象
  • 定义渐变和编写文本
  • 创建 Two.js 项目

安装

该库的未压缩版本大小约为 128 KB,而压缩版本为 50 KB。如果您使用的是最新版本,则可以使用自定义构建进一步减小库的大小。

您可以从 GitHub 下载该库的缩小版本,也可以直接链接到 CDN 托管版本。将库添加到网页后,您就可以开始绘制不同的形状或对象并为其设置动画。

创建基本形状

首先,您需要告诉 Two.js 您想要在其上绘制 2D 并为形状设置动画的元素。您可以将一些参数传递给 Two 构造函数来进行设置。

使用 type 属性设置渲染器类型。您可以指定一个值,例如 svgwebglcanvas 等。 type 设置为 svg。绘图空间的宽度和高度可以使用 widthheight 参数指定。您还可以使用 fullscreen 参数将绘图空间设置为整个可用屏幕。当 fullscreen 设置为 true 时,widthheight 的值将被忽略。

最后,您可以借助布尔型 autostart 参数告诉 Two.js 自动启动动画。

将所有所需参数传递给构造函数后,您可以开始绘制直线、矩形、圆形和椭圆形。

您可以使用 two.makeLine(x1, y1, x2, y2) 绘制一条线。这里,(x1, y1) 是第一个端点的坐标,(x2, y2) 是第二个端点的坐标。该函数将返回一个 Two.Line 对象,该对象可以存储在变量中以便稍后进行进一步操作。

以类似的方式,您可以分别使用 two.makeRectangle(x, y, width, height)two.makeRoundedRectangle(x, y, width, height, radius) 绘制普通矩形和圆角矩形。请记住, xy 确定矩形的中心,而不是像许多其他库那样确定矩形的左上角坐标。 widthheight 参数将确定矩形的大小。 radius 参数用于指定圆角的半径值。

您还可以分别使用 two.makeCircle(x, y, radius)two.makeEllipse(x, y, width, height) 在网页上渲染圆形和椭圆形。就像矩形一样, xy 参数指定圆或椭圆的中心。如果是椭圆形,则将 widthheight 设置为相同的值会将其呈现为圆形。

借助 two.makeArrow(x1, y1, x2, y2, size) 方法也可以轻松创建箭头。 x1y1 值确定箭头尾部的位置。 x2y2 值确定箭头的位置。第五个参数决定箭头的大小。

有一个名为 two.makePolygon(x, y, radius,sides) 的方法,您可以使用它来创建正多边形。 x 和 y 值确定多边形的中心。 radius 确定多边形顶点到中心的距离,而 sides 指定多边形的边数。

操作组中的对象

Two.js 中您经常使用的一个有用方法是 two.makeGroup(objects)。您可以传递不同对象的列表,也可以传递对象、路径或组的数组作为此方法的参数。它还将返回 Two.Group 对象。创建组后,您可以使用该组提供的属性一次性操作其所有子组。

Strokefill 属性可用于设置组中所有子项的描边和填充颜色。他们将接受所有可以在 CSS 中表示颜色的有效形式。这意味着您可以自由使用 RGB、HSL 或十六进制表示法。您也可以简单地使用颜色的名称,例如 orangeredblue。同样,您可以设置所有其他属性的值,例如 linewidthopacitymitercap。可以使用 noFill()noStroke() 方法删除组中所有子项的填充和描边。

您还可以应用其他物理变换,例如 scalerotationtranslation。这些变换将应用于单个对象。使用 add()remove() 等方法可以轻松地将新对象添加到组中并删除它们。

下面是一个在随机位置创建大约 40 个不同矩形的示例。然后对矩形进行分组,以便我们可以立即更改它们的 fillStrokelinewidth 值。

var rects = [];

var elemWidth = document.querySelector("#draw-shapes").offsetWidth;

for (i = 0; i < 100; i++) {
  rects[i] = two.makeRectangle(
    Math.floor(Math.random() * elemWidth * 2),
    Math.floor(Math.random() * 420 * 2),
    10 + Math.floor(Math.random() * 100),
    10 + Math.floor(Math.random() * 100)
  );
}

var group = two.makeGroup(...rects);

group.noFill();
group.stroke = "black";
group.linewidth = 6;

two.update();

您可以单击 div 内的任意位置来更改矩形的位置。我们实际上将设定该组的位置。由于矩形是该组的一部分,因此它们会自动移动。

为了练习,您应该尝试修改代码并将矩形分成相等的两个组。对每个颜色值应用不同的 linewidthlines 颜色值,以创建您自己独特的几何艺术作品。

定义渐变和编写文本

您可以在 Two.js 中定义线性和径向渐变。定义渐变并不意味着它会自动渲染在屏幕上,而是在设置各种对象的 fillStroke 值时可以使用它。

您可以使用 two.makeLinearGradient(x1, y1, x2, y2,stops) 定义线性渐变。值 x1y1 确定渐变开始的坐标。同样,值 x2y2 确定渐变结束的坐标。 stops 参数是 Two.Stop 实例的数组。它们定义了数组每个部分的颜色以及每种颜色过渡到下一种颜色的位置。它们可以使用 new Two.Stop(offset, color, opacity) 来定义,其中 offset 确定渐变上必须完全渲染该特定颜色的点。 color 参数确定特定点处渐变的颜色。您可以使用任何有效的 CSS 颜色表示作为其值。最后,opacity 参数决定颜色的不透明度。不透明度是可选的,它可以是 0 到 1 之间的任何值。

Shakespeare
Shakespeare

一款人工智能文案软件,能够创建几乎任何类型的文案。

下载

您可以使用 two.makeRadialGradient(x, y, radius,stops, fx, fy) 以类似的方式定义径向渐变。在这种情况下,值 xy 确定渐变的中心。 radius 参数指定渐变应延伸多远。您还可以将停止点数组传递给此方法,以设置渐变的颜色组成。参数 fxfy 是可选的,它们可用于指定渐变的焦点位置。

在下面的 CodePen 中查看一些渐变类型及其代码。

请记住,xy 渐变的位置是相对于它们尝试填充的形状的原点而言的。例如,应该从中心填充形状的径向渐变将始终将 xy 设置为零。

Two.js 还允许您在绘图区域上书写文本,并在以后根据您的需要进行更新。这需要使用方法 two.makeText(message, x, y, styles)。从参数名称可以明显看出 message 是您要写入的实际文本。参数 xy 是将作为写入文本中心的点的坐标。 styles 参数是一个对象,可用于设置大量属性的值。

您可以使用样式设置字体 familysizealignment 等属性的值。您还可以指定以下属性的值 fill行程opacityrotationscaletranslation

创建 Two.js 项目

了解所有这些方法和属性后,是时候将它们应用到项目中了。在本教程中,我将向您展示如何使用 Two.js 渲染元素周期表的前十个元素,其中电子围绕原子核旋转。核也会有一些轻微的移动,以提高我们表示的视觉吸引力。

我们首先定义一些稍后将使用的变量和函数。

var centerX = window.innerWidth / 2;
var centerY = window.innerHeight / 2;

var elem = document.getElementById("atoms");

var elementNames = [
  "",
  "Hydrogen",
  "Helium",
  "Lithium",
  "Beryllium",
  "Boron",
  "Carbon",
  "Nitrogen",
  "Oxygen",
  "Fluorine",
  "Neon"
];

var styles = {
  alignment: "center",
  size: 36,
  family: "Lato"
};

var nucleusCount = 10;
var nucleusArray = Array();

var electronCount = 10;
var electronArray = Array();

function intRange(min, max) {
  return Math.random() * (max - min) + min;
}

上面的代码将窗口中心的坐标存储在变量 centerXcenterY 中。稍后将使用它们将我们的原子放置在中心。 elementNames 数组包含元素周期表前十个元素的名称。每个名称的索引对应于该元素的电子和质子数,并且以空字符串开头。 styles 对象包含用于设置文本对象样式的属性。

我们还定义了一个函数 intRange() 来获取给定极值范围内的随机整数值。

var two = new Two({ fullscreen: true }).appendTo(elem);

var protonColor = two.makeRadialGradient(
  0,
  0,
  15,
  new Two.Stop(0, "red", 1),
  new Two.Stop(1, "black", 1)
);

var neutronColor = two.makeRadialGradient(
  0,
  0,
  15,
  new Two.Stop(0, "blue", 1),
  new Two.Stop(1, "black", 1)
);

for (i = 0; i < nucleusCount; i++) {
  nucleusArray.push(two.makeCircle(intRange(-10, 10), intRange(-10, 10), 8));
}

nucleusArray.forEach(function(nucleus, index) {
  if (index % 2 == 0) {
    nucleus.fill = protonColor;
  }
  if (index % 2 == 1) {
    nucleus.fill = neutronColor;
  }
  nucleus.noStroke();
});

这将创建 Two 的实例并定义两个径向渐变。红/黑径向渐变代表质子,蓝/黑渐变代表中子。

我们使用 intRange() 函数将所有这些中子和质子放置在彼此 20 像素以内。 makeCircle() 方法还将这些质子和中子的半径设置为 10 像素。之后,我们迭代 nucleusArray 并交替用不同的渐变填充每个圆圈。

for (var i = 0; i < 10; i++) {
  if (i < 2) {
    var shellRadius = 50;
    var angle = i * Math.PI;
    electronArray.push(
      two.makeCircle(
        Math.cos(angle) * shellRadius,
        Math.sin(angle) * shellRadius,
        5
      )
    );
  }
  if (i >= 2 && i < 10) {
    var shellRadius = 80;
    var angle = (i - 2) * Math.PI / 4;
    electronArray.push(
      two.makeCircle(
        Math.cos(angle) * shellRadius,
        Math.sin(angle) * shellRadius,
        5
      )
    );
  }
}

将中子和质子放入原子核内很容易。然而,将电子正确地放置在均匀的距离需要一些数学知识。我们使用 shellRadius 变量来指定不同电子壳层距原子核的距离。整个圆所覆盖的角度等于 2 PI 弧度。我们可以通过在不同的电子之间均匀分布 2 PI 弧度来均匀地放置它们。

Math.cos()Math.sin() 函数用于根据不同电子的位置向量分离垂直和水平分量他们的角度。

var orbitA = two.makeCircle(centerX, centerY, 50);
orbitA.fill = "transparent";
orbitA.linewidth = 2;
orbitA.stroke = "rgba(0, 0, 0, 0.1)";

var orbitB = two.makeCircle(centerX, centerY, 80);
orbitB.fill = "transparent";
orbitB.linewidth = 2;
orbitB.stroke = "rgba(0, 0, 0, 0.1)";

var groupElectronA = two.makeGroup(electronArray.slice(0, 2));
groupElectronA.translation.set(centerX, centerY);
groupElectronA.fill = "orange";
groupElectronA.linewidth = 1;

var groupElectronB = two.makeGroup(electronArray.slice(2, 10));
groupElectronB.translation.set(centerX, centerY);
groupElectronB.fill = "yellow";
groupElectronB.linewidth = 1;

var groupNucleus = two.makeGroup(nucleusArray);
groupNucleus.translation.set(centerX, centerY);

这部分代码将来自不同壳层的电子以及中子和质子放入各自单独的组中。它还同时设置特定轨道中所有电子的填充颜色。

two
  .bind("update", function(frameCount) {
    groupElectronA.rotation += 0.025 * Math.PI;
    groupElectronB.rotation += 0.005 * Math.PI;
    groupNucleus.rotation -= 0.05;
  })
  .play();

var text = two.makeText("", centerX, 100, styles);

nucleusArray.forEach(function(nucleus, index) {
  nucleus.opacity = 0;
});

electronArray.forEach(function(electron, index) {
  electron.opacity = 0;
});

这部分代码将单个电子和质子的不透明度设置为零。它还告诉 Two.js 以特定速度旋转电子和质子。

visible = 0;

document.addEventListener("click", function(event) {
  if (visible < nucleusArray.length) {
    nucleusArray[visible].opacity = 1;
    electronArray[visible].opacity = 1;
    visible++;
    text.value = elementNames[visible];
  }
  else {
    nucleusArray.forEach(el => el.opacity=0);
    electronArray.forEach(el => el.opacity=0);
    visible = 0;
    text.value = elementNames[0];
  }
});         

代码的最后部分允许我们通过单击鼠标或点击来迭代元素。为了加载下一个元素,我们再添加一个电子和一个质子或中子可见,并更新元素名称。单击最后一个元素后,所有粒子都会再次隐藏,以便我们可以重新开始。 visible 变量跟踪当前可见的原子粒子的数量,以便我们可以相应地显示或隐藏它们。

尝试单击或点击以下 CodePen 演示来查看元素周期表的前十个元素。

最后的想法

本教程首先简要介绍了 Two.js 库以及如何使用它来绘制矩形、圆形和椭圆形等形状。之后,我们讨论了如何对不同的对象进行分组以同时操作它们。我们利用这种能力对元素进行分组,以同步平移和旋转它们。这些工具全部集中在我们的元素周期表前十个元素的原子动画中。

如您所见,使用 Two.js 创建动画 2D 图形非常容易。这篇文章的重点是帮助您快速入门,因此我们只介绍了基础知识。但是,您应该阅读官方文档以了解有关该库的更多信息!

更多 JavaScript 资源

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
Golang gRPC 服务开发与Protobuf实战
Golang gRPC 服务开发与Protobuf实战

本专题系统讲解 Golang 在 gRPC 服务开发中的完整实践,涵盖 Protobuf 定义与代码生成、gRPC 服务端与客户端实现、流式 RPC(Unary/Server/Client/Bidirectional)、错误处理、拦截器、中间件以及与 HTTP/REST 的对接方案。通过实际案例,帮助学习者掌握 使用 Go 构建高性能、强类型、可扩展的 RPC 服务体系,适用于微服务与内部系统通信场景。

6

2026.01.15

公务员递补名单公布时间 公务员递补要求
公务员递补名单公布时间 公务员递补要求

公务员递补名单公布时间不固定,通常在面试前,由招录单位(如国家知识产权局、海关等)发布,依据是原入围考生放弃资格,会按笔试成绩从高到低递补,递补考生需按公告要求限时确认并提交材料,及时参加面试/体检等后续环节。要求核心是按招录单位公告及时响应、提交材料(确认书、资格复审材料)并准时参加面试。

28

2026.01.15

公务员调剂条件 2026调剂公告时间
公务员调剂条件 2026调剂公告时间

(一)符合拟调剂职位所要求的资格条件。 (二)公共科目笔试成绩同时达到拟调剂职位和原报考职位的合格分数线,且考试类别相同。 拟调剂职位设置了专业科目笔试条件的,专业科目笔试成绩还须同时达到合格分数线,且考试类别相同。 (三)未进入原报考职位面试人员名单。

37

2026.01.15

国考成绩查询入口 国考分数公布时间2026
国考成绩查询入口 国考分数公布时间2026

笔试成绩查询入口已开通,考生可登录国家公务员局中央机关及其直属机构2026年度考试录用公务员专题网站http://bm.scs.gov.cn/pp/gkweb/core/web/ui/business/examResult/written_result.html,查询笔试成绩和合格分数线,点击“笔试成绩查询”按钮,凭借身份证及准考证进行查询。

6

2026.01.15

Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

63

2026.01.14

php与html混编教程大全
php与html混编教程大全

本专题整合了php和html混编相关教程,阅读专题下面的文章了解更多详细内容。

34

2026.01.13

PHP 高性能
PHP 高性能

本专题整合了PHP高性能相关教程大全,阅读专题下面的文章了解更多详细内容。

74

2026.01.13

MySQL数据库报错常见问题及解决方法大全
MySQL数据库报错常见问题及解决方法大全

本专题整合了MySQL数据库报错常见问题及解决方法,阅读专题下面的文章了解更多详细内容。

20

2026.01.13

PHP 文件上传
PHP 文件上传

本专题整合了PHP实现文件上传相关教程,阅读专题下面的文章了解更多详细内容。

31

2026.01.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号