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

JavaScript+Canvas創(chuàng)建一個(gè)獨(dú)特的字符畫生成器

 更新時(shí)間:2024年01月26日 10:49:47   作者:_XU  
這篇文章主要介紹了如何使用 Canvas 和 JavaScript 創(chuàng)建一個(gè)獨(dú)特的字符畫生成器,通過此生成器,我們可以將圖片轉(zhuǎn)換為由字符構(gòu)成的作品,感興趣的可以了解下

在本篇文章中,我將分享如何使用 Canvas 和 JavaScript 創(chuàng)建一個(gè)獨(dú)特的字符畫生成器。通過此生成器,我們可以將圖片轉(zhuǎn)換為由字符構(gòu)成的作品,并通過一些JavaScript屬性讓這些字符動(dòng)起來。結(jié)合現(xiàn)代的 Web 技術(shù),我們?cè)诰W(wǎng)頁上動(dòng)態(tài)地生成字符畫,并且通過添加一些動(dòng)畫效果,使其更富有趣味性。

準(zhǔn)備工作

首先,我們需要一些基礎(chǔ)的 HTML 結(jié)構(gòu)和 JavaScript 代碼,用于加載圖片并創(chuàng)建 Canvas。

<body>
  <div class="glass">
    <img id="myImg" src="./xxx.png" style="display: none;"></img>
    <div id="canvasDiv">
      <canvas id="canvas" width="600" height="600" style="display: none;"></canvas>
    </div>
    <div id="textDiv" class="textDiv" style="line-height: 0.9;"></div>
  </div>
  <script>
    // ...(后續(xù)代碼將在下文詳細(xì)介紹)
  </script>
</body>

圖片和canvas都不需要展示,設(shè)置它們?yōu)?code>display: none;

圖片加載與轉(zhuǎn)換

在 window.onload 事件中,我們加載圖片并將其繪制到 Canvas 上。為了保持生成的字符畫不失真,我們需要進(jìn)行一些調(diào)整。

window.onload = () => {
     canvas = document.getElementById("canvas");
     ctx = canvas.getContext("2d");
     const img = document.querySelector('#myImg');
     changeImg(img);
     let newimgText = imgText.split('</br>').map((e) => "<div class='amiDiv' style='display:flex'>" + e + "</div>") .join('');
      document.getElementById("textDiv").innerHTML = newimgText;
};

首先獲取canvas標(biāo)簽,并且創(chuàng)建一個(gè)2D渲染上下文ctx,以便后續(xù)使用。接下來,該代碼獲取圖片,并且將其作為參數(shù)傳遞給changeImg函數(shù),該函數(shù)將會(huì)對(duì)這個(gè)圖片進(jìn)行處理,將其轉(zhuǎn)換為字符畫并將結(jié)果存儲(chǔ)在全局變量imgText中。然后,定義新的字符串變量newimgText,將imgText字符串每一行分隔開,方便一會(huì)兒分別給每一行添加動(dòng)態(tài)效果。

Canvas 操作與字符生成

changeImg 函數(shù)中,我們使用 Canvas 獲取圖片像素信息,并逐個(gè)讀取每個(gè)像素的RGB值,計(jì)算出對(duì)應(yīng)的灰度值并映射到字符上。同時(shí),我們也可以調(diào)整字符大小控制顯示圖像的精度。

function changeImg(img) {
      // 清空字符畫
      imgText = "";
      // 先記錄比率,如果寬,那么先縮放寬,再用比率算出長,反之同理,這里是保證不超過不超過設(shè)定規(guī)模
      let rate = img.width / img.height;
      if (rate > 1) {
        img.style.width = IMAGE_SIZE + 'px';
        img.style.height = IMAGE_SIZE / rate + 'px';
        img.width = IMAGE_SIZE;
        img.height = IMAGE_SIZE / rate;
      } else {
        img.style.height = IMAGE_SIZE + 'px';
        img.style.width = IMAGE_SIZE * rate + 'px';
        img.height = IMAGE_SIZE;
        img.width = IMAGE_SIZE * rate;
      }

      ctx.clearRect(0, 0, canvas.width, canvas.height)
      // 將圖片繪制在canvas上
      ctx.drawImage(img, 0, 0, img.width, img.height);

      // 獲取像素信息
      let pixelInfo;
      try {
        pixelInfo = ctx.getImageData(0, 0, img.width, img.height);
      } catch {
        console("圖片有問題!");
      }
      // 數(shù)值越小,精度越高
      let size = 2;
      // 設(shè)置zoom縮放
      document.querySelector("#textDiv").style.zoom = size / 6;
      // 生成主體,逐個(gè)讀取字符
      for (let i = 0; i < img.height; i = i + size) {
        for (let j = 0; j < img.width; j = j + size) {
          const curPoint = (i * img.width + j) * 4; // ×4是因?yàn)椋?為r,2為g,3為b,4為a,四個(gè)是一組rgba值
          const [r, g, b] = pixelInfo.data.slice(curPoint, curPoint + 3);
          const gray = r * 0.3 + g * 0.6 + b * 0.1; // 計(jì)算灰度值
          const color = `rgba(${r},${g},$)`; // 保存像素點(diǎn)rgb值
          toText(gray, color)
        }
        imgText += "</br>";
      }
    }

拼接字符畫

將字符拼接成一行一行的文本。

    function toText(g, color) {
      if (color) imgText += `<span style='color:${color}'>`;
      if (g == 255) imgText += "&nbsp;&nbsp;&nbsp;";
      else imgText += "@";
      if (color) imgText += "</span>";
    }

添加動(dòng)態(tài)效果

最后,使用JavaScript的正弦函數(shù)來控制每個(gè)文字元素的位置和偏移量,從而實(shí)現(xiàn)字符畫龍?jiān)陧撁嫔系膭?dòng)態(tài)效果。

  const container = document.querySelectorAll(".amiDiv");

  // 創(chuàng)建曲線運(yùn)動(dòng)
  function createCurve(func, range) {
    container.forEach(e => {
      const points = getCurvePoints(func, range, e.children.length, e.clientWidth);
      for (let i = 0; i < points.length; i++) {
        e.children[i].style.transform = `translateY(${points[i]}px)`;
      }
    });
  }

  let offset = 0;
  createCurve((x) => Math.sin(x), [offset, offset + 2 * Math.PI]);

  setInterval(() => {
    offset += 0.1;
    createCurve((x) => Math.sin(x), [offset, offset + 2 * Math.PI]);
  }, 30);

  // 輔助函數(shù):獲取曲線上的點(diǎn)

  function getCurvePoints(curveFunc, range, number, xLength) {
    if (number < 1) {
      return [];
    }
    if (number === 1) {
      return [0];
    }
    const piece = (range[1] - range[0]) / (number - 1);
    const result = [];
    const scale = xLength / (range[1] - range[0]);
    for (let i = 0; i < number; i++) {
      result.push(-curveFunc(i * piece + range[0]) * scale);
    }
    return result;
  }

在這個(gè)龍年,愿我們的代碼如同神龍一般威猛,技術(shù)如同飛龍一般翱翔,最后祝大家新的一年:龍行龘龘,前程?hào)T朤!

到此這篇關(guān)于JavaScript+Canvas創(chuàng)建一個(gè)獨(dú)特的字符畫生成器的文章就介紹到這了,更多相關(guān)JavaScript Canvas字符畫生成器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • javascript:void(0)是什么意思示例介紹

    javascript:void(0)是什么意思示例介紹

    Javascript中void是一個(gè)操作符,該操作符指定要計(jì)算一個(gè)表達(dá)式但是不返回值,有不了解的朋友可以參考下本文
    2013-11-11
  • TypeScript入門之利用裝飾器擴(kuò)展代碼能力

    TypeScript入門之利用裝飾器擴(kuò)展代碼能力

    在?TypeScript?中,裝飾器是一種特殊的聲明,可以讓你的代碼更有趣、更靈活,下面小編就來帶大家學(xué)習(xí)一下TypeScript中裝飾器的具體使用吧
    2023-06-06
  • javascript中的一些注意事項(xiàng) 更新中

    javascript中的一些注意事項(xiàng) 更新中

    記錄一下這些內(nèi)容只是以后查閱起來方便,作為自己知識(shí)積累的記錄。其中有很多是參考網(wǎng)絡(luò)上的資源,不再一一寫出出處,還請(qǐng)?jiān)髡咭娬彙?/div> 2010-12-12
  • js數(shù)組去重的方法總結(jié)

    js數(shù)組去重的方法總結(jié)

    今天小編就為大家分享一篇關(guān)于js數(shù)組去重的方法總結(jié),小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • js中eval()函數(shù)和trim()去掉字符串左右空格應(yīng)用

    js中eval()函數(shù)和trim()去掉字符串左右空格應(yīng)用

    對(duì)于js中eval()函數(shù)的理解和寫一個(gè)函數(shù)trim()去掉字符串左右空格;對(duì)于js中eval()函數(shù)的理解是本人心得不一定正確,感興趣的朋友參考下,或許對(duì)你學(xué)習(xí)eval()函數(shù)有所幫助
    2013-02-02
  • 表單序列化與jq中的serialize使用示例

    表單序列化與jq中的serialize使用示例

    這篇文章主要介紹了表單序列化與jq中的serialize使用,需要的朋友可以參考下
    2014-02-02
  • JavaScript實(shí)現(xiàn)標(biāo)簽頁切換效果

    JavaScript實(shí)現(xiàn)標(biāo)簽頁切換效果

    這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)標(biāo)簽頁切換效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • javascript 面向?qū)ο骹unction詳解及實(shí)例代碼

    javascript 面向?qū)ο骹unction詳解及實(shí)例代碼

    這篇文章主要介紹了javascript 面向?qū)ο骹unction詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • 微信小程序--獲取用戶地理位置名稱(無須用戶授權(quán))的方法

    微信小程序--獲取用戶地理位置名稱(無須用戶授權(quán))的方法

    這篇文章主要介紹了微信小程序-獲取用戶地理位置名稱(無須用戶授權(quán))的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • Bootstrap每天必學(xué)之按鈕(Button)插件

    Bootstrap每天必學(xué)之按鈕(Button)插件

    Bootstrap每天必學(xué)之按鈕(Button)插件,通過按鈕(Button)插件,您可以添加進(jìn)一些交互,比如控制按鈕狀態(tài),或者為其他組件(如工具欄)創(chuàng)建按鈕組,感興趣的小伙伴們可以參考一下
    2016-04-04

最新評(píng)論

都昌县| 军事| 苍梧县| 宜君县| 开原市| 怀安县| 武隆县| 辰溪县| 光山县| 班戈县| 修文县| 乐山市| 柘城县| 平邑县| 衡水市| 喀喇| 达孜县| 石渠县| 瑞昌市| 蒙阴县| 秦皇岛市| 太谷县| 灯塔市| 盐边县| 临安市| 水富县| 南召县| 娱乐| 开平市| 文安县| 永春县| 北川| 内黄县| 特克斯县| 称多县| 庄河市| 随州市| 左权县| 茌平县| 错那县| 建德市|