zoukankan      html  css  js  c++  java
  • 手写造轮子day01--vue3自定义渲染-实现canvas

     
    <!DOCTYPE html>
    <html lang="en">

    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
    </head>

    <body>
      <div id="app">
      </div>

      <script type="text/x-template" id="chart">
        <bar-chart :data="chartData"></bar-chart>
      </script>

      <script src="../dist/vue.global.js"></script>
      <script>

        const { createRenderer } = Vue

        const renderer = createRenderer(
          // 创建element
          {
          createElement(tag) {
            return { tag }
          },
          // 更新属性
          patchProp(el, key, prevValue, nextValue) {
            // el就是上面对象,key是data,nextValue就是数据数组
            el[key] = nextValue
          },
          // 插入操作
          insert(child, parent) {
            // 判断为元素就执行画画操作
            if (parent.nodeType === 1) {
              // parent是canvas
              draw(child)
            }
          }
        })

        // 画画的逻辑
        let canvas, ctx
        const draw = (el, noClear) => {
          // 清空画布
          if (!noClear) {
            ctx.clearRect(0, 0, canvas.width, canvas.height)
          }
          // 判断tag
          if (el.tag == 'bar-chart') {
            const { data } = el;
            const barWidth = canvas.width / 10,
              gap = 20,
              paddingLeft = (data.length * barWidth + (data.length - 1) * gap) / 2,
              paddingBottom = 10;
            // x轴
            // 柱状图
            data.forEach(({ title, count, color }, index) => {
              const x = paddingLeft + index * (barWidth + gap)
              const y = canvas.height - paddingBottom - count
              ctx.fillStyle = color
              ctx.fillRect(x, y, barWidth, count)
              // ctx.fillRect(barWidth, count*2, x, y)
              // text
            });
          }
          // 递归绘制⼦节点
          el.childs && el.childs.forEach(child => draw(child, true));
        }

        // 声明高阶函数
        function createCanvasApp(App) {
          const app = renderer.createApp(App)
          const mount = app.mount

          app.mount = function (sel) {
            canvas = document.createElement('canvas')
            canvas.width = window.innerWidth
            canvas.height = window.innerHeight
            document.querySelector(sel).appendChild(canvas)
            ctx = canvas.getContext('2d')
            mount(canvas)
          }

          return app
        }

        createCanvasApp({
          template: '#chart',
          data() {
            return {
              chartData: [
                { title: "黑铁", count: 260, color: "yellow" },
                { title: "⻘铜", count: 200, color: "brown" },
                { title: "钻石", count: 300, color: "pink" },
                { title: "星耀", count: 100, color: "purple" },
                { title: "王者", count: 50, color: "gold" }
              ]
            }
          },
        })
          .mount('#app')

      </script>
    </body>

    </html>
  • 相关阅读:
    管道通信
    进程间的八种通信方式----共享内存是最快的 IPC 方式
    归并排序时间复杂度
    vector中的push_back函数的意思是什么
    如何实现android和服务器长连接
    android中实现service动态更新UI界面
    android中如何实现UI的实时更新---需要考虑电量和流量
    Map集合排序
    (二十一)自定义Tabbar
    (二十)首页内容详细【详细页】+ 评论 + 回复
  • 原文地址:https://www.cnblogs.com/soonK/p/14590869.html
Copyright © 2011-2022 走看看