欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

VUE使用canvas繪制管線管廊實現(xiàn)思路

 更新時間:2023年04月27日 14:19:46   作者:前端界的CV大師  
這篇文章主要為大家介紹了VUE使用canvas繪制管線管廊實現(xiàn)思路詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

正文

最近接到公司項目中的一個需求,需要繪制一個展示管線平面圖的功能,除了展示以外,還需要進行內(nèi)容的編輯,UI人員給的最終效果圖如下:

經(jīng)過分析后,覺得使用canvas,能夠?qū)⒋诵Ч麑崿F(xiàn)。最終將功能拆分為以下三點:

  • canvas 繪制圖形并填充
  • canvas 繪制圖片
  • canvas 繪制文字

其中,繪制圖形并填充對應(yīng)的為管線,繪制圖片對應(yīng)的為設(shè)備圖標(biāo),繪制文字則對應(yīng)設(shè)備上方的文字描述及其他部分的文字信息,例如:一供、二回等。

因上述功能為項目中的功能的一部分,項目整體由VUE搭建,所以,此功能需要在VUE的項目結(jié)構(gòu)上進行建立。

查閱大量資料及論壇后,沒有找到合適的案例,那只能由本人親自來手搓了,此案例涉及到以下知識點:

  • JS的鼠標(biāo)事件: onmousedown onmousemove onmouseup
  • canvas 坐標(biāo)軸與瀏覽器坐標(biāo)軸的計算
  • canvas 實時繪制
  • canvas 旋轉(zhuǎn)
  • 構(gòu)造函數(shù)的運用

先分享一下最后的成果吧~

因時間及此案例代碼量的關(guān)系

vue使用canvas繪制管線實現(xiàn)思路

首先,因canvas的繪制離不開JS,但是在vue頁面中來書寫,又會導(dǎo)致vue頁面代碼量過多,所以,我單獨寫了一個js文件,通過 export 進行導(dǎo)出,在vue頁面中進行調(diào)用,下面來看代碼:

index.vue

<template>
    <div class="canvas-container">
        <div class="canvas-icon-content">左側(cè)選項列表</div>
        <div class="canvas-content">
            <div class="canvas" id="canvas">
                <canvas id="myCanvas" ref="myCanvas"></canvas>
            </div>
            <div class="canvas-options">下方操作按鈕</div>
        </div>
    </div>
</template>
<script>
import canvas from '../utils/canvas'
let myCanvas = {}
export default {
    name: 'index',
    data() {
        return {}
    },
    mounted() {
        myCanvas = canvas.init('myCanvas')
    },
}
</script>

在 vue 頁面中,主要是針對整體界面的搭建,css樣式進行編寫,其中除了界面外,還有 管線設(shè)備 信息修改的彈窗界面編寫,如下圖

針對信息編輯后的 “確定” 及 “取消” 事件,全部通過調(diào)用 myCanvas 中的方法來進行。

JS文件

在JS文件中,

首先定義一個 allElementCollection 數(shù)組,這個數(shù)組最終需要提交給后端,同時,頁面中元素的繪制主要來自于這個主要數(shù)組。

剩下的就是來添加繪制的工作,以及JS中數(shù)據(jù)傳入vue頁面,vue頁面的數(shù)據(jù),傳入JS中。

數(shù)據(jù)傳輸這里,我是這樣做的,定義了一個對象 canvasDraw ,里面部分方法,如下代碼:

const canvasDraw = {
    init(element) {
        canvas = document.getElementById(element)
        ctx = canvas.getContext('2d')
        const w = 1200, h = 800;
        canvas.width = w * devicePixelRatio;
        canvas.height = h * devicePixelRatio;
        canvas.style.width = w + 'px';
        canvas.style.height = h + 'px';
        return canvas
    },
    // 回傳鼠標(biāo)抬起事件
    canvasMouseUp: (e) =&gt; {},
    // 繪制類型切換
    drawTypeChange: (ele) =&gt; {},
    // 修改管線類型(冷熱水)
    changePipelineType: (type) =&gt; {},
    // 設(shè)備參數(shù)修改
    canvasModifyInfo: (info) =&gt; {},
    // 顯示設(shè)備可拖動的區(qū)域范圍
    showEquipmentIconArea: ()  =&gt; {},
    commit: () =&gt; {
        // todo
        // 提交事件
    },
    // 清除整個畫布
   clearAll: (info) =&gt; {},
    // 數(shù)據(jù)回顯
    echoData: (data) =&gt; {}
}
export default canvasDraw

上述代碼中,所有的 canvas 相關(guān)的方法,都通過對象 canvasDraw 導(dǎo)出,在vue頁面,就可以通過 myCanvas 來進行調(diào)用了。

接下來,我們需要一個構(gòu)造函數(shù),這個函數(shù)的作用是,通過構(gòu)造函數(shù),可以 new 多個對象,每個對象里面有鼠標(biāo)按下的起點坐標(biāo) startX、startY,鼠標(biāo)抬起的重點坐標(biāo) endX、endY,以及繪制的類型、繪制不同類型的信息對象、繪制形狀的方法、繪制文字的方法、繪制圖片的方法:

/**
 * 創(chuàng)建繪制元素工廠函數(shù)
 *
 * */
class ElementFactory {
    constructor(startX, startY, endX, endY) {
        this.startX = startX;  // 鼠標(biāo) 按下 X點
        this.startY = startY;  // 鼠標(biāo) 按下 Y點
        this.endX = endX;      // 鼠標(biāo) 抬起 X點
        this.endY = endY;      // 鼠標(biāo) 抬起 Y點
        this.type = 0;       // 繪制類型:圖形、文字、圖片
        this.pipelineInfo = {};  // 圖形(管線)私有信息
        this.equipmentInfo = {};  // 圖片(設(shè)備)私有信息
        this.textInfo = {};      // 文字(文字)私有信息
    }
    get minX() {
        return Math.min(this.startX, this.endX);
    }
    get maxX() {
        return Math.max(this.startX, this.endX);
    }
    get minY() {
        return Math.min(this.startY, this.endY);
    }
    get maxY() {
        return Math.max(this.startY, this.endY);
    }
    get middleX() {
        return this.endX - (this.endX - this.startX) / 2
    }
    get middleY() {
        return this.endY - (this.endY - this.startY) / 2
    }
    // 判斷點擊的是否存在元素繪制的范圍之內(nèi)
    isInside(x, y) {
        return x &gt;= this.minX &amp;&amp; x &lt;= this.maxX &amp;&amp; y &gt;= this.minY &amp;&amp; y &lt;= this.maxY
    }
    // 繪制管線
    drawPipeline() {}
    // 繪制設(shè)備
    drawEquipment() {}
    // 繪制設(shè)備上方文字
    drawEquipmentText() {}
    // 繪制純文本
    drawText() {}
    // 根據(jù)條件來調(diào)用不同的繪制方法
    drawAllElement() {
        parseInt(this.type) === 0 ? this.drawPipeline() : (parseInt(this.type) === 1 ? this.drawEquipment() : this.drawText())
    }
}

基本的方法已經(jīng)寫完了,那接下來,就剩下一些鼠標(biāo)的管理事件了。

在函數(shù) canvasMousedown 中,主要處理三件事情:

1、鼠標(biāo)按下事件;

2、鼠標(biāo)移動事件;

3、鼠標(biāo)抬起事件。

鼠標(biāo)按下的那一刻,有以下幾個方面需要注意:

  • 鼠標(biāo)是左鍵點擊還是右鍵點擊;
  • 當(dāng)前鼠標(biāo)點擊的位置,即startX、startY;
  • 當(dāng)前鼠標(biāo)點擊的位置是否是存在了已經(jīng)繪制的內(nèi)容;

具體代碼如下:

const canvasMousedown = (e) =&gt; {
    const rect = canvas.getBoundingClientRect();
    const clickX = e.clientX - rect.left;
    const clickY = e.clientY - rect.top;
    // 查詢所點擊元素是否存在
    const shape = getElement(clickX, clickY);
    if (shape) {
        moveAllElement(e, clickX, clickY, rect, shape);
        canvas.style.cursor= "move";
    } else {
        if (e.buttons === 1) {
            draw_element_type === 0 ? drawRealTimePipeline(e, clickX, clickY, rect) : (draw_element_type === 1 ? drawRealTimeEquipment(e, clickX, clickY, rect) : drawRealTimeText(e, clickX, clickY, rect))
        }
    }
};

其中 getElement 方法為:

// 鼠標(biāo)點擊canvas查看是否點擊到了已經(jīng)繪制的路線,若是,則返回相關(guān)線的對象,若否,返回null
const getElement = (x, y) =&gt; {
    for (let i = allElementCollection.length - 1; i &gt;= 0; i--) {
        if (element.isInside(x, y)) return element;
    }
    return null
};

鼠標(biāo)按下后,獲取到 clickX、clickY,判斷當(dāng)前點擊的位置是否已經(jīng)繪制了元素shape,如果shape存在,執(zhí)行移動事件,如果不存在,則執(zhí)行繪制事件。

大致的思路就是上述分享內(nèi)容,接下來的文章中,我會將具體的方法及注意事項進行細(xì)化,

以上就是VUE使用canvas繪制管線管廊實現(xiàn)思路的詳細(xì)內(nèi)容,更多關(guān)于VUE canvas繪制管線管廊的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • vue用戶長時間不操作退出到登錄頁的兩種實現(xiàn)方式

    vue用戶長時間不操作退出到登錄頁的兩種實現(xiàn)方式

    出于安全考慮,用戶長時間不操作,就回到登錄頁面,讓用戶重新登錄,本文就記錄一下實現(xiàn)這種效果的兩種方式,具有一定的參考價值,感興趣的可以了解一下
    2021-09-09
  • vue3在setup中使用mapState解讀

    vue3在setup中使用mapState解讀

    這篇文章主要介紹了vue3在setup中使用mapState方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • 關(guān)于引入vue.js 文件的知識點總結(jié)

    關(guān)于引入vue.js 文件的知識點總結(jié)

    在本篇文章里小編給大家分享的是關(guān)于引入vue.js 文件的知識點總結(jié),有需要的朋友們可以參考學(xué)習(xí)下。
    2020-01-01
  • 在 vue-cli v3.0 中使用 SCSS/SASS的方法

    在 vue-cli v3.0 中使用 SCSS/SASS的方法

    關(guān)于如何在 vue-cli v3.0 中使用 SCSS/SASS,這里提供三種方案。感興趣的朋友通過本文一起學(xué)習(xí)吧
    2018-06-06
  • Vue項目中使用jquery的簡單方法

    Vue項目中使用jquery的簡單方法

    這篇文章主要給大家介紹了關(guān)于Vue項目中使用jquery的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Vue具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • vue jsx 使用指南及vue.js 使用jsx語法的方法

    vue jsx 使用指南及vue.js 使用jsx語法的方法

    這篇文章主要介紹了vue jsx 使用指南及vue.js 使用jsx語法的方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2017-11-11
  • 淺談webpack SplitChunksPlugin實用指南

    淺談webpack SplitChunksPlugin實用指南

    這篇文章主要介紹了淺談webpack SplitChunksPlugin實用指南,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09
  • vue.js input框之間賦值方法

    vue.js input框之間賦值方法

    今天小編就為大家分享一篇vue.js input框之間賦值方法具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-08-08
  • Vue條件渲染與列表渲染

    Vue條件渲染與列表渲染

    這篇文章主要介紹了Vue條件渲染與列表渲染,條件渲染包括v-if、v-show等內(nèi)容,文章對條件渲染及列表渲染介紹詳細(xì),具有一定的參考價值,需要的小伙伴可以參考一下
    2022-05-05
  • VSCode Vue開發(fā)推薦插件和VSCode快捷鍵(小結(jié))

    VSCode Vue開發(fā)推薦插件和VSCode快捷鍵(小結(jié))

    這篇文章主要介紹了VSCode Vue開發(fā)推薦插件和VSCode快捷鍵(小結(jié)),文中通過圖文表格介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08

最新評論