[Vue] 09 - Canvas + OpenCV.js

Case: Canvas and Router

一、效果图

侧边栏效果。

代码下载:https://github.com/jiaopi404/my-canvas

 

二、demo-001 子模块 

执行动画

window.requestAnimationFrame(this.draw)

对canvas做具体操作。

<template>
  <div id="demo-001">
    <canvas id="demo-001-canvas">
      不支持 canvas
    </canvas>
  </div>
</template>

<script>
export default {
  name: 'demo-001.vue',
  data () {
    return {
      ctx: null,
      x: 0
    }
  },
  mounted () {
    this.init()
    // window.requestAnimationFrame(this.draw)
    this.draw()
  },
  methods: {
    init () {
      const canvas = document.getElementById('demo-001-canvas')
      this.ctx = canvas.getContext('2d')
    },
    draw () {
      // this.drawRect()  // 意义不大,可以注释掉
      this.drawPolygon()
      this.x += 1
      if (this.x >= 270) {
        this.x = 0
      }
      window.requestAnimationFrame(this.draw)
    },
    drawRect () {
      this.ctx.strokeRect(50, 50, 50, 50)
      this.ctx.fillRect(75, 75, 25, 25)
    },
    drawPolygon () {
      this.ctx.clearRect(0, 0, 300, 150)
      this.ctx.beginPath()
      this.ctx.moveTo(this.x, 75)
      this.ctx.lineTo(this.x + 30, 45)
      this.ctx.lineTo(this.x + 30, 105)
      // this.ctx.stroke()
      this.ctx.fillStyle = 'pink'
      // this.ctx.rotate(5 * Math.PI / 360)
      this.ctx.fill()
      // note
    }
  }
}
</script>

<style lang="scss" scoped>
#demo-001 {
  #demo-001-canvas {
    border-radius: 5px;
    border: 1px solid #333;
  }
}
</style>

 

三、home 主模块

参考:[Vue] 06 - Route

<template>
  <div id="home">
<div class="menu"> <el-scrollbar> <ul> <li><router-link to="demo-001">demo-001</router-link></li> <li><router-link to="demo-002">demo-002</router-link></li> </ul> </el-scrollbar> </div>
<div class="body"> <router-view></router-view> </div>
</div> </template> <script> export default { name: 'home', components: {
} }
</script> <style lang="scss" scoped> #home { display: flex; height: 100%; .menu { padding: 10px; width: 200px; height: 100%; background-color: pink; li { margin-bottom: 5px; } } .body { flex: auto; padding: 10px; } } </style>

 

四、路由配置

Ref: 关于Vue.use()详解(跟 install 有关)

参考:[Vue] 06 - Route

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

Vue.use(ElementUI) Vue.config.productionTip
= false new Vue({ router, store, render: h => h(App) }).$mount('#app')

此处,单独一个文件 router.js 进行路由配置。

import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'

Vue.use(Router)

export default new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  routes: [
    {
      path: '/',
      name: 'home',
      component: Home,
      redirect: '/demo-001'
    },
    {
      path: '/demo-001',
      name: 'demo-001',
      component: () => import('@/components/demo-001/demo-001.vue')
    },
    {
      path: '/demo-002',
      name: 'demo-002',
      component: () => import('@/components/demo-002/demo-002.vue')
    }
  ]
})

 

 

 

OpenCV.js

一、资源

Ref: https://github.com/greenpdx/opencv-vue [OpenCV 3.3.1 版本有点老旧]

 

Ref: https://github.com/hengzi/opencv-vue [预编译出opencvjs的包文件,也是 3.3.1 版本,再动态引用]

使用OpenCV.js进行人脸检测。

 

Ref: https://github.com/abtassociates/mecvision [前后端完整展示]

 

Ref: https://github.com/latsic/imgalign

WebAssembly的例子: 

    • Vue - The web framework used
    • Vuex - Vue store
    • Vuetify - Vue Material Design Component Framework
    • OpenCV - Open Source Computer Vision Library
    • WebAssembly - Binary instruction format for a stack-based virtual machine

  

二、代码分析

  • 依赖包配置:package.json

  "dependencies": {
    "axios": "^0.18.0",
    "opencv.js": "^1.2.1",
    "vue": "^2.6.6"
  },

 

  • 默认脚本文件:main.js

默认的样子。

import Vue from 'vue'
import App from './App.vue'
import Vue2TouchEvents from 'vue2-touch-events'
// import * as cv from './build-4.3.0/wasm/opencv.js';

Vue.use(Vue2TouchEvents)
Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

工程中使用OpenCV的案例。

import Vue from 'vue'
import App from './App.vue'
import Axios from 'axios'
import * as cv from 'opencv.js'

Vue.prototype.$http = Axios
Vue.prototype.$cv = cv

Vue.config.productionTip = false


let cnt = 0
let info
let tim = setInterval(() => {
  cnt++
  try {
    info = cv.getBuildInformation()
    clearInterval(tim)
    //console.log(cnt, 'INFO\n', info)

    // Now start Vue
    new Vue({
      render: h => h(App),
    }).$mount('#app')
  }
  catch(err) {
    //console.log('try again', cnt)
    if (cnt > 100) clearInterval(tim)
  }
}, 25)

 

  • 加载main.js的过程

 index.tml->main.js->app.vue->index.js->helloworld.vue

 

 

 

常见问题

这个画笔怎么奇奇怪怪的呢?

this.$cv.imshow("output", this.g_cur_frame);
this.$cv.imshow("canvas", this.g_cur_frame);
// this.canvasContext.drawImage(this.$refs.output, 0, 0)

imshow一用,就出现了如下奇怪的“画笔”,圆笔变叉叉笔。 What happened?

若干属性。

this.canvasContext = this.$refs.canvas.getContext('2d');
this.canvasContext.lineJoin    = 'round';
this.canvasContext.lineCap     = 'round';
this.canvasContext.lineWidth   = this.brushSize;
this.canvasContext.strokeStyle = this.tools[this.selectedToolIdx].color;

Ref: Canvas学习:globalCompositeOperation详解 [有图例和示范]

答案:

imshow后,可能是某种原因重置了canvas的属性,re-init canvas就好了。虽然比较龊,不优雅,但不妨碍功能的使用。

 

End.

posted @ 2020-08-21 18:36  郝壹贰叁  阅读(3014)  评论(0编辑  收藏  举报