【Virtual World 02】两点一线!!!

这是纯前端手搓虚拟世界第二篇。

在上一篇里,我们已经成功搭好了项目的基础骨架,并实现了最基础的单位 ------ Point2D类。如果你是中途加入,点下面先补一下。

戳这里就可以【Virtual World 01】头脑热一把,带你手搓虚拟世界💪!

吐个槽

第一篇写得有点啰嗦,可能有人觉得我"明明是手搓虚拟世界,为啥从语文课开始讲起"😂。

这...总得有点仪式感嘛。

别急别急!

上代码!!!

来,直接在我们primitives文件夹中,定义一个segment类。

js 复制代码
// ./primitives/segment.js
export default class Segment {
  // p1 p2 传入Point类 
  constructor(p1, p2) {
    this.p1 = p1;
    this.p2 = p2;
  }
}

现在看过去,这个类依旧那么简单,但如果能跟到后面,你会发现---它是构建虚拟世界里所有「形状」的基础大到建筑、道路、地形轮廓,小到网格、辅助线,全都绕不开它。

打基础的时候就是这么简单,但往往复杂的东西就是简单东西堆砌的。知道1+1然后考上了清华的朋友一定会给我点个赞的。

骑驴看账本--走着瞧吧

两点一线

对于创建虚拟世界,我们打小就有理论基础的。这个我坚信。

你肯定还记得小学二年级的王老师曾告诉你,两点才能成一条线!!!

嗯,好,知识充,接下来动手实操了。技术点上,主要还依赖canvasgetContext("2d")。其中有moveTolineTo

在Segment类中填上如下代码:

js 复制代码
// ./primitives/segment.js
draw(ctx, { width = 2, color = "black" } = {}) {
    ctx.beginPath();  // 开始绘制
    ctx.lineWidth = width; // 设置线的宽度
    ctx.strokeStyle = color; // 设置线的颜色
    ctx.moveTo(this.p1.x, this.p1.y);
    ctx.lineTo(this.p2.x, this.p2.y);
    ctx.stroke();
}

代码很好理解,但我们可以靠想象力丰富下。

脑海中想一下你拿着笔,先移动笔到纸的某一点,然后下笔,手腕将笔移动到另一点,把笔拿开,线搞定!!

show一下,在/src/index.js中的display方法添加如下代码:

js 复制代码
 // 用于绘制所有图形
  display() {
    new Segment(new Point2D(200, 200),new Point2D(400, 400)).draw(this.ctx)
  }

嗯...万里长征第二步。

粗细是个问题(但先不急)

先说明下:

属性 说明
lineWidth Canvas 只是大致控制粗细,不是像 SVG 那样精确
strokeStyle 支持颜色、渐变等
高级需求 需要结合像素密度 / DPR 做适配

目前好只是基础几何阶段先不在乎这个。后面做 坐标系 + 视口缩放 的时候,我们再一起处理 DPI 适配和缩放视觉一致性。

至于曲线,先忘掉这回事吧。

装个X

老师常常告诫我们举一反三,嗯,这就来了。

我们目前两个类:

  • Point2D
  • Segment

但理论上,可以绘制任何几何图形了,这样,简简单单搞个分形树

还在在/src/index.js中的display方法中,添加上实验代码:

js 复制代码
 // 用于绘制所有图形
 const fractalTree = (p1, length, angle, depth, ctx) => {
      if (depth <= 0) return;

      const p2 = new Point2D(
        p1.x + Math.cos(angle) * length,
        p1.y + Math.sin(angle) * length
      );

      new Segment(p1, p2).draw(this.ctx);

      const nextLength = length * 0.7;

      fractalTree(p2, nextLength, angle - 0.5, depth - 1, ctx); // 左叉
      fractalTree(p2, nextLength, angle + 0.5, depth - 1, ctx); // 右叉
}

fractalTree(new Point2D(300, 500), 120, -Math.PI / 2, 10, this.ctx);

不出意外,艺术成分还得上几层楼。

今天就这样了!!!

相关推荐
by__csdn43 分钟前
Vue2纯前端图形验证码实现详解+源码
前端·javascript·typescript·vue·状态模式·css3·canva可画
Gomiko1 小时前
JavaScript基础(八):函数
开发语言·javascript·ecmascript
我是阿亮啊1 小时前
搭建Vue环境遇到的问题
javascript·vue.js·npm·node.js
han_2 小时前
Vue.js 为什么要推出 Vapor Mode?
前端·javascript·vue.js
秋氘渔3 小时前
Vue 3 组合式写法:侦听器 watch 和 watchEffect 的区别及使用技巧
前端·javascript·vue.js·watch·watcheffect
阿奇__4 小时前
element二次封装组件套餐 搜索组件 表格组件 弹窗组件
javascript·vue.js·elementui
The_era_achievs_hero4 小时前
Echarts
前端·javascript·echarts
亮子AI5 小时前
【JavaScript】修改数组的正确方法
开发语言·javascript·ecmascript
可触的未来,发芽的智生5 小时前
微论-自成长系统引发的NLP新生
javascript·人工智能·python·程序人生·自然语言处理