likes
comments
collection
share

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

作者站长头像
站长
· 阅读数 45

前言

学习目标

  • 快速创建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

效果如下:

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

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>

最终效果如下:

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

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-创建图形类

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

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

  • /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恤编辑器的业务逻辑相分离的,这样可以让我们更专注于图形组件的开发。

转载自:https://juejin.cn/post/7244407068110602297
评论
请登录