使用 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
属性设置渲染器类型。您可以指定一个值,例如 svg
、webgl
、canvas
等。 type
设置为 svg
。绘图空间的宽度和高度可以使用 width
和 height
参数指定。您还可以使用 fullscreen
参数将绘图空间设置为整个可用屏幕。当 fullscreen
设置为 true 时,width
和 height
的值将被忽略。
最后,您可以借助布尔型 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)
绘制普通矩形和圆角矩形。请记住, x
和 y
确定矩形的中心,而不是像许多其他库那样确定矩形的左上角坐标。 width
和 height
参数将确定矩形的大小。 radius
参数用于指定圆角的半径值。
您还可以分别使用 two.makeCircle(x, y, radius)
和 two.makeEllipse(x, y, width, height)
在网页上渲染圆形和椭圆形。就像矩形一样, x
和 y
参数指定圆或椭圆的中心。如果是椭圆形,则将 width
和 height
设置为相同的值会将其呈现为圆形。
借助 two.makeArrow(x1, y1, x2, y2, size)
方法也可以轻松创建箭头。 x1
和 y1
值确定箭头尾部的位置。 x2
和 y2
值确定箭头的位置。第五个参数决定箭头的大小。
有一个名为 two.makePolygon(x, y, radius,sides)
的方法,您可以使用它来创建正多边形。 x 和 y 值确定多边形的中心。 radius
确定多边形顶点到中心的距离,而 sides
指定多边形的边数。
操作组中的对象
Two.js 中您经常使用的一个有用方法是 two.makeGroup(objects)
。您可以传递不同对象的列表,也可以传递对象、路径或组的数组作为此方法的参数。它还将返回 Two.Group
对象。创建组后,您可以使用该组提供的属性一次性操作其所有子组。
Stroke
和 fill
属性可用于设置组中所有子项的描边和填充颜色。他们将接受所有可以在 CSS 中表示颜色的有效形式。这意味着您可以自由使用 RGB、HSL 或十六进制表示法。您也可以简单地使用颜色的名称,例如 orange
、red
或 blue
。同样,您可以设置所有其他属性的值,例如 linewidth
、opacity
、miter
和 cap
。可以使用 noFill()
和 noStroke()
方法删除组中所有子项的填充和描边。
您还可以应用其他物理变换,例如 scale
、rotation
和 translation
。这些变换将应用于单个对象。使用 add()
和 remove()
等方法可以轻松地将新对象添加到组中并删除它们。
下面是一个在随机位置创建大约 40 个不同矩形的示例。然后对矩形进行分组,以便我们可以立即更改它们的 fill
、Stroke
和 linewidth
值。
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 内的任意位置来更改矩形的位置。我们实际上将设定该组的位置。由于矩形是该组的一部分,因此它们会自动移动。
为了练习,您应该尝试修改代码并将矩形分成相等的两个组。对每个颜色值应用不同的 linewidth
和 lines
颜色值,以创建您自己独特的几何艺术作品。
定义渐变和编写文本
您可以在 Two.js 中定义线性和径向渐变。定义渐变并不意味着它会自动渲染在屏幕上,而是在设置各种对象的 fill
或 Stroke
值时可以使用它。
您可以使用 two.makeLinearGradient(x1, y1, x2, y2,stops)
定义线性渐变。值 x1
和 y1
确定渐变开始的坐标。同样,值 x2
和 y2
确定渐变结束的坐标。 stops
参数是 Two.Stop
实例的数组。它们定义了数组每个部分的颜色以及每种颜色过渡到下一种颜色的位置。它们可以使用 new Two.Stop(offset, color, opacity)
来定义,其中 offset
确定渐变上必须完全渲染该特定颜色的点。 color
参数确定特定点处渐变的颜色。您可以使用任何有效的 CSS 颜色表示作为其值。最后,opacity
参数决定颜色的不透明度。不透明度是可选的,它可以是 0 到 1 之间的任何值。
您可以使用 two.makeRadialGradient(x, y, radius,stops, fx, fy)
以类似的方式定义径向渐变。在这种情况下,值 x
和 y
确定渐变的中心。 radius
参数指定渐变应延伸多远。您还可以将停止点数组传递给此方法,以设置渐变的颜色组成。参数 fx
和 fy
是可选的,它们可用于指定渐变的焦点位置。
在下面的 CodePen 中查看一些渐变类型及其代码。
请记住,x
和 y
渐变的位置是相对于它们尝试填充的形状的原点而言的。例如,应该从中心填充形状的径向渐变将始终将 x
和 y
设置为零。
Two.js 还允许您在绘图区域上书写文本,并在以后根据您的需要进行更新。这需要使用方法 two.makeText(message, x, y, styles)
。从参数名称可以明显看出 message
是您要写入的实际文本。参数 x
和 y
是将作为写入文本中心的点的坐标。 styles
参数是一个对象,可用于设置大量属性的值。
您可以使用样式设置字体 family
、size
和 alignment
等属性的值。您还可以指定以下属性的值 fill
、行程
、opacity
、rotation
、scale
和 translation
。
创建 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; }
上面的代码将窗口中心的坐标存储在变量 centerX
和 centerY
中。稍后将使用它们将我们的原子放置在中心。 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 资源
以上就是使用 Two.js 创建 2D 图形入门:初学者指南的详细内容,更多请关注双恒网络其它相关文章!