亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何使用 HTML Canvas 創建像素完美的剪切區域?

如何使用 HTML Canvas 創建像素完美的剪切區域?

互換的青春 2023-10-20 15:33:33
對于我的應用程序,我試圖將所有內容移動到任意垂直接縫線的右側,向左移動一個像素。目前我正在使用 O(n^2) for 循環并手動編輯像素數據,但不幸的是這太慢了。我有以下想法:將原始圖像繪制到畫布上,創建接縫Path2D,在接縫右側創建所有內容的剪切區域,然后將該區域向左繪制一個像素。不幸的是,這種剪切似乎不是像素完美的,而是在圖像中引入了抗鋸齒功能。這是演示該問題的代碼示例:function getRandomInt(min, max) {  min = Math.ceil(min);  max = Math.floor(max);  return Math.floor(Math.random() * (max - min) + min);}const canvas = document.getElementById('canvas');const ctx = canvas.getContext('2d');ctx.imageSmoothingEnabled = false;ctx.beginPath();ctx.strokeStyle = "#00000000";ctx.moveTo(50, 0);for (let i = 1; i < 200; i++) {  ctx.lineTo(50 + getRandomInt(-1, 2), i);}ctx.lineTo(500, 200);ctx.lineTo(500, 0);ctx.lineTo(50, 0);ctx.stroke();ctx.clip();ctx.fillStyle = 'blue';ctx.fillRect(0, 0, canvas.width, canvas.height);ctx.fillStyle = 'orange';ctx.fillRect(0, 0, 100, 100);<canvas id="canvas" width="300" height="300">正如您所看到的,接縫在切口中引入了抗鋸齒功能。有沒有辦法創建像素完美且不抗鋸齒的剪切區域?我還嘗試添加image-rendering: pixelated;到樣式表中,雖然它似乎有一點幫助,但仍然在進行抗鋸齒處理。
查看完整描述

1 回答

?
九州編程

TA貢獻1785條經驗 獲得超4個贊

問題是您在每個針跡之間繪制斜線。

讓事情變得更加戲劇化,這就是你正在做的事情。

function getRandomInt(min, max) {

? min = Math.ceil(min);

? max = Math.floor(max);

? return Math.floor(Math.random() * (max - min) + min);

}


const canvas = document.getElementById('canvas');

const ctx = canvas.getContext('2d');


ctx.imageSmoothingEnabled = false;

ctx.beginPath();

ctx.strokeStyle = "#00000000";


ctx.moveTo(50, 0);

for (let i = 1; i < 200; i+= 10) {

? ctx.lineTo(50 + getRandomInt(-5, 10), i);

}

ctx.lineTo(500, 200);

ctx.lineTo(500, 0);

ctx.lineTo(50, 0);

ctx.stroke();

ctx.clip();


ctx.fillStyle = 'blue';

ctx.fillRect(0, 0, canvas.width, canvas.height);

ctx.fillStyle = 'orange';

ctx.fillRect(0, 0, 100, 100);

<canvas id="canvas" width="300" height="300">

當渲染這些斜線時,瀏覽器將使用抗鋸齒來平滑線條,因為這通常是人們想要的。

但在您的情況下,您想要像素完美,因此解決方案是以階梯形狀圍繞像素邊界行走。這可以通過從最后一個 y 坐標到下一個 y 坐標繪制一條垂直線,然后繪制水平線來實現。

function getRandomInt(min, max) {

? min = Math.ceil(min);

? max = Math.floor(max);

? return Math.floor(Math.random() * (max - min) + min);

}


const canvas = document.getElementById('canvas');

const ctx = canvas.getContext('2d');


// for high-res monitors

{

? const dPR = window.devicePixelRatio;

? canvas.width = canvas.height *= dPR

? ctx.scale( dPR, dPR );

}


ctx.beginPath();

ctx.strokeStyle = "#00000000";


ctx.moveTo(50, 0);

for (let i = 1; i < 200; i++) {

? let rand = getRandomInt( -1, 2 );

? ctx.lineTo( 50 + rand, i - 1 ); // from last y move horizontally

? ctx.lineTo( 50 + rand, i ); // move vertically

}

ctx.lineTo(500, 200);

ctx.lineTo(500, 0);

ctx.lineTo(50, 0);

ctx.clip();


ctx.fillStyle = 'blue';

ctx.fillRect(0, 0, canvas.width, canvas.height);

ctx.fillStyle = 'orange';

ctx.fillRect(0, 0, 100, 100);

canvas { width: 300px; height: 300px }

<canvas id="canvas" width="300" height="300">

再次以更戲劇化的方式:

function getRandomInt(min, max) {

? min = Math.ceil(min);

? max = Math.floor(max);

? return Math.floor(Math.random() * (max - min) + min);

}


const canvas = document.getElementById('canvas');

const ctx = canvas.getContext('2d');


ctx.imageSmoothingEnabled = false;

ctx.beginPath();

ctx.strokeStyle = "#00000000";


ctx.moveTo(50, 0);

for (let i = 1; i < 200; i+= 10) {

? const rand = getRandomInt(-5, 10);

? ctx.lineTo(50 + rand, i-10);

? ctx.lineTo(50 + rand, i);

}

ctx.lineTo(500, 200);

ctx.lineTo(500, 0);

ctx.lineTo(50, 0);

ctx.stroke();

ctx.clip();


ctx.fillStyle = 'blue';

ctx.fillRect(0, 0, canvas.width, canvas.height);

ctx.fillStyle = 'orange';

ctx.fillRect(0, 0, 100, 100);

<canvas id="canvas" width="300" height="300">


查看完整回答
反對 回復 2023-10-20
  • 1 回答
  • 0 關注
  • 117 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號