最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

正文

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

經(jīng)過(guò)分析后,覺(jué)得使用canvas,能夠?qū)⒋诵Ч麑?shí)現(xiàn)。最終將功能拆分為以下三點(diǎn):

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

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

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

查閱大量資料及論壇后,沒(méi)有找到合適的案例,那只能由本人親自來(lái)手搓了,此案例涉及到以下知識(shí)點(diǎn):

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

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

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

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

首先,因canvas的繪制離不開(kāi)JS,但是在vue頁(yè)面中來(lái)書(shū)寫(xiě),又會(huì)導(dǎo)致vue頁(yè)面代碼量過(guò)多,所以,我單獨(dú)寫(xiě)了一個(gè)js文件,通過(guò) export 進(jìn)行導(dǎo)出,在vue頁(yè)面中進(jìn)行調(diào)用,下面來(lái)看代碼:

index.vue

<template>
    <div class="canvas-container">
        <div class="canvas-icon-content">左側(cè)選項(xiàng)列表</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 頁(yè)面中,主要是針對(duì)整體界面的搭建,css樣式進(jìn)行編寫(xiě),其中除了界面外,還有 管線設(shè)備 信息修改的彈窗界面編寫(xiě),如下圖

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

JS文件

在JS文件中,

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

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

數(shù)據(jù)傳輸這里,我是這樣做的,定義了一個(gè)對(duì)象 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; {},
    // 繪制類(lèi)型切換
    drawTypeChange: (ele) =&gt; {},
    // 修改管線類(lèi)型(冷熱水)
    changePipelineType: (type) =&gt; {},
    // 設(shè)備參數(shù)修改
    canvasModifyInfo: (info) =&gt; {},
    // 顯示設(shè)備可拖動(dòng)的區(qū)域范圍
    showEquipmentIconArea: ()  =&gt; {},
    commit: () =&gt; {
        // todo
        // 提交事件
    },
    // 清除整個(gè)畫(huà)布
   clearAll: (info) =&gt; {},
    // 數(shù)據(jù)回顯
    echoData: (data) =&gt; {}
}
export default canvasDraw

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

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

/**
 * 創(chuàng)建繪制元素工廠函數(shù)
 *
 * */
class ElementFactory {
    constructor(startX, startY, endX, endY) {
        this.startX = startX;  // 鼠標(biāo) 按下 X點(diǎn)
        this.startY = startY;  // 鼠標(biāo) 按下 Y點(diǎn)
        this.endX = endX;      // 鼠標(biāo) 抬起 X點(diǎn)
        this.endY = endY;      // 鼠標(biāo) 抬起 Y點(diǎn)
        this.type = 0;       // 繪制類(lèi)型:圖形、文字、圖片
        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
    }
    // 判斷點(diǎn)擊的是否存在元素繪制的范圍之內(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ù)條件來(lái)調(diào)用不同的繪制方法
    drawAllElement() {
        parseInt(this.type) === 0 ? this.drawPipeline() : (parseInt(this.type) === 1 ? this.drawEquipment() : this.drawText())
    }
}

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

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

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

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

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

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

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

具體代碼如下:

const canvasMousedown = (e) =&gt; {
    const rect = canvas.getBoundingClientRect();
    const clickX = e.clientX - rect.left;
    const clickY = e.clientY - rect.top;
    // 查詢所點(diǎn)擊元素是否存在
    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)點(diǎn)擊canvas查看是否點(diǎn)擊到了已經(jīng)繪制的路線,若是,則返回相關(guān)線的對(duì)象,若否,返回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)前點(diǎn)擊的位置是否已經(jīng)繪制了元素shape,如果shape存在,執(zhí)行移動(dòng)事件,如果不存在,則執(zhí)行繪制事件。

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

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

相關(guān)文章

最新評(píng)論

海阳市| 和平县| 陕西省| 高邮市| 太白县| 祥云县| 榆林市| 衡水市| 赞皇县| 上饶市| 连平县| 古蔺县| 临洮县| 谢通门县| 凉山| 阳东县| 如皋市| 永平县| 汪清县| 云龙县| 龙游县| 五莲县| 嘉禾县| 上饶市| 富源县| 永清县| 宜黄县| 仁布县| 涟源市| 东宁县| 道真| 丰台区| 大丰市| 安吉县| 鄄城县| 沙雅县| 乌鲁木齐市| 绥德县| 潢川县| 乡城县| 沂源县|