Canvas에는 drawImage()(w3c)라는 매우 강력한 API가 있습니다.
주요 기능은 그림, 비디오 및 기타 캔버스를 그리는 것입니다.
질문:그는 감탄하며 그곳에 왔지만 고개를 숙였을 때 땅에 큰 구멍이 있는 것을 보았다.
문제는 이렇습니다. w3c의 소개와 매우 설득력 있고 가르치는 데모를 읽은 후, 진정한 지식을 얻기 위해 연습해야 한다는 생각을 바탕으로 한번 시도해 보기로 결정했습니다. 시도해 보세요~
나는 조립 라인 프로젝트에 따라 다음과 같은 기본 작업을 계획했습니다.
1. 캔버스 태그+ID
<canvas id=canvas1></canvas>
2. 캔버스 가져오기 + 너비와 높이 설정
var cav1 = document.getElementById('canvas1'), wWidth = 800, wHeight = 600; cav1.width = wWidth = wHeight;3. getContext('2d')는 캔버스를 준비합니다.
var ctx1 = cav1.getContext('2d');4. 새로운 Image() 객체를 생성하고 내가 좋아하는 사진의 속성을 부여하세요... (너무 많이 생각하지 마세요)
var bgImg = new Image();bgImg.src = '이미지/배경.jpg';
5. 드디어 그릴 차례입니다. 나는 신나게 다음 코드를 작성했습니다.
ctx1.drawImage(bgImg,0,0,wWidth,wHeight);
당황해서 브라우저에서 F5를 눌렀습니다.
그러자 죽은 침묵이 흘렀다...
코드를 잘못 쓴 줄 알고 다시 가서 확인해 보니 맞더군요.
w3c의 주요 속성 이름과 메소드를 복사하고 다시 확인하십시오.
사진을 출력하면 이런 사진도 있어요!
나중에 W3C 사례를 관찰했을 때 내 코드와 다른 점은 이미지가 HTML로 되어 있다는 점이었습니다.
그런 다음 HTML에 그림을 삽입하는 방법을 배웠습니다.
<img src=./images/Background.jpg id=imgs style=display:none></img>
그리고 getElementById를 사용하여 이 요소를 가져옵니다.
var bgImg = document.getElementById('imgs')도면을 다시 실행하면 작동했습니다.
그는 실제로 할 수 있습니다!
슬프게도 물리적인 것이어야만 할까요? 그냥 캔버스 태그 앞에 놓는거 아닌가요? Node.js 로딩에도 엔터티가 있고 저는 여전히 new를 사용합니다. 실제 사람들과 얼마나 다른가요!
그렇죠 그냥 앞쪽에 넣는거 아닌가요? 이는 순서 문제와 관련이 있습니다!
js에 로드된 이미지가 도면 앞에 배치되는 것은 사실이나, 이미지를 로드하는데 시간이 좀 걸립니다. 이미지 버퍼링을 위한 시간이 필요합니다. 이미지를 그리기 전에 이미지가 성공적으로 로드될 때까지 기다리십시오. 이미지가 로드되기 전에 이미지를 사용하는 경우 drawImage 메서드가 호출되지 않습니다. 그리기가 실패합니다. 알겠어요!
img 태그에 있는 사진을 로드하는 데 시간이 걸리지 않는다고 주장하는 사람들이 있나요? 현재 drawImage는 제한되지 않나요? ! 하지만 js 시작 부분에 있는 window.onload를 무시하지 마세요. 이미지가 느리게 로드되더라도 이미지 태그의 순서가 캔버스 태그 다음인데 window.onload가 이를 덮고 있어도 이미지가 로드될 수 없습니다. 로드되고 drawImage가 실행될 가능성은 없습니다. 그렇죠?
대략적인 순서는 이렇습니다.
<img src=>window.onload = function(){ drawImage}이미지가 html 구조에 삽입되지 않았다면 이 제한은 나의 부주의로 인해 우회되었을 것입니다:
리소스 요청으로 인해 js에 사진이 로딩되면 당연히 사진 로딩 시간이 발생하게 됩니다.
하지만 제한이 없기 때문에 대부분의 경우 이미지가 로드되지 않은 상태에서 drawImage가 호출되며 이 메서드는 작동하지 않습니다.
해결하다:그렇다면 이미지 로딩 순서로 인해 drawImage 그리기가 실패하는 문제를 해결할 수 있는 좋은 방법이 있을까요?
다음 세 가지 방법을 정리해 보았습니다.
1. 태그+window.onload <img src=>window.onload = function(){ context.drawImage()}이 접근 방식의 핵심 솔루션은 이미지와 drawImage를 별도로 로드하는 onload로, 로드가 완료된 후 드로잉이 사용되도록 보장합니다.
1-2. 태그를 나중에 삽입하시겠습니까? 가능합니까?한 가지 상황은 스크린샷 기능을 사용할 때 drawImage도 사용할 수 있으며 스크린샷은 기존 이미지의 스크린샷을 찍는 것이 아니라 이미지의 주소를 매개변수로 사용하는 것입니다.
이런 종류의 작업에는 js가 img를 만들고 주소를 할당한 다음 이미지를 생성하고 스크린샷을 찍어야 한다고 생각합니다.
var myImg = document.createElement('img');myImg.src = '///';document.body.appendChild(myImg);ctx1.drawImage(myImg,0,0,wWidth,wHeight);추가 태그를 추가하고 싶지 않으신가요? 새 이미지 개체를 만들려면 아래와 같이 js를 사용해야 합니까?
var bgImg = new Image();bgImg.src = '이미지/배경.jpg';
앞에서 언급했듯이 new Image()를 사용하여 생성된 이러한 종류의 이미지는 이미지를 버퍼링하는 데 시간이 필요합니다. 이미지를 그리기 전에 이미지가 성공적으로 로드될 때까지 기다리십시오.
이미지 객체가 준비되었지만 이미지가 실제로 로드되는 시점을 어떻게 알 수 있나요?
js 작업이 실행되는 동안 실행 시간이 너무 가까워졌다고 생각하시나요? 저를 혼자 데리고 나가서 다시 대기열에 추가한 다음 나중에 다시 실행할 수 있나요?
2. 타이머 비동기 구현 setTimeout(function(){ ctx1.drawImage(bgImg,0,0,wWidth,wHeight);},10)여기에 익숙한 1000이나 0 대신 10을 쓰는 것이 지연되는 이유는 무엇입니까?
내 특정 Wi-Fi 환경과 특정 데스크톱 컴퓨터의 테스트에서 0이 나오지 않는 것과 달리 이미지가 로드된 후에 10이 나올 수 있고 1000처럼 반나절을 기다리고 싶지 않기 때문입니다.
하지만 사진을 더 큰 사진으로 변경한다고 상상해 보세요. 이 10이 여전히 적용되나요? Wi-Fi를 2G로 변경해도 이 10이 계속 적용되나요?
따라서 타이머의 단점은 시간이 지난 후에도 이미지가 로드된다는 보장이 없으며, 네트워크가 빠르지 않으면 여전히 중단된다는 점입니다.
3. img.onloadwindow.onload는 로딩 완료를 직접 모니터링할 수 없나요?
img의 로딩 이벤트를 사용하여 이미지가 성공적으로 로딩되었는지 모니터링한 다음 캔버스의 그리기 효과를 실행하는 것이 더 안정적입니다.
bgImg.onload = function(){ console.log('이미지가 성공적으로 로드되었습니다'); console.log(this)(bgImg,0,0,wWidth,wHeight);실제로 이 세 가지 방법은 모두 이미지를 먼저 로드한다는 동일한 핵심을 가지고 있습니다. 즉, 이미지를 미리 로드하는 것입니다. 그러나 캐시된 이미지의 경우 이미지 사전 로드는 페이지가 새로 고쳐지지 않을 때 캐시된 이미지를 모니터링하는 문제도 해결해야 합니다.
또 다른 문제를 발견했습니다. . . . 먼저, 배경 그림을 완성한 후의 모습은 다음과 같습니다.
그러다가 드디어 배경사진이 나왔고, 즐겁게 계속했어요.
그래서 바로 빨간색 선을 그어 안보이게 하기 위해 너비도 20으로 늘렸습니다.
bgImg.onload = function(){ ctx1.drawImage(bgImg,0,0,wWidth,wHeight); } /* 다음과 같이 빨간색 선을 그립니다. */ ctx1.beginPath(); ctx1.lineTo(10,wHeight-100);ctx1.lineWidth = 20; ctx1.StrokeStyle = '빨간색' ctx1.closePath();그런데 F5를 눌러도 아무런 변화가 없고, 여전히 빨간색 선이 보이지 않습니다.
한참을 검색하다가 배경이미지를 끄기 전까지는 안보이네요:
아, 알고보니 배경화면에 가려졌네요!
그런데 왜?
나는 두 가지 가능성이 있다고 생각한다.
1. 계층 문제
2. 순서 문제
1에 관해서는 배경 이미지가 빨간색 선을 덮는 CSS의 z-index와 같은 느낌입니다. 배경 이미지의 레벨이 빨간색 선보다 높은 것은 아닐까요?
나는 이 가설을 테스트할 방법이 없었기 때문에 두 번째 공개 가능성을 포기했습니다.
그런데 왜 배경 이미지가 맨 위에 있는 걸까요? 배경이미지를 나중에 그려서 그런걸까요?
이는 실행 순서를 관찰하기 위해 console.log() 인쇄를 통해 가장 쉽게 관찰할 수 있습니다.
범인은 onload 콜백인 것으로 밝혀졌습니다. 타이머와 마찬가지로 비동기 작업입니다. 당연하게도 동기화 작업보다 뒤처지는 순위입니다(아래 선 그리기).
그래서 onload는 좋은 해결책인 것 같지만 여기서 단점도 드러납니다.
아주 좋습니다. 약속 학습 계획은 최대한 빨리 일정에 넣어야 할 것 같습니다! 하하하
위의 내용은 이 기사의 전체 내용입니다. 모든 분들의 학습에 도움이 되기를 바랍니다. 또한 모든 분들이 VeVb Wulin Network를 지지해 주시길 바랍니다.