整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          Fabric.js 右鍵菜單 - 掘金

          Fabric.js 右鍵菜單 - 掘金

          K創意鬧新春,我正在參加「春節創意投稿大賽」,詳情請看:春節創意投稿大賽

          本文簡介

          Fabric.js 默認沒提供 鼠標右鍵事件,只有 鼠標按鍵點擊 、鼠標按鍵抬起 、鼠標移動 等事件。 但在工作中有可能需要用到 “右鍵” 事件,比如 “右鍵菜單” 。所以就有了本文。
          本文主要關注 Fabric.js 的主要 api 有:

          • fireRightClick:允許右鍵點擊
          • stopContextMenu:禁用默認右鍵菜單
          • mouse:down:鼠標點擊事件



          如果不知道 Fabric.js 的同學,可以看 《Fabric.js 從入門到___》


          本案例是使用原生方式開發,不基于 Vue 、React 等框架,所以不用太擔心運行環境等問題。


          案例代碼放了在文末~



          環境和版本

          Chrome瀏覽器版本:96.0.4664.45

          Fabric.js版本:4.6.0


          思路

          先說說需求:

          • 右鍵單擊元素,彈出菜單;
          • 彈出菜單分4種情況(菜單在鼠標右側,菜單在鼠標左側,菜單在鼠標上方,菜單在鼠標下方);
          • 左鍵單擊畫布其他地方,隱藏菜單;


          實現思路:

          • 創建畫布;
          • 創建 “菜單” 的DOM元素;
          • 去官網查找 “右鍵相關事件”;
          • 右鍵單擊在元素上,根據鼠標離畫布邊緣的距離,計算菜單要顯示的位置;
          • 左鍵單擊在畫布上,隱藏菜單;


          實現

          查文檔

          在上面的思路中,其實難點只有 “右鍵相關事件” 。

          在 對象相關的文檔 里,關于鼠標的事件好像沒有右鍵,稍微沾邊點的就是鼠標點擊(這里我選了 mousedown)。


          于是我去 畫布的文檔 里找了下,發現這兩個屬性:

          • fireRightClick :畫布是否可以觸發右鍵事件
          • stopContextMenu:禁止默認右鍵菜單

          哈哈哈哈,發達了~


          經我仔細觀察,發現 mouse:down 事件里有個 button 屬性:

          • 左鍵:button 的值為 1
          • 右鍵:button 的值為 3
          • 中鍵(也就是點擊滾輪),button 的值為 2,前提需要設置 fireMiddleClick: true


          動手開發

          布局

          <style>
            /* 容器,相對定位 */
            .box {
              position: relative;
            }
          
            /* 畫布,給個邊框 */
            #canvas {
              border: 1px solid #ccc;
            }
          
            /* 菜單 */
            .menu-x {
              visibility: hidden; /* 隱藏菜單 */
              z-index: -100;
              position: absolute;
              top: 0;
              left: 0;
              box-sizing: border-box;
              border-radius: 4px;
              box-shadow: 0 0 4px rgba(0, 0, 0, 0.3);
              background-color: #fff;
            }
          
            /* 菜單每個選項 */
            .menu-li {
              box-sizing: border-box;
              padding: 4px 8px;
              border-bottom: 1px solid #ccc;
              cursor: pointer;
            }
          
            /* 鼠標經過的選項,更改背景色 */
            .menu-li:hover {
              background-color: antiquewhite;
            }
          
            /* 第一個選項,頂部兩角是圓角 */
            .menu-li:first-child {
              border-top-left-radius: 4px;
              border-top-right-radius: 4px;
            }
          
            /* 最后一個選項,底部兩角是圓角,底部不需要邊框 */
            .menu-li:last-child {
              border-bottom: none;
              border-bottom-left-radius: 4px;
              border-bottom-right-radius: 4px;
            }
          </style>
          
          <!-- 容器(相對定位) -->
          <div class="box">
            <!-- 畫布 -->
            <canvas id="canvas" width="600" height="600"></canvas>
          
            <!-- 右鍵菜單(絕對定位,且默認是隱藏的) -->
            <div
              id="menu"
              class="menu-x"
            >
              <div class="menu-li">什么都不做</div>
              <div class="menu-li">什么都不做</div>
              <div class="menu-li">什么都不做</div>
              <div class="menu-li">什么都不做</div>
              <div class="menu-li" onclick="delEl()">刪除</div>
            </div>
          </div>

          此時的效果如上圖所示。


          初始化畫布,并生成圖形

          <script>
          // 文檔加載后執行
          window.onload=function() {
            // 輸出當前 fabric 版本
            console.log(`Facrib.js版本:${fabric.version}`)
          
            // 初始化畫布
            init()
          
            // 禁止在菜單上的默認右鍵事件
            menu.oncontextmenu=function(e) {
              e.preventDefault()
            }
          }
          
          // 初始化
          function init() {
            canvas=new fabric.Canvas('canvas', {
              fireRightClick: true, // 啟用右鍵,button的數字為3
              stopContextMenu: true, // 禁止默認右鍵菜單
            })
          
            // 矩形
            const rect1=new fabric.Rect({
              left: 10,
              top: 510,
              fill: 'orange',
              width: 40,
              height: 40
            })
          
            // 圓角矩形
            const rect2=new fabric.Rect({
              left: 510,
              top: 10,
              fill: 'pink',
              width: 40,
              height: 40,
              rx: 10, // 圓角x
              ry: 10, // 圓角y
            })
          
            // 圓形
            const circle=new fabric.Circle({
              radius: 30, // 半徑
              fill: 'green',
              left: 20,
              top: 20,
            })
          
            // 三角形
            let triangle=new fabric.Triangle({
              width: 80, // 底邊寬度
              height: 100, // 底邊到定點的距離
              fill: 'blue',
              left: 500,
              top: 480
            })
          
            // 將矩形添加到畫布中
            canvas.add(rect1, rect2, circle, triangle)
          }
          </script>


          添加點擊事件(判斷右鍵)

          <script>
          // 省略上面的部分代碼
          function init() {
            // 省略部分代碼......
            // 將矩形添加到畫布中
            canvas.add(rect1, rect2, circle, triangle)
          
            // 按下鼠標
            canvas.on('mouse:down', canvasOnMouseDown)
          }
              
          // 鼠標在畫布上的點擊事件
          function canvasOnMouseDown(opt) {
          
            // 判斷:右鍵,且在元素上右鍵
            // opt.button: 1-左鍵;2-中鍵;3-右鍵
            // 在畫布上點擊:opt.target 為 null
            if (opt.button===3 && opt.target) {
              // 獲取當前元素
              activeEl=opt.target
          
              menu.domReady=function() {
                console.log(123)
              }
          
              // 顯示菜單,設置右鍵菜單位置
              // 獲取菜單組件的寬高
              const menuWidth=menu.offsetWidth
              const menuHeight=menu.offsetHeight
          
              // 當前鼠標位置
              let pointX=opt.pointer.x
              let pointY=opt.pointer.y
          
              // 計算菜單出現的位置
              // 如果鼠標靠近畫布右側,菜單就出現在鼠標指針左側
              if (canvas.width - pointX <=menuWidth) {
                pointX -=menuWidth
              }
              // 如果鼠標靠近畫布底部,菜單就出現在鼠標指針上方
              if (canvas.height - pointY <=menuHeight) {
                pointY -=menuHeight
              }
          
              // 將菜單展示出來
              menu.style=`
                visibility: visible;
                left: ${pointX}px;
                top: ${pointY}px;
                z-index: 100;
              `
            } else {
              hiddenMenu()
            }
          }
          
          // 隱藏菜單
          function hiddenMenu() {
            menu.style=`
              visibility: hidden;
              left: 0;
              top: 0;
              z-index: -100;
            `
            activeEl=null
          }
          
          // 刪除元素
          function delEl() {
            canvas.remove(activeEl)
            hiddenMenu()
          }
          </script>



          上面的代碼中,通過 opt.target 是否為 null 來判斷當前點擊的對象。

          opt.target===null ,就是點擊在畫布上(沒有點擊在圖形元素上)。

          如果你的項目需求是右鍵點擊畫布也展示不同菜單,你可以修改上面代碼的判斷。


          代碼倉庫

          • 原生方式實現Fabric右鍵菜單:https://gitee.com/k21vin/fabricjs-demo/blob/master/demos/ContextMenu/index.html
          • 在Vue3中使用Fabric實現右鍵菜單功能:https://gitee.com/k21vin/front-end-data-visualization/blob/master/src/views/FabricJS/Demo/pages/ContextMenu/ContextMenu.vue


          如果本文內容對你有所幫助,也請你幫我點個贊唄~


          章正文



            • 前言
            • 安裝 webpack
            • 創建項目
            • 創建一個簡單的 Demo
            • 編譯 ES6 代碼
            • 編譯 Vue 代碼
            • 配置 vue-router
            • 讓項目綁定端口跑起來
            • 編譯生成 HTML 文件
            • 處理 CSS
            • cross-env
            • 使用 Less
            • 處理圖片
            • 處理字體
            • 優化緩存
            • clean-webpack-plugin
            • 抽離公共代碼
            • 優化組件的引入路徑
            • 配置懶加載
            • 拆分webpack
            • 結語
            • 1. 創建 index.js 文件
            • 2. 在當前項目安裝 webpack
            • 3. 創建 webpack.dev.config.js
            • 4. 在根目錄創建 HTML 文件
            • 5. 執行編譯命令
            • 1. 安裝 ES6 需要的 loader
            • 2. 創建 .babelrc 文件
            • 3. 修改 webpack.dev.config.js 配置
            • 4. 添加 ES6 的代碼
            • 5. 執行編譯命令
            • 1. 安裝解析 Vue 語法的 loader 和 Vue
            • 2. 修改 webpack.dev.config.js 配置
            • 3. 添加 Vue 模板文件
            • 4. 執行編譯命令


          前言

          前段時間一直在找工作,作為前端目前最火的技術棧 Vue,被問到了很多次,其中問得最多的就是有沒有自己動手搭過腳手架。

          于是自己就嘗試著搭建 Vue 腳手架,在搭建腳手架的過程中,自己也遇到了各式各樣的問題,在此,我想把這些過程一步一步地寫下來。本文的項目文件夾會一個一個地構建,配置每一行都會有注釋,每一個文件干什么、配置是做什么的都會給大家介紹,供大家學習參考。

          安裝 webpack

          在這里我已經假設用戶已經安裝 Node 環境,我就不介紹 Node 環境的安裝,接下來我們安裝 webpack,這里要全局安裝,否則之后 webpack 命令無法執行。

          npm install --g webpack webpack-cli

          創建項目

          使用右鍵創建文件夾 my-app,進入文件打開命令提示符或者 PowerShell,執行 npm init,直接全部回車,我們會看到文件夾里會多了一個 package.json 的文件,這里面主要是對當前項目的一些描述。

          創建一個簡單的 Demo

          這里我準備隨便寫而一段 ES5 的代碼,然后通過 webpack 打包,介紹 webpack 基本的輸入輸出配置。

          1. 創建 index.js 文件

          在根目錄創建 src 文件夾,在該文件夾下創建 index.js 文件,并輸入如下代碼:

          document.getElementById("app").innerHTML="hello webpack";

          2. 在當前項目安裝 webpack

          npm install --save-dev webpack webpack-cli

          在以前只需要安裝 webpack 即可,但是現在必須安裝 webpack-cli,否則 webpack 命令會出錯。

          3. 創建 webpack.dev.config.js

          我們在根目錄建一個名為 webpack.dev.config.js 的文件,寫上如下代碼:

          const path=require('path');
          module.exports={
            entry: path.join(__dirname, 'src/index.js'),
            output: {
                path: path.join(__dirname, './dist'),
                filename: 'app.js'
            }
          };
          • entry:入口,一般配置項目的入口文件
          • __dirname:node下的全局變量,返回的是當前項目的絕對路徑
          • output:項目的輸出配置
          • output.path:輸出路徑
          • output.filename: 輸出文件名稱

          4. 在根目錄創建 HTML 文件

          在根目錄創建名為 index.html 的文件,在 body 中寫下如下內容,./dist/app.js 這個文件暫時是不存在的,編譯之后才會有。

          <body>
            <div id="app"></div>
            <script src="./dist/app.js"></script>
          </body>

          5. 執行編譯命令

          在根目錄執行編譯命令,格式:webpack --config 文件名稱

          webpack --config webpack.dev.config.js

          然后我們會看到根目錄自動生成了 dist 文件夾,里面有一個 app.js,和 webpack.dev.config.js 里面輸出是吻合的。這里來有一個警告:是指沒有設置 webpack 的環境(生產 or 開發)。

          一般解決方式兩種:

          修改命令

          webpack --config webpack.dev.config.js --mode=development 或者 production

          在 webpack.dev.config.js 里面的 entry 同級配置 mode:"development" 或者 mode:"production"。

          在瀏覽器打開第 4 步在根目錄創建的 index.html。

          編譯 ES6 代碼

          剛才演示了如何編譯 ES5 的代碼,接下來我們來看如何編譯 ES6 的代碼。

          1. 安裝 ES6 需要的 loader

          • babel-core:調用 Babel 的 API 進行轉碼
          • babel-preset-env:用于解析 ES6 的語法
          npm install babel-core babel-loader babel-preset-env --save-dev

          2. 創建 .babelrc 文件

          創建 .babelrc 文件,并輸入如下字符:

          {
              "presets": [
                [
                  "env",
                  {
                    "targets": {
                      "browsers": ["last 2 versions", "ie >=7"]
                    }
                  }
                ]
              ], 
            }

          3. 修改 webpack.dev.config.js 配置

          因為我們需要把 ES6 的代碼轉為 ES5 的代碼,除了安裝對于的 loader 外,還需要在 webpack.dev.config.js 中配置對于的解析規則。

          在 output 的同級寫入如下配置:

          module: {
              rules: [
                  {
                      test: /\.js$/,                  
                      loader: 'babel-loader',
                      exclude:/node-modules/
                  },
              ]
          }

          解析規則在 module 下的 rules 中配置,test 表示匹配的文件,loader 表示使用什么加載器,exclude 表示禁止解析該目錄下的文件。

          4. 添加 ES6 的代碼

          使用了 ES6 的箭頭函數和字符串拼接方式,把 src 目錄下的 index.js 文件修改為:

          var str="babel"
          var func=s=> {
              document.getElementById("app").innerHTML=`hello ${s}`;
          }
          func(str);

          5. 執行編譯命令

          執行命令:

          webpack --config webpack.dev.config.js --mode=development

          結果出現如下錯誤:

          一邊學習javascript一邊跟大家分享成果,喜歡就關注我吧,大家一起學習!

          今天分享javascript在chrome瀏覽器的常用斷點調試

          調試的源碼

          開始進入今天正題

          1設置斷點

          這邊以chrome瀏覽器為例,點F12進入調試,切換到sources選項卡,從左邊選擇要調試的文件,然后鼠標點擊展開文件的行號,出現藍色的標簽即為打上斷點。打上斷點后刷新網頁,就會執行到打斷點的那一行就停止執行。

          2介紹常用按鈕

          左一(藍色):正常執行 當刷新網頁后,停留在斷點處,點擊這個按鈕就會繼續正常執行下去

          左二:逐過程執行 當斷點斷在一個函數的時候,點這個按鈕,既執行完整個函數(直到下一個函數)

          左三:逐步執行 這個按鈕為分步執行,每點擊一次就執行一行代碼,適用較為細致的調試

          3逐過程執行(結果)

          4逐步執行(結果)

          注意藍條的位置,逐步執行到fn2的函數里面

          5設置條件斷點

          在行號前面點擊鼠標右鍵,選擇add conditional breakpoint選項既為設置條件斷點

          輸入條件,如上圖斷點條件為i==5,輸入完成后按回車鍵即設置完成條件斷點,條件斷點為橙色標簽(區別于普通藍色斷點)設置完成后點擊瀏覽器刷新按鈕進行調試。

          6watch屬性對變量進行監視

          watch屬性可以用來監視變量的值,如上面設置條件斷點后進行調試,查看屬性是否正確!


          主站蜘蛛池模板: 国内偷窥一区二区三区视频| 久久精品国产亚洲一区二区三区| 亚洲乱码av中文一区二区| 精品国产一区二区三区久久久狼| 97人妻无码一区二区精品免费| 亚洲乱码av中文一区二区 | 99在线精品一区二区三区| 日本一道一区二区免费看| 亚洲av成人一区二区三区在线观看| 国产波霸爆乳一区二区| 在线视频一区二区| 白丝爆浆18禁一区二区三区| 中文字幕亚洲乱码熟女一区二区| 中文字幕一区二区三匹| 日本精品一区二区三区在线视频一 | 国产一区内射最近更新| 国产视频一区在线观看| 色婷婷av一区二区三区仙踪林| 日韩精品一区二区三区不卡| 日韩在线不卡免费视频一区| 国产精品成人一区二区三区| 久久se精品一区精品二区| 亚洲AV网一区二区三区| 亚洲中文字幕无码一区二区三区| 一本久久精品一区二区| 一区二区三区观看| 中文字幕av日韩精品一区二区| 亚洲日韩国产一区二区三区 | 亚洲中文字幕丝袜制服一区| 国产精品视频一区国模私拍 | 成人国内精品久久久久一区| 国产自产对白一区| 国产丝袜视频一区二区三区| 在线观看日韩一区| 亚洲福利电影一区二区?| 久久精品国产一区二区三区不卡| 亚洲色一区二区三区四区| 久久久久久免费一区二区三区| 精品女同一区二区三区免费播放| 久久精品无码一区二区WWW| 中文字幕亚洲一区二区va在线|