브라우저 (또는 그래픽 카드)는 수학적 알고리즘을 적용하여 픽셀을 설정하기 만합니다.
결과는 HTML 캔버스가 각 픽셀의 상태를 유지하기 위해 유지하는 배킹 배열에 저장됩니다.
각 캔버스 픽셀은 캔버스 픽셀 배열에있는 4 개의 요소 집합으로 표현됩니다. 4 픽셀 세트는 R, G, B, A 값입니다. 그래서 하나의 적색 픽셀은 픽셀 배열의 4 개 요소의 집합으로 표현 될 것이다 :
pixelArray=[...255,0,0,255...] // where 255==red, 0==green, 0==blue, alpha==255
당신은 브라우저의 내부 픽셀 설정 알고리즘에 접근 할 수 없지만, 사용자가 설정 한 동일한 알고리즘을 실행할 수 있습니다 적절한 픽셀.
var width=500;
var height=500;
var pixels=new Array(width*height);
당신은 배열 요소를 얻을 수있는 모든 픽셀에 해당 :
당신이 가상의 그리드의 모든 픽셀을 나타내는 배열이 있다고 가정 : 여기 는 것을 수행하는 방법의 개요이다 var x=200;
var y=30;
var arrayElement=y*width+x;
당신을이 같은
function setPixel(x,y,colorObject){
pixels[y*width+x]=colorObject;
}
setPixel(100,50,{r:255,g:0,b:0,a:255});
당신은 어떤 [X, Y]의 화소 설정을 얻을 수 이런 :
function getPixel(x,y){
return(pixels[y*width+x]);
}
var theColor=getPixel(100,50);
는 그런 다음 픽셀을 설정할 수있는이 같은 어레이 픽셀 요소를 설정할 수
// Refer to: http://rosettacode.org/wiki/Bitmap/Bresenham's_line_algorithm#JavaScript
function bline(x0, y0, x1, y1) {
var dx = Math.abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
var dy = Math.abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
var err = (dx>dy ? dx : -dy)/2;
while (true) {
setPixel(x0,y0);
if (x0 === x1 && y0 === y1) break;
var e2 = err;
if (e2 > -dx) { err -= dy; x0 += sx; }
if (e2 < dy) { err += dx; y0 += sy; }
}
}
다른 html로 C : 이런 [X1, Y1]로 선분 접속점 [X0, Y0]에 anvas 경로 요소에는 경로를 따라 설정해야하는 각 [x, y] 픽셀을 계산하는 유사한 알고리즘이 있습니다.
html로 캔버스 커브 경로
각 곡선 경로 요소는 수학 식에 의해 정의된다. 이 방정식을 사용하여 간격을두고 오버 샘플링 값을 사용하여 각 [x, y]를 곡선을 따라 얻을 수 있습니다.
예를 들어, 수식 은 간격 (T)으로 이차 곡선을 따라 [x, y] 점을 가져옵니다. T는 0.00과 1.00 사이의 값이고 T == 0.00은 곡선의 시작점이고 T == 1.00은 곡선의 끝에 있습니다.
// Get [x,y] at interval T along a Quadratic Curve
var x = Math.pow(1-T,2) * startPt.x + 2 * (1-T) * T * controlPt.x + Math.pow(T,2) * endPt.x;
var y = Math.pow(1-T,2) * startPt.y + 2 * (1-T) * T * controlPt.y + Math.pow(T,2) * endPt.y;
사용자는 곡선을 따라서 간격 (T)을 오버 샘플링해야하거나 그 곡선을 따라 [X, y]는 점을 누락시킬 위험. 이는 선과 달리 곡선 공식이 균일 한 간격의 점을 가져 오지 않기 때문입니다. 다음은 0.00과 1.00 사이의 1000 T 웨이 포인트를 오버 샘플링하는 예제입니다. 다음
// Oversample T along a quadratic curve to be sure to catch all [x,y]
// Some pixels will harmlessly be set more than once,
// but it's likely that all desired pixels will be set
for(var i=0;i<1000;i++){
var T=i/1000;
var x = Math.pow(1-T,2) * startPt.x + 2 * (1-T) * T * controlPt.x + Math.pow(T,2) * endPt.x;
var y = Math.pow(1-T,2) * startPt.y + 2 * (1-T) * T * controlPt.y + Math.pow(T,2) * endPt.y;
setPixel(x,y,color);
}
을 수식 페치는 [X는 Y] 큐빅 베 지어 곡선을 따라 점이다. 다음
// De Casteljau's algorithm which calculates points along a cubic Bezier curve
function getCubicBezierXYatT(startPt,controlPt1,controlPt2,endPt,T){
var x=CubicN(T,startPt.x,controlPt1.x,controlPt2.x,endPt.x);
var y=CubicN(T,startPt.y,controlPt1.y,controlPt2.y,endPt.y);
return({x:x,y:y});
}
// cubic helper formula at T distance
function CubicN(T, a,b,c,d) {
var t2 = T * T;
var t3 = t2 * T;
return a + (-a * 3 + T * (3 * a - a * T)) * T
+ (3 * b + T * (-6 * b + b * 3 * T)) * T
+ (c * 3 - c * 3 * T) * t2
+ d * t3;
}
을 수식 페치는 [X는 Y] 소정 각도 라디안에서 아크 따른 점이다. globalAlpha 설정 html로 캔버스 운영자
// Trigonometry to calculate [x,y] at a specified angle
function get ArcXYatRadianAngle(centerX,centerY,radius,radianAngle){
var x=centerX+radius*Math.cos(radianAngle);
var y=centerY+radius*Math.sin(radianAngle);
}
은 0과 255 (완전 투명하고 완전 불투명 사이) 사이에서 원하는 값으로 모든 화소의 alpha
요소를 설정하는 것만 큼 단순하다.
심지어 globalCompsiteOperation도 비교적 간단합니다.
- 픽셀 배열에 적용 할 새 [x, y] 픽셀 값을 플롯합니다.
- 픽셀 배열에서 기존 픽셀 값을 읽습니다.
- 이 옵션의 사용 원하는 합성 효과를 적용 :
- 는
- 0 (이 투명하게)
에 픽셀의 알파 값을 설정 새로운 픽셀 값
- 로 덮어 쓰기 기존의 픽셀 값을 유지
힌트 : 기존 픽셀과 교체 픽셀을 비교하는이 방법을 사용하여 픽셀에 블렌딩 필터를 적용 할 수 있습니다! ;-)
클리핑 클리핑 지정 클리핑 영역 내에서만 새 픽셀 값을 적용해야한다는 점에서 반드시 어렵습니다. 이미 (이하 "도면 배열"호출)
가에 제 2 픽셀 배열을 만들기 제 1 화소 배열을
- : 당신은 허용 도면 영역을 결정하기 위해 미적분을 사용할 수 있지만 더 간단이하는 것 클리핑 패스로 정의 된 픽셀을 유지합니다 (이 두 번째 배열을 "클리핑 배열"이라고 함).
- 새 픽셀을 드로잉 배열에 적용하려면 먼저 클리핑 배열을 참조하십시오. 클리핑 배열 픽셀이 SET이면 도면 배열에 픽셀을 설정합니다. 클리핑 배열 픽셀이 UNSET 인 경우 드로잉 배열에서 해당 픽셀을 변경하지 마십시오.
휴! 글쎄 그것은 당신을 시작해야합니다 ... 당신의 프로젝트에 행운을 빌어 요!
+1 좋은 답변 @Ken Fyrstenberg - 오신 것을 환영합니다! 안녕하세요, 귀하의 프로필에 링크 된 미술 작품을 확인했습니다 ... 인상적입니다! 내 작품이 스틱 인물보다 더 좋아질 수 있었으면 좋겠지 만 나는 그렇게 축복받은 사람이 아니 었습니다. – markE
한 캔버스의 픽셀 데이터를 다른 캔버스에 보내려고했습니다. 그래서 이것은 HTML 캔버스와 연관된 프레임 버퍼가 없다는 것을 이해합니다. 프레임 버퍼가 필요하다면 X 윈도우 시스템과 같은 디스플레이 시스템의 버퍼를 사용해야 할 것입니다. 서버에서 '줄'과 같은 신호를 내보내고 클라이언트에서 다시 그려서 제대로 작동합니다. 그러나 비 벡터 그래픽 (예를 들어 jpeg 이미지)이 포함 된 캔버스에는 동일한 작업을 수행 할 수 없습니다. 그럴 경우 프레임 버퍼를 갖는 것이 유일한 방법입니다. – lonesword
질문 : 노드 버퍼 위에 프레임 버퍼를 구현하면 성능이 크게 저하됩니까? 또한 오프 스크린 캔버스를 사용하면 화면상의 캔버스를 사용하는 것보다 향상된 성능을 제공합니까? (실제로 화면에 그릴 필요가 없기 때문에). 좋은 답변을 주셔서 대단히 감사합니다. – lonesword