使用vue+vite+ts+vitest创建canvas图形项目

前言

学习目标

  • 快速创建vue+vite+ts+vitest 项目
  • 搭建测试环境

知识点

  • vue
  • vite
  • ts
  • vitest

1-创建vite+vue3.0+ts 项目

在敲代码之前,我们先初始化一个专门写图形组件的项目。

1.建立vue 项目。我选择vue并没有什么其它目的,你若喜欢,用react也行。

npm create vite
√ Project name: canvas-lmm
√ Select a framework: » Vue
√ Select a variant: » TypeScript


Scaffolding project in D:\work\canvas引擎\canvas-stamp...

Done. Now run:


  cd canvas-lmm
  npm install
  npm run dev

这个项目的名称是canvas-lmm,我会用TypeScript来开发。

目前TypeScript已经是图形项目的标配了,这是我们走图形路线的同学必须要掌握的。

TypeScript很简单,所以我在后面的课程里不会对其进行系统讲解,但我会遇到什么说什么。

2.按照上面的提示进入项目,安装依赖,运行项目。

  cd canvas-stamp
  npm install
  npm run dev

效果如下:

image-20221203114003453

3.安装vitest,方便代码测试。

npm install -D vitest

tsconfig.json 的内容如下:

{

    "compilerOptions": {
        "target": "ESNext",
        "useDefineForClassFields": true,
        "module": "ESNext",
        "moduleResolution": "Node",
        "strict": true,
        "jsx": "preserve",
        "resolveJsonModule": true,
        "isolatedModules": true,
        "esModuleInterop": true,
        "lib": ["ESNext", "DOM"],
        "skipLibCheck": true,
        "noEmit": true,
        "suppressImplicitAnyIndexErrors": true,
        "ignoreDeprecations": "5.0"
    },
    "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
    "references": [{ "path": "./tsconfig.node.json" }]
}

4.安装vue-router,方便创建多个测试页面。

npm install vue-router@4

2-创建绘图测试页面

这里的测试页面主要是用于测试组件的绘图功能的。

1.把src 中的components 目录改成examples,我们要在其中创建测试案例。

2.建立路由文件

  • /src/router/index.ts
import { createRouter, createWebHistory } from 'vue-router'









const routes = [
    {
        path: '/',
        component: () => import('../examples/HelloWorld.vue'),
    },
]


const router = createRouter({
    history: createWebHistory(),
    routes,
})

export default router

3.修改examples/HelloWorld.vue 中的代码。

  • /src/examples/HelloWorld.vue
<script setup lang="ts">

import { ref, onMounted } from 'vue'

// 获取父组件属性
defineProps({
    size: { type: Object, default: { width: 0, height: 0 } },
})


// 对应canvas 画布的Ref对象
const canvasRef = ref<HTMLCanvasElement>()

onMounted(() => {
    const canvas = canvasRef.value
    const ctx = canvas?.getContext('2d')
    ctx?.fillRect(100, 100, 100, 100)
})
</script>

<template>
    <canvas ref="canvasRef" :width="size.width" :height="size.height"></canvas>
</template>

<style scoped>
</style>

我在上面的vue页面中创建了一张canvas画布,并在其中绘制了一个黑色正方形。

canvas画布的尺寸是从父组件中获取的。

4.在main.ts中应用路由。

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from './router'


createApp(App).use(router).mount('#app')

5.修改一下src中style.css的样式。

html {
    height: 100%;
}
body {
    margin: 0;
    height: 100%;
    overflow: hidden;
}
#app {
    height: 100%;
    display: flex;
}

6.在App.vue 中创建导航栏,并显示相应路由。

<script setup lang="ts">

import { onMounted, ref } from 'vue'
/* canvas 容器 */
const contRef = ref<HTMLDivElement>()
const size = ref<{
    width: number | undefined
    height: number | undefined
}>({
    width: 0,
    height: 0,
})

onMounted(() => {
    // 获取canvas 容器的尺寸
    const cont = contRef.value
    size.value.width = cont?.clientWidth
    size.value.height = cont?.clientHeight
})
</script>

<template>
    <!-- 路由出口 -->
    <div id="cont" ref="contRef">
        <!-- 将canvas容器的尺寸传给子组件 -->
        <router-view :size="size"></router-view>
    </div>
    <!-- 导航栏 -->
    <nav>
        <div class="nav-tit">测试</div>
        <router-link to="/">HelloWorld</router-link>
    </nav>
</template>

<style scoped>
nav {
    width: 200px;
    padding: 15px;
    border-left: 1px solid #ddd;
}
.nav-tit {
    font-weight: bold;
    margin-bottom: 15px;
}
nav a {
    display: block;
    margin-bottom: 10px;
}
#cont {
    flex: 1;
}
.router-link-active {
    color: #00acec;
}
</style>

最终效果如下:

image-20230312163409320

3-创建vitest测试文件

vitest 使用测试组件非可视部分的运行逻辑的。

1.在src中创建_tests_ 目录,然后在其中建立一个测试文件。

  • /src/tests/EventDispatcher.spec.ts
import { describe, expect, it } from 'vitest'









describe('EventDispatcher', () => {
    it('功能测试', () => {
        expect(1 + 1).toBe(2)
    })
})

之后这个文件会用于测试事件分发器。

2.在package.json 中添加一个测试命令

{

    ……
    "scripts": {
        "dev": "vite",
        "build": "vue-tsc && vite build",
        "preview": "vite preview",
        "test": "vitest --root src"
    },
    ……
}

3.执行test 命令,可见以下内容,这说明测试文件没有问题。

 ✓ _tests_/EventDispatcher.spec.ts (1)









 Test Files  1 passed (1)
      Tests  1 passed (1)
   Start at  17:28:34
   Duration  358ms (transform 44ms, setup 0ms, collect 29ms, tests 3ms)

4-创建图形类

接下来我们可以根据之前的关系树,创建类对象及其继承关系写出来。

image-20230301224856781

  • /src/lmm/core/EventDispatcher.ts
/* 事件调度器 */
export class EventDispatcher {}
  • /src/lmm/objects/Object2D.ts
import { EventDispatcher } from '../core/EventDispatcher'










class Object2D extends EventDispatcher {}
export { Object2D }
  • /src/lmm/objects/Img.ts
import { Object2D } from './Object2D'










class Img extends Object2D {}
export { Img }
  • /src/lmm/objects/Group.ts
import { Object2D } from './Object2D'










class Group extends Object2D {}
export { Group }
  • /src/lmm/core/Scene.ts
import { Group } from '../objects/Group'









class Scene extends Group {}
export { Scene }
  • /src/lmm/controler/ImgControler.ts
import { Object2D } from '../objects/Object2D'









class ImgControler extends Object2D {}
export { ImgControler }
  • /src/lmm/controler/OrbitControler.ts
import { EventDispatcher } from '../core/EventDispatcher'










/* 在裁剪坐标系中做轨道控制 */
class OrbitControler extends EventDispatcher {}
export { OrbitControler }
  • /src/lmm/core/Camera.ts
class Camera {}
export { Camera }

这个框架会涵盖图案编辑器的大部分

总结

当前的图形项目是与T恤编辑器的业务逻辑相分离的,这样可以让我们更专注于图形组件的开发。

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYRA0CIf' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片