国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

慶祝新年?畫一顆圣誕樹?還是...

cloud / 1321人閱讀

摘要:關(guān)于節(jié)日圣誕節(jié),元旦,看大家情侶在朋友圈里發(fā)各種慶祝的或者祝福的話語,甚是感動,然后悄悄拉黑了。預覽效果本地下打開很卡,火狐正常圣誕樹早先的時候是圣誕節(jié)的時候,看到各種用字符組成圣誕樹的形式,于是自己就去試了下,還是比較簡單的。

關(guān)于節(jié)日

圣誕節(jié),元旦,看大家(情侶)在朋友圈里發(fā)各種慶祝的或者祝福的話語,甚是感動,然后悄悄拉黑了。作為單身狗,我們也有自己慶祝節(jié)日的方式,今天我們就來實現(xiàn)一些祝福的效果。

需要說明的是,所有的效果都是利用canvas來實現(xiàn)的。
祝福話語

偷了朋友的圖,很基本的慶祝方式,展示不同的文字,一段時間切換一次,普普通通,但是對于低像素來說,是最好的方法了,也是慶祝節(jié)日用的最多的了,我們這里做個效果多一點的版本
效果展示:

基本原理是這樣的:

canvas中把字畫出來,漸變色效果,通過canvas的相關(guān)API獲取imageData,就是像素點信息,同rgba。

遍歷imageData,生成相關(guān) dom。

設置定時,因為渲染不同的文字效果,當然,有過渡效果。

過程對應的代碼:

canvas里寫字,且漸變效果:

// 像素點的單位長度
const rectWidth =
  parseFloat(document.documentElement.style.getPropertyValue("--rect-width"));
const canvas = document.createElement("canvas");
canvas.width = 100;
canvas.height = 20;

const ctx = canvas.getContext("2d");
ctx.font = "100 18px monospace";
ctx.textBaseline = "top"; // 設置文字基線
ctx.textAlign = "center";
// 將區(qū)域內(nèi)所有像素點設置成透明
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 漸變效果
const gradient = ctx.createLinearGradient(10, 0, canvas.width - 10, 0);
gradient.addColorStop(0, "red");
gradient.addColorStop(1 / 6, "orange");
gradient.addColorStop(2 / 6, "yellow");
gradient.addColorStop(3 / 6, "green");
gradient.addColorStop(4 / 6, "blue");
gradient.addColorStop(5 / 6, "indigo");
gradient.addColorStop(1, "violet");
ctx.fillStyle = gradient;

// y設置2,是因為火狐瀏覽器下效果有異常...
ctx.fillText("這是測試", canvas.width / 2, 2);
// 插入
document.body.appendChild(canvas);


像素點過多會卡頓,所以這里盡量用少的點去完成效果

獲取imageData,生成相關(guān) dom

const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
// 打印一下
console.log(imageData);


imageData包含三個屬性,data,width和height,data是一個一維數(shù)組,[[0-255], [0-255], [0-255], [0-255]],長度是4的倍數(shù),4個算一小組,相當于rgba,只不過透明度范圍也是0~255,width和height相當于長寬,像素點數(shù)量 = (高 寬) 4

{
  let i = 2000;
  const fragment = document.createDocumentFragment();
  while (i-- > 0) {
    fragment.appendChild(document.createElement("li"));
  }
  ul.appendChild(fragment);
}
let iLi = 0;
for (let column = 0; column < imageData.width; column++) {
  for (let row = 0; row < imageData.height; row++) {
    // 第幾個像素點起始位置,肯定是4的倍數(shù)
    const idx = ((row * imageData.width) + column) * 4;
    if (imageData.data[idx + 3] > 0) {
      const li = ul.children[iLi++];
      li.style.opacity = "1";
      // 觀察css你會發(fā)現(xiàn),所有顯示的點初始位置都是在中心
      li.style.transform = `translate(
        ${column * rectWidth}px,
        ${row * rectWidth}px)
        scale(1.5)`;
      // 這里 scale 完全是為了好看
      li.style.background =
        `rgba(${imageData.data[idx]},${imageData.data[idx + 1]},${imageData.data[idx + 2]},${imageData.data[idx + 3] / 255})`;
    }
  }
}
while (iLi < 2000) {
  const li = ul.children[iLi++];
  li.style.opacity = "0";
}

定時器比較簡單,就不寫了,具體可以看源碼。

注意的點,Chrome下有點卡頓,Safari和Firefox下沒有卡頓,原因未知。

預覽效果-本地Chrome下打開很卡,火狐、safari正常

圣誕樹

早先的時候是圣誕節(jié)的時候,看到各種用字符組成圣誕樹的形式,于是自己就去試了下,還是比較簡單的。

這段用的是項目里的js代碼,不過一看就是不可執(zhí)行的,因為我是按照空格分割的。

需要注意的點是:

因為是處理文件,所以我們需要借助 node

怎樣處理圖片,生成相應的代碼

如何讓切割后的代碼仍然可以執(zhí)行

對于上面的幾點,做以下分析:

關(guān)于第一點和第二點,和上面的例子一樣,我們還是需要 canvas,node 環(huán)境并沒有 canvas 這個 element,需要借助第三方的庫node-canvas(npm)
例子:


繪制好圖片,我們就能像上面一樣拿到需要的 ImageData,然后就是寫文件,基本上是非常簡單了,寫的時候考慮到 canvas 的API比較多,用了 typescript,不影響閱讀,都9102年了,你可以不用,你也應該全局裝以下typescript(畢竟如今typescript已經(jīng)成了社交語言,“哎呦,你也在用typescript的啊,我也在用呢~”)

先寫個簡單版本,用text格式,展示基本圖形
const fs = require("fs");
const path = require("path");
const { createCanvas, loadImage } = require("canvas");

const canvas = createCanvas(80, 80)
const ctx: CanvasRenderingContext2D = canvas.getContext("2d")

async function transform(input: string, output: string) {
  const image: ImageBitmap = await loadImage(input);

  ctx.drawImage(image, 0, 0, 80, 80);

  const imageData: ImageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
  const { width, height, data } = imageData;
  let outStr = "";

  for (let col = 0; col < height; col++) {
    for (let row = 0; row < width; row++) {
      const index = ((col * height) + row) * 4;
      const r = data[index];
      const g = data[index + 1];
      const b = data[index + 2];
      const a = data[index + 3];

      // “黑色”區(qū)間, 找的圖片不是完全黑色
      if (r < 100 && g < 100 && b < 100 && a === 255) {
        outStr += "+";
      } else {
        outStr += " ";
      }
    }

    outStr += "
";
  }

  console.log(outStr);
  fs.writeFileSync(output, outStr);
}

transform(path.join(__dirname, "../img/tree.jpg"), path.join(__dirname, "../outputs/demo2.txt"));

效果:

關(guān)于把js代碼切割成可執(zhí)行的樣子,這塊我想了很久,剛開始只是是想把js文件按空格切割成數(shù)組,給定一個初始的變量start,記錄到什么位置,因為一些變量名是不能分割,但js一些語法特性不好處理,比如說

function test() {
    return 
    function aa() {}
}

function test() {
    return function aa() {}
}

完全是兩個函數(shù),后面在網(wǎng)上看了下,發(fā)現(xiàn)了芋頭大大很久以前寫過一篇類似的,地址,有興趣的小伙伴可以看看,這塊不做過多說明,實現(xiàn)還是有點麻煩的

會動的字符

上面說了字符和圖片,自然而然的,下面說的應該就是視頻了。視頻的話,也是非常簡單的,因為視頻是由連續(xù)的圖片組成的,也就是不斷變化的圖片,就是所謂的“幀”。也就是,如果我們能拿到視頻所有定格的圖片,就能作出相應的動畫效果。

需要把視頻“拆成”圖片,需要借助第三方的工具,ffmpeg,功能比較強大,具體不做說明,需要安裝到全局,利用brew,運行brew install ffmpeg就好了(大概,我好像是這樣裝的233),windows用戶下載要配置環(huán)境變量之類的,自己查一下吧。

// 主要代碼
const mvPath = path.join(__dirname, "../mv/bad-apple.flv");
const imgPath = path.join(__dirname, "../img");

const setTime = (t: number) => new Promise((resolve) => {
  setTimeout(() => resolve(), t);
});

try {
  void async function main() {
    let img = fs.readdirSync(imgPath);
    let len = img.length;
    if (len <= 1) {
      await execSync(`cd ${imgPath} && ffmpeg -i ${mvPath} -f image2 -vf fps=fps=30 bad-%d.png`);
      img = fs.readdirSync(imgPath);
      len = img.length;
    }
    let start = 1;
    let count = len;

    (async function inter(i: number) {
      if (i < count) {
        await transform(path.join(__dirname, `../img/bad-${i}.png`));
        await setTime(33.33);
        await inter(++i);
      }
    })(start);
  }()
} catch (err) {
  console.log(err);
}


工具的配置非常多,文檔看起來也是很麻煩,有個 npm 包,node-fluent-ffmpeg,用著也還可以,我剛開始用了,但是感覺功能不能滿足,而且使用這個包的前提是你全局安裝了ffmpeg...

總結(jié)

GitHub源碼

這個我拖了比較久,有的東西有點記不清楚,可能有些東西表達的不好,說的不是很細,一些api的說明我都省略了,這些MDN上都有,就沒做過多說明,當然,你可以做些更有趣的事情,文檔,本來自己還想做些有趣的東西,但后面沒啥時間,就沒繼續(xù)做下去了,希望有興趣的朋友可以去嘗試一波,還是很有意思的。

就醬,感謝閱讀~

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/117273.html

相關(guān)文章

  • 慶祝新年?一顆誕樹?還是...

    摘要:關(guān)于節(jié)日圣誕節(jié),元旦,看大家情侶在朋友圈里發(fā)各種慶祝的或者祝福的話語,甚是感動,然后悄悄拉黑了。預覽效果本地下打開很卡,火狐正常圣誕樹早先的時候是圣誕節(jié)的時候,看到各種用字符組成圣誕樹的形式,于是自己就去試了下,還是比較簡單的。 關(guān)于節(jié)日 圣誕節(jié),元旦,看大家(情侶)在朋友圈里發(fā)各種慶祝的或者祝福的話語,甚是感動,然后悄悄拉黑了。作為單身狗,我們也有自己慶祝節(jié)日的方式,今天我們就來實現(xiàn)...

    k00baa 評論0 收藏0
  • 慶祝新年?一顆誕樹?還是...

    摘要:關(guān)于節(jié)日圣誕節(jié),元旦,看大家情侶在朋友圈里發(fā)各種慶祝的或者祝福的話語,甚是感動,然后悄悄拉黑了。預覽效果本地下打開很卡,火狐正常圣誕樹早先的時候是圣誕節(jié)的時候,看到各種用字符組成圣誕樹的形式,于是自己就去試了下,還是比較簡單的。 關(guān)于節(jié)日 圣誕節(jié),元旦,看大家(情侶)在朋友圈里發(fā)各種慶祝的或者祝福的話語,甚是感動,然后悄悄拉黑了。作為單身狗,我們也有自己慶祝節(jié)日的方式,今天我們就來實現(xiàn)...

    zhoutk 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<