成人性生交大片免费看视频r_亚洲综合极品香蕉久久网_在线视频免费观看一区_亚洲精品亚洲人成人网在线播放_国产精品毛片av_久久久久国产精品www_亚洲国产一区二区三区在线播_日韩一区二区三区四区区区_亚洲精品国产无套在线观_国产免费www

主頁(yè) > 知識(shí)庫(kù) > 原生canvas制作畫(huà)圖小工具的踩坑和爬坑

原生canvas制作畫(huà)圖小工具的踩坑和爬坑

熱門(mén)標(biāo)簽:電話機(jī)器人電銷系統(tǒng)掙話費(fèi) 拓展地圖標(biāo)注 高德地圖標(biāo)注地點(diǎn)糾錯(cuò) 南昌仁和怎么申請(qǐng)開(kāi)通400電話 電話機(jī)器人黑斑馬免費(fèi) 只辦理400電話 如何獲取地圖標(biāo)注客戶 機(jī)器人外呼系統(tǒng)存在哪些能力 平?jīng)龅貓D標(biāo)注位置怎么弄

最近在寫(xiě)一個(gè)類似截圖里的簡(jiǎn)易畫(huà)圖的小工具,畫(huà)線,畫(huà)矩形,畫(huà)圓,可以選擇顏色,就像這樣

 寫(xiě)的過(guò)程中遇到了一些坑,還好爬出來(lái)了,也得到幾位大佬的指點(diǎn),稍微接觸了一下zrender,在這里記錄一下。

坑1,繪制過(guò)程的預(yù)覽

用canvas畫(huà)線沒(méi)什么問(wèn)題,moveTo和lineTo就好了,來(lái)一段代碼湊字?jǐn)?shù)(:joy:)

鼠標(biāo)按下,開(kāi)始繪制,記錄初始鼠標(biāo)的位置
startPaint = (e)=>{
    this.startPaintFlag = true;
    this.paintstartX = e.clientX;
    this.paintstartY = e.clientY;
}

鼠標(biāo)抬起,停止繪制
stopPaint = (e)=>{
    this.startPaintFlag = false;    
}

painting = (e)=>{
    const {activeColor, activeShape} = this.state;
    
    繪制過(guò)程中
    if(this.startPaintFlag){
      const ctx = this.canvas.getContext("2d");
      ctx.strokeStyle = activeColor;
      ctx.lineWidth = 2;
      ctx.beginPath();
    
      if(activeShape === 'pen'){
        ctx.moveTo(this.paintstartX, this.paintstartY);
        ctx.lineTo(e.clientX, e.clientY);
      }
      if(activeShape === 'circle'){
        const r = Math.sqrt(Math.pow(e.clientX - this.paintstartX, 2) + Math.pow(e.clientY - this.paintstartY, 2));
        ctx.arc(this.paintstartX, this.paintstartY, r, 0, 2*Math.PI)
      }
      if(activeShape === 'rect'){
        ctx.rect(this.paintstartX, this.paintstartY, e.clientX - this.paintstartX, e.clientY - this.paintstartY);
      }
      ctx.stroke();
      
      記錄此次移動(dòng)的最后位置,供下一次繪制使用
      this.paintstartX = e.clientX;
      this.paintstartY = e.clientY;
    }
}

但是畫(huà)矩形和圓就出事了,因?yàn)榻貓D工具畫(huà)矩形和圓的時(shí)候,是有預(yù)覽效果的,就是我一邊畫(huà),我一邊能看到我畫(huà)出的形狀是多大,如果按照畫(huà)線的思路來(lái),會(huì)得到這樣的一串圖形

很好理解,因?yàn)閙ousemove的時(shí)候一直在改變位置和距離。那么如果我一開(kāi)始就記錄下位置,在畫(huà)矩形和圓的時(shí)候不改變初始位置呢,那么會(huì)得到以下圖形

也很好理解,因?yàn)闆](méi)有擦除,每次繪制的圖形都在畫(huà)布上。那擦除不就好了?不好,因?yàn)樵诋?huà)布上畫(huà)的不是只有一個(gè)圖形,如果我先畫(huà)線,再畫(huà)圓,那么一擦除,之前畫(huà)的線就沒(méi)了,令人糾結(jié)QAQ

我有過(guò)一個(gè)思路是,只擦除這個(gè)圖形內(nèi)部的形狀,比如上面這一堆同心圓,我只擦除最后繪制的那個(gè)圓內(nèi)部的內(nèi)容,可惜還是不行,一方面內(nèi)部可能有別的線事先繪制了,一方面圖形可以拖動(dòng)放大,也可以拖動(dòng)縮小,那么怎么辦呢?

在嘆了一口大氣,喝了一杯水,凝視了一下窗外之后,想出了一個(gè)辦法,我在畫(huà)布上再疊一個(gè)畫(huà)布不就好了,我在疊上去的這個(gè)畫(huà)布上就可以為所欲為了不是咩。

來(lái)個(gè)示意圖,黑色框框是我們展示用的畫(huà)布,黑色形狀表示已經(jīng)繪制上去的內(nèi)容,紅色框框是我們?cè)诋?huà)有預(yù)覽效果的圖形時(shí)所使用的臨時(shí)畫(huà)布,紅色形狀表示我們鼠標(biāo)拖動(dòng)過(guò)程中繪制的預(yù)覽內(nèi)容,每次需要繪制預(yù)覽內(nèi)容我們就生成一個(gè)臨時(shí)畫(huà)布,放在頂層,隨心所欲的繪制,繪制完畢(鼠標(biāo)抬起)將臨時(shí)畫(huà)布銷毀,在展示用的畫(huà)布(黑色框框)上繪制最終的圖形

來(lái)一段代碼幫助理解

startPaint = (e) => {
  this.startPaintFlag = true;
  this.paintstartX = e.clientX;
  this.paintstartY = e.clientY;

  畫(huà)矩形和圓形時(shí)臨時(shí)生成一個(gè)canvas
  if (this.state.activeShape !== "pen") {
    this.tempCanvas = document.createElement("canvas");
    this.tempCanvas.width = this.canvas.width;
    this.tempCanvas.height = this.canvas.height;
    
    設(shè)置一些定位樣式
    this.tempCanvas.style.cssText = "position: absolute; top: 0; left: 0; z-index: 0;";
    
    append到需要的容器元素里
    document.querySelector(".contain").appendChild(this.tempCanvas);
  }
};

stopPaint = (e) => {
  this.startPaintFlag = false;
  const { activeShape, activeColor } = this.state;
  if (activeShape !== "pen") {
    
    從容器元素里刪除臨時(shí)畫(huà)布
    document.querySelector(".contain").removeChild(this.tempCanvas);
    this.tempCanvas = null;
    
    將lastDrawData記錄的繪制數(shù)據(jù),繪制到展示用的畫(huà)布上
    const ctx = this.canvas.getContext("2d");
    ctx.strokeStyle = activeColor;
    ctx.lineWidth = 2;
    ctx.beginPath();
    if (activeShape === "circle") {
      const { x, y, r } = this.lastDrawData;
      ctx.arc(x, y, r, 0, 2 * Math.PI);
    } else {
      const { x, y, width, height } = this.lastDrawData;
      ctx.rect(x, y, width, height);
    }
    ctx.stroke();
    this.lastDrawData = null;
  }
};

painting = (e) => {
  const { activeColor, activeShape } = this.state;

  if (this.startPaintFlag) {
    const ctx = this.canvas.getContext("2d");
    ctx.strokeStyle = activeColor;
    ctx.lineWidth = 2;

    畫(huà)線的邏輯不動(dòng)
    if (activeShape === "pen") {
      ctx.beginPath();
      ctx.moveTo(this.paintstartX, this.paintstartY);
      ctx.lineTo(e.clientX, e.clientY);
      ctx.stroke();
      this.paintstartX = e.clientX;
      this.paintstartY = e.clientY;
    } else {

      有預(yù)覽的圖形繪制在臨時(shí)畫(huà)布上
      const tempCtx = this.tempCanvas.getContext("2d");
      tempCtx.strokeStyle = activeColor;
      tempCtx.lineWidth = 2;

      每次繪制前清除畫(huà)布
      tempCtx.clearRect(0, 0, this.canvas.width, this.canvas.height);
      tempCtx.beginPath();
      if (activeShape === "circle") {
        const r = Math.sqrt(
          Math.pow(e.clientX - this.paintstartX, 2) +
            Math.pow(e.clientY - this.paintstartY, 2)
        );
        tempCtx.arc(this.paintstartX, this.paintstartY, r, 0, 2 * Math.PI);

        繪制的數(shù)據(jù)記錄在一個(gè)變量里
        this.lastDrawData = {
          x: this.paintstartX,
          y: this.paintstartY,
          r,
        };
      } else {
        tempCtx.rect(
          this.paintstartX,
          this.paintstartY,
          e.clientX - this.paintstartX,
          e.clientY - this.paintstartY
        );
        this.lastDrawData = {
          x: this.paintstartX,
          y: this.paintstartY,
          width: e.clientX - this.paintstartX,
          height: e.clientY - this.paintstartY,
        };
      }
      tempCtx.stroke();
    }
  }
};

坑2,窗口大小變更

如果畫(huà)著畫(huà)著,突然用戶將窗口大小變了,你說(shuō)我是保持畫(huà)布大小不變呢,還是讓畫(huà)布大小隨著窗口改變而改變,如果窗口縮小,那么保持畫(huà)布大小不變是沒(méi)什么大問(wèn)題的,但是窗口如果變大,畫(huà)布區(qū)域又是自適應(yīng)的,那么就不得不跟隨改變了,但是canvas的寬高改變的話,內(nèi)容是會(huì)清除的,那么就面臨兩種選擇:

  1. 用變量將繪制的每一個(gè)坐標(biāo)記錄下來(lái),寬高變更后重新繪制;
  2. 將畫(huà)布的內(nèi)容直接作為圖像(這個(gè)形容不準(zhǔn)確,理解意思就行)保存下來(lái)

第一種我沒(méi)試過(guò),不過(guò)可想而知如果畫(huà)的內(nèi)容多了,應(yīng)該會(huì)閃爍一下,第二種,就我所知有兩種形式

第一種,用getImageData保存圖像,改變大小后,用putImageData繪制,putImageData只能裁剪圖像,不能拉伸
const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
canvas.width = newWidth;
canvas.height = newHeight;
ctx.putImageData(imgData, 0, 0);

第二種,還是創(chuàng)建一個(gè)臨時(shí)畫(huà)布,將圖形繪制下來(lái),改變大小后,用drawImage繪制,drawImage是可以拉伸圖像的
const newCanvas = document.createElement("canvas");
newCanvas.width = canvas.width;
newCanvas.height = canvas.height;
newCanvas.getContext("2d").drawImage(canvas, 0, 0);
canvas.width = newWidth;
canvas.height = newHeight;
ctx.drawImage(newCanvas, 0, 0);

開(kāi)始我選的是drawImage,窗口如果不是等比縮放(一般不可能等比),圖像可以拉伸,但是拉伸一兩次圖形就變得很模糊,所以可能還不如不改變圖像的比例為好,具體還是看場(chǎng)景

到此這篇關(guān)于原生canvas制作畫(huà)圖小工具的踩坑和爬坑的文章就介紹到這了,更多相關(guān)canvas畫(huà)圖小工具內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持腳本之家!

標(biāo)簽:遼源 新疆 青島 西藏 漯河 棗莊 池州 永州

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《原生canvas制作畫(huà)圖小工具的踩坑和爬坑》,本文關(guān)鍵詞  原生,canvas,制作,畫(huà)圖,小,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《原生canvas制作畫(huà)圖小工具的踩坑和爬坑》相關(guān)的同類信息!
  • 本頁(yè)收集關(guān)于原生canvas制作畫(huà)圖小工具的踩坑和爬坑的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    亚洲天堂小视频| а√天堂8资源在线| 91精品国产自产在线观看永久∴| 日韩精品手机在线| 99久久国产宗和精品1上映| 日本视频在线观看一区二区三区| 欧美女激情福利| 国产精品婷婷| 性欧美长视频免费观看不卡| 老太脱裤让老头玩ⅹxxxx| 久播影院第一理论片| 国产无遮挡猛进猛出免费软件| 国产精品激情自拍| 欧洲杯半决赛直播| 一区二区成人在线观看| 在线成人视屏| 亚洲无码精品在线观看| 欧美一区二区免费视频| 青娱乐国产在线视频| 91久久精品国产91性色69| 日韩精品综合在线| 7777久久亚洲中文字幕| 国产欧美综合一区| 欧美日韩成人综合| 久久免费高清| www.91popny.com| 精品国产白色丝袜高跟鞋| 91丨国产丨九色丨pron| 国产一区二区av| 伊人精彩视频| www亚洲欧美| 亚洲黑人在线| 亚洲第一精品福利| 91亚洲欧美激情| 国产在线精品一区| 国产精品久久久久久亚洲av| www.夜夜骑.com| 久久男人天堂| 成视频免费观看在线看| 国产精品久久久久久亚洲调教| 大胆亚洲人体视频| 日日爱66.cn| 91 在线视频| 美女脱光内衣内裤| 狠狠色丁香婷婷综合久久片| 阳光姐妹淘韩国版| 2023国产精品久久久精品双| 99国产精品99| 亚洲日本在线观看视频| 在线观看视频免费| 最近中文字幕在线视频| 91麻豆精品国产91久久综合| 亚洲精品免费观看| 成人综合久久网| 日日夜夜精品视频免费观看| 亚洲视频一区| 国产69精品久久久久777| 超碰人人在线| 91蝌蚪|人| 国产成人aa精品一区在线播放| 97自拍视频| 污污视频在线免费观看| 日本xxxxxwwwww| 青青青免费在线视频| 成人手机在线视频| 国产精品精品久久久久久| 岛国成人av| 91久久精品日日躁夜夜躁国产| 日本成人在线免费视频| 久久91精品国产| 校园春色亚洲| 亚洲av电影一区| 免费看欧美女人艹b| 欧美成人高清手机在线视频| 色综合视频在线观看| 欧美码中文字幕在线| 国产黄视频网站| 亚洲综合激情另类小说区| 国产性生活视频| 欧美美女黄色| 久久超碰亚洲| 国产主播在线资源| 岛国精品一区二区三区| 亚洲国产婷婷香蕉久久久久久| 韩国三级电影一区二区| 你懂得在线网址| www.国产欧美| 日韩久久在线| 顶级网黄在线播放| 日本爱爱小视频| 亚洲区精品久久一区二区三区| 久久久国产精品视频| 毛片毛片毛片毛片毛| 欧美人妖在线| 成人国产1314www色视频| 夜夜操天天干| 成年女人a毛片免费视频| 亚洲视频第二页| 深夜福利网站在线观看| 久久精品国产**网站演员| 欧美激情xxxxx| 国产亚洲一区在线播放| 91产国在线观看动作片喷水| 久久一级免费视频| 女人另类性混交zo| 中文精品一区二区三区| 欧美视频免费在线| 久久精品视频日本| 亚洲毛片在线免费| 久久xxxx精品视频| 黄大色黄女片18第一次| 极品美女一区二区三区| 这里只有精品视频在线观看| 日本精品福利视频| 国产视频高清免费| 成年人在线免费观看| 精品成在人线av无码免费看| 免费看日本黄色| 日韩影院在线| a级黄色毛片| 亚洲欧美欧美一区二区三区| 99草在线视频| 美女高潮在线观看| av影音在线| 亚洲欧美日韩精品一区二区| 午夜国产福利一区二区| 蜜臀一区二区三区| 日韩毛片在线播放| 五月激情在线| 四虎影视成人| 亚洲色大成网站www久久九九| 懂色av成人一区二区三区| 天天干,夜夜操| 日韩一级不卡| 高潮无码精品色欲av午夜福利| 国产精品福利视频一区二区三区| 国产精品探花一区二区在线观看| 国模视频一区二区三区| 欧美久久久久久久久中文字幕| 亚洲黄色激情视频| 日韩高清av在线| 日韩av一区二区三区在线| 欧美影院天天5g天天爽| 日本xxxxxwwwww| 深夜福利91大全| 男人在线视频资源| 国内精品免费视频| 亚洲国产欧美久久| 麻豆tv在线播放| 97福利网站在线观看视频| 亚洲成av人影片在线观看| 欧美视频亚洲色图| 亚洲国产精品123| 精品一区二区三区日本| 亚洲日韩第九十九页| 亚洲综合av在线播放| 国产奶水涨喷在线播放| 2020中文字幕在线| 国产一区欧美二区| 国产做a爰片久久毛片| 亚洲色大成网站www久久九九| 欧美精品777| 国产一区二区自拍视频| 欧美美乳视频网站在线观看| 国产亚洲自拍av| 成人免费视频a| 亚洲丝袜精品| 成人做爰69片免费看网站| 久久机热这里只有精品| 正在播放木下凛凛xv99| 销魂美女一区二区三区视频在线| 欧美精品乱码视频一二专区| 欧美日韩一区小说| 亚洲清纯自拍| 亚洲精品国产动漫| 亚洲国产精品一区二区尤物区| 美女激情视频网站| 久久99久久精品| 国产xxxxx视频| 亚洲图片欧洲图片av| 成人中心免费视频| 亚洲精品一区二区口爆| 欧美a大片欧美片| 国产日韩欧美日韩大片| 国产91在线亚洲| 2018av| 亚洲精品中文字幕乱码三区| 成人无号精品一区二区三区| 欧美高清视频一区| 人人妻人人澡人人爽久久av| 亚洲性图自拍| 亚洲一区二区视频在线观看| 可以免费在线观看的av| 性高湖久久久久久久久aaaaa| 久久久久久久久久久久国产精品| 久草在现在线| 成人写真视频| 日一区二区三区| 国产亚洲欧洲黄色| 欧美成人午夜视频| 欧美日韩亚洲一区二区三区| 欧美无遮挡国产欧美另类| www.久久网| 国产永久免费高清在线观看| 日本www视频在线观看| 美女免费视频黄| 亚洲香蕉伊在人在线观| 一区二区中文视频| 电影一区二区三区| 2024短剧网剧在线观看| 蜜桃伊人久久| 日韩精品久久久久久久电影99爱| 日韩欧美第二区在线观看| 人妻 日韩精品 中文字幕| 97精品超碰一区二区三区| 国产一区二区在线免费观看| 亚洲高清视频网站| 日本少妇一区| 三年中国国语在线播放免费| 欧美激情视频在线| 成人在线播放网站| 亚洲综合一区中| 日本黄色片免费观看| 在线成人综合色一区| 成人美女免费网站视频| 综合色就爱涩涩涩综合婷婷| 911av视频| 综合久久久久| 亚洲男人av在线| 久久av少妇| 日本久久一区二区三区| 亚洲精品国产精品国自产在线| 色婷婷综合在线观看| 欧美一区二区三区四区久久| 久久精品国产99国产| 国精产品999国精产品官网| 亚洲色图综合久久| 久草在线最新视频| 91久久精品日日躁夜夜躁国产| 亚洲欧美综合在线精品| 精品美女在线视频| 精品久久影视| 久久九九热视频| 中文字幕久久精品一区二区| 激情视频极品美女日韩| 久久久久久久久久久国产精品| 午夜精品亚洲一区二区三区嫩草| 国产精品丝袜一区二区三区| 亚洲一卡二卡三卡四卡| 亚洲色在线视频| 香蕉视频黄色在线观看| 一区二区国产精品| 国产精品一区二区精品视频观看| 久久夜色电影| 色悠悠国产精品| 久久最新网址| 亚洲中文字幕无码一区二区三区| 校园春色另类视频| 日韩一区二区电影| 成人亚洲精品777777ww| 日韩欧美亚洲范冰冰与中字| 北条麻妃69av| 91久久久久久久久| 亚洲日本青草视频在线怡红院| 一区二区三区免费| 久久夜精品va视频免费观看| 欧美性欧美巨大黑白大战| 国产久草在线| 亚洲国产综合久久| 国产精品69久久久久孕妇欧美| 超碰成人在线观看| 欧美人与牲动交xxxxbbbb| 欧美中文在线视频| 欧美阿v一级看视频| 亚洲小说欧美另类社区| 日本xxxx裸体xxxx| 99在线精品观看| 国产成人禁片免费观看视频| 性高潮久久久久久| 在线视频国内自拍亚洲视频| 国产欧美日韩精品一区二区免费| 成人性视频免费看| av三级在线观看| 色播五月综合| 欧美午夜在线播放| 毛片免费在线| 国产日本在线观看| 亚洲成a人片77777在线播放| 香蕉久久夜色精品国产更新时间| 久久视频国产| 亚洲自拍欧美精品| 麻豆精品99| 天天插天天射| 亚洲欧美日韩一区二区在线| 欧美精品第一页在线播放| av黄色免费| 欧美日韩人人澡狠狠躁视频| 亚洲男人第一网站| 禁果av一区二区三区| 欧美videos巨大粗暴| 国产免费专区| 中文字幕一区二区三区在线观看| 福利电影一区二区| av一级毛片| 久久久电影一区二区三区| 成人黄色短视频在线观看| 久久综合国产| 成人午夜视频福利| 欧美国产日韩一区| 国产成人a亚洲精品| 成人免费播放器| 高清在线成人网| av成人免费看| 欧美日产一区二区三区在线观看| 午夜伦欧美伦电影理论片| 隔壁老王国产在线精品| 国产五月天婷婷| 一本一道波多野毛片中文在线| 国产精品国三级国产av| 7777kkkk成人观看| 国产精品毛片在线| 亚洲色诱最新| 亚洲片国产一区一级在线观看| 求av网址在线观看| 欧美日韩中文视频| 日韩欧美国产高清91| 国产成人精品777777| 78精品国产综合久久香蕉|