JavaScript를 사용하여 유사한 행렬의 가상 배경 만들기
20821 단어 funvirtualbackgroundjavascript
현재의 가상 환경에서 나는 매우 멋있는 일은 나의 OBS 행렬과 유사한 가상 배경을 설정하는 것이라고 생각한다.내가 첫 번째 영화를 보고 프로그래밍을 시작한 이래로 (이 두 영화는 모두 아주 오래된 일이다.) 나는 이런 매트릭스 효과를 스스로 실현하고 싶어서 해 보기로 결정했다.
나는 자바스크립트를 나의 실현 언어로 선택했다. 왜냐하면 가시화 결과를 얻기 쉽기 때문이다. 나의 자바스크립트는 매우 낡아서 약간 복습해야 한다.
계속 읽지 않으려면 public Git Repository 로 이동하여 결과를 볼 수 있습니다.
첫 번째 시도: HTML 요소
나의 첫 번째 시도는 전혀 성능적인 고려가 없었고, 단지 자바스크립트의 애니메이션 기능을 이용하여 실험과 학습의 공간을 주었다.
나는 첫 번째 버전을 보완하지 못했다. 그것은 진실하고 거칠고 추악한 것이다. 나는 구글에서 검색, 시도, 탐색을 해서 매우 기쁘다.
첫 번째 시도
주요 문제 중 하나는 HTML 요소를 사용하여 입자 애니메이션을 설정하는 것입니다.이것은 매우 비싼 계산이지 좋은 선택이 아니다.하지만 이것은 나에게 좋은 첫걸음이다. 왜냐하면 나는 문제 분야와 언어에 관한 지식을 많이 배웠기 때문이다.
두 번째 시도: 캔버스 입자
다음 단계는 Canvas 요소와 2D 컨텍스트를 사용하는 것입니다.캔버스를 사용하면 HTML 요소와 모든 비용을 처리하지 않고... 캔버스에 직접 그릴 수 있습니다.
여러 MatrixChar 객체를 포함할 수 있는 클래스 MatrixRow를 만들었습니다. 각 객체는 직접 그리거나 구성할 수 있습니다.모든 Matrix Chars는 100% 불투명도로 시작하여 시간이 지날수록 희미해진다.
이 기술의 성능이 훨씬 좋아서 나는 크기, 속도 등 방면에서 임의화를 진행하였는데 결과가 매우 좋다.
function render(time) {
context.fillStyle="#000000";
context.fillRect(0, 0, wi, hi);
matrixRows.forEach(mRow => {
mRow.draw(context, time);
});
matrixRows = matrixRows.filter(elem => {return elem.chars.length > 0 || elem.curY < hi});
if ( time - prev > 50 && matrixRows.length < maxRows ) {
prev = time;
matrixRows.push(new MatrixRow(Math.random()*wi-10));
}
requestAnimationFrame(render);
}
초 Attmept그래서 사실 나는 입자계통해를 선택했다.문제는 입자(= 매트릭스 샤르)를 많이 처리해야 한다는 것이다. 때로는 한 번에 15000개를 처리해야 한다.
활약이 그다지 뛰어나지 않다.이것도 아마도 내 쪽에서 가장 좋은 실현이 아니기 때문일 것이다. 나는'진실'입자 시스템의 실현 방식이 다르다는 것을 안다.마찬가지로 메모리 라이브러리에서 녹슬고 불완전한 버전을 찾을 수 있다. 그럼에도 불구하고 그것은 나에게 내가 어디로 가고 싶은지에 대한 많은 지식을 가르쳐 주었다.
그 외에 결과가 완전히 매트릭스 효과와 같지는 않다.
세 번째 시도: 화포층 담입 담출
나의 세 번째 시도는 친애하는 친구 벤의 계발을 받은 것이다. 그는 나에게 계속 다른 불투명도로 모든 약간 보이는 문자를 그리지 말라고 건의했다. 나는 단지 새로운 Y 위치에서 모든 문자의 첫 번째'명중'을 그릴 수 있을 뿐, 매번 전체 장면에 투명한 검은색 직사각형을 그릴 수 있을 뿐이다.
"새"캐릭터가 가장 밝습니다. 장면을 그릴 때마다 이전 캐릭터에 검은색이 추가됩니다.
이렇게 하면 나는 유사한 효과에 도달할 수 있지만, 필요한 계산의 일부분만 진행할 수 있다.
나는 실제 매트릭스 효과처럼 보이기 위해 무대를 울타리화했다.문자는 격자에만 나타나서 중첩을 방지합니다.
function initCanvas(stage) {
stage.width = wi;
stage.height = hi;
gridHorizontal = Math.floor(wi/(fontSize-6));
gridVertical = Math.floor(hi/(fontSize));
context.fillStyle="#000000";
context.fillRect(0, 0, wi, hi);
}
function initChar() {
var char = {
x: (Math.floor(Math.random()*gridHorizontal)),
y: 0,
tickTime: Math.random()*50+50,
lastTick: performance.now(),
char: getRandomHexChar()
}
return char;
}
애니메이션을 더욱 재미있게 하기 위해 제가 하는 또 다른 일은 무작위로 그려진 문자의 밝기를 늘리는 것입니다.function addBrightness( rgb, brightness ) {
var multiplier = (100+brightness)/100;
var result = {};
result.r = rgb.r * multiplier;
result.g = rgb.g * multiplier;
result.b = rgb.b * multiplier;
return result;
}
추적할 문자 그룹을 관리하는 매우 경제적인 방법을 찾았습니다. 매번 보이는 문자 (Y가 무대 높이보다 낮음) 로 새로운 그룹을 만드는 것이 아니라 그룹을 다시 구성하여 유효한 문자를 위로 이동하고 그룹에 남은 요소를 차단하는 것입니다.var iOut = 0;
for ( var i = 0; i < chars.length; i++ ) {
var c = chars[i];
if ( c.y < gridVertical ) {
chars[iOut++] = c;
}
...
}
chars.length = iOut;
이것은 JavaScript에서 가능합니다. - 다른 언어에서는 그룹의 길이를 조작하기 어려울 수 있습니다.)최종 렌더링 방법은 다음과 같습니다.
function render(time) {
// Draw a transparent, black rect over everything
// But not each time
if ( time - prev > 50 ) {
context.fillStyle="rgba(0,0,0,"+alphaMask+")";
context.fillRect(0, 0, wi, hi);
prev = time;
}
// Setup Context Font-Style
context.font = 'bold 20px Consolas';
context.textAlign = 'center';
context.textBaseline = 'middle';
var iOut = 0;
for ( var i = 0; i < chars.length; i++ ) {
var c = chars[i];
if ( c.y < gridVertical ) { // If Char is still visible
chars[iOut++] = c; // put it further-up in the array
// Add a bit more random brightness to the char
var color = addBrightness({r: 100, g:200, b:100}, Math.random()*70);
context.fillStyle = "rgb("+color.r+","+color.g+","+color.b+")";
context.fillText(c.char, c.x*(fontSize-6), c.y*(fontSize));
// Only move one y-field down if the randomized TickTime is reached
if ( time - c.lastTick > c.tickTime) {
c.y++;
c.lastTick = time;
// New y-field means new Char, too
c.char = getRandomHexChar();
}
}
}
chars.length = iOut; // Adjust array to new length.
//Every visible char is moved to a point before this, the rest is cut off
var newChars = 0;
while (chars.length < maxRunningChars && newChars < 3) {
chars.push(initChar());
newChars++;
}
requestAnimationFrame(render);
}
다시 한 번, 랜덤화를 많이 추가했습니다. 저는 maxRunningChars의 제한도 포함했습니다.그러나 나는 현재의 최종 결과에 대해 매우 만족한다.
세 번 시도
OBS에 통합
OBS에서 가장 멋진 점은 브라우저 소스를 추가할 수 있다는 것입니다.그것이 있으면 나는 나의 Matrix 사이트를 직접 무대 위에 놓을 수 있다.
이것이 바로 시도 3의 실제 효과이다.
Reference
이 문제에 관하여(JavaScript를 사용하여 유사한 행렬의 가상 배경 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/pesse/creating-a-matrix-like-virtual-background-with-javascript-1boo텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)