Canvas имеет очень мощный API под названием drawImage() (w3c):
Его основная функция — рисовать картинки, видео и даже другие полотна.
вопрос:Он подошел туда в восхищении, но промахнулся. Когда он опустил голову, он увидел большую дыру на земле.
Дело в том, что после того, как я прочитал введение в w3c и очень убедительную и обучающую демонстрацию, я решил попробовать, основываясь на идее попрактиковаться, чтобы получить истинные знания. Неважно, буду ли я это делать. попробуй~
Согласно проекту сборочной линии я определил следующие основные задачи:
1. тег холста+идентификатор
<canvas id=canvas1></canvas>
2. Получите холст + установите ширину и высоту.
вар cav1 = document.getElementById('canvas1'), wWidth = 800, wHeight = 600; cav1.width = wWidth; cav1.height = wHeight;3. getContext('2d') подготавливает холст.
var ctx1 = cav1.getContext('2d');4. Создайте новый объект Image() и присвойте ему атрибуты картинок, которые мне нравятся... (не думайте слишком много)
вар bgImg = новое изображение (); bgImg.src = 'images/background.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')Повторное выполнение рисунка сработало.
Он действительно может!
Я с грустью думаю, а должно ли это быть физическим? Разве он не помещен перед тегом Canvas? js в загрузке тоже есть сущности, и я до сих пор использую новые, которые сильно отличаются от реальных людей!
Правильно, разве его просто не ставят спереди? Это связано с проблемой последовательности!
Это правда, что изображение, загруженное в js, размещается перед рисунком, но загрузка изображения займет некоторое время. Необходимо дать время на буферизацию изображения. Подождите, пока изображение успешно загрузится, прежде чем вы сможете его нарисовать. Метод drawImage не будет вызываться, если изображение используется до его загрузки. Рисование не удастся. Я понимаю!
Некоторые люди утверждают, что изображения в тегах img не требуют времени для загрузки? В настоящее время drawImage не ограничен? ! Но не игнорируйте window.onload в начале js. Даже если изображение загружается медленно, даже если порядок тегов изображения находится после тега холста, но у меня есть window.onload, закрывающий его, мое изображение не может быть загружено. загрузится, и у вашего drawImage не будет шансов, верно?
Примерный порядок такой:
<img src=>window.onload = function(){ drawImage}Если бы изображение не было вставлено в html-структуру, это ограничение было бы обойдено по моей невнимательности:
В качестве запроса ресурса, когда изображение загружается в js, естественно, будет время загрузки изображения.
Но поскольку ограничений нет, в большинстве случаев drawImage вызывается, когда изображение не загружено, и этот метод не будет работать.
решать:Итак, есть ли хороший способ решить проблему сбоя рисования drawImage из-за последовательности загрузки изображения?
Я обобщил следующие три метода:
1. тег+window.onload <img src=>window.onload = function(){ context.drawImage()}Основным решением этого подхода является onload, который загружает изображение и drawImage отдельно. Сначала загружается img, чтобы гарантировать использование рисунка после завершения загрузки.
1–2. Вставить теги позже? Возможно ли это?Одна из ситуаций заключается в том, что при использовании функции скриншота вы также можете использовать drawImage, и снимок экрана не делает снимок экрана вашего собственного существующего изображения, а использует адрес изображения в качестве параметра.
Я думаю, что для такого рода вещей требуется, чтобы js создал img и присвоил ему адрес, затем сгенерировал изображение и сделал снимок экрана.
var myImg = document.createElement('img');myImg.src = '///';document.body.appendChild(myImg);ctx1.drawImage(myImg,0,0,wWidth,wHeight);Не хотите добавлять лишние теги? Нужно ли мне использовать js, как показано ниже, для создания нового объекта изображения?
вар bgImg = новое изображение (); bgImg.src = 'images/background.jpg';
Как упоминалось ранее, изображения такого типа, созданные с помощью new Image(), требуют времени для буферизации изображения. Подождите, пока изображение успешно загрузится, прежде чем вы сможете его нарисовать.
Объект изображения готов, но как узнать, что изображение действительно загружено?
Пока выполняется задача js, не думаете ли вы, что я слишком близок к вашему времени выполнения. Можете ли вы вывести меня одного и снова поставить в очередь, а затем выполнить его еще раз позже?
2. Асинхронная реализация таймера setTimeout(function(){ ctx1.drawImage(bgImg,0,0,wWidth,wHeight);},10)Почему здесь задержка с написанием 10 вместо привычных 1000 или 0?
Потому что при тестировании моей конкретной среды Wi-Fi и конкретного настольного компьютера 10 может просто выйти после загрузки изображения, в отличие от 0, который не выходит, и я не хочу ждать полдня, как 1000.
Но представьте, если вы измените картинку на большую, будет ли эта 10 по-прежнему актуальна? Будет ли эта 10 действовать, если Wi-Fi будет изменен на 2g?
Поэтому недостатком таймера является то, что нет гарантии, что изображение загрузится по истечении времени, и оно все равно зависнет, если сеть не быстрая.
3. img.onloadwindow.onload подсказывает нам, нельзя ли напрямую контролировать завершение загрузки?
Используйте событие загрузки img для отслеживания успешной загрузки изображения, а затем выполните эффект рисования холста. Этот метод более надежен.
bgImg.onload = function(){ console.log('Изображение успешно загружено'); console.log(this); ctx1.drawImage(bgImg,0,0,wWidth,wHeight);Фактически, все эти три метода имеют одно и то же ядро, которое заключается в том, чтобы сначала загрузить изображение. То есть предварительная загрузка изображения. Но для кэшированных изображений предварительная загрузка изображений также должна решить проблему мониторинга кэшированных изображений, когда страница не обновляется.
Обнаружил еще одну проблему. . . . Во-первых, вот как выглядит фоновая картина после ее завершения.
Затем наконец появилась фоновая картинка, и я счастливо продолжил.
Поэтому я сразу нарисовал красную линию, чтобы ее не видеть, я еще увеличил ширину до 20:
bgImg.onload = function(){ ctx1.drawImage(bgImg,0,0,wWidth,wHeight } /* Нарисуйте красную линию следующим образом: */ ctx1.beginPath(); ctx1.moveTo(10,wHeight); ctx1.lineTo (10,wHeight-100); ctx1.lineWidth = 20; ctx1.strokeStyle = 'красный'; ctx1.stroke(); ctx1.closePath();Но когда я нажимаю F5, изменений все равно нет, и я все еще не вижу красной линии.
После долгих поисков так и не увидел, пока не отключил фоновое изображение:
Ах, оказывается, его закрыло фоновое изображение!
Но почему?
Я думаю, есть два варианта
1. Проблемы иерархии
2. Проблемы с последовательностью
Что касается 1, то это похоже на z-индекс CSS, где фоновое изображение закрывает красную линию. Может ли быть так, что уровень фонового изображения выше красной линии?
У меня не было возможности проверить эту гипотезу, поэтому я отказался от второго возможного открытия.
Но почему фоновое изображение находится вверху? Это потому, что фоновое изображение рисуется позже?
Это легче всего наблюдать с помощью печати console.log() для наблюдения за последовательностью выполнения.
Оказывается, виноват обратный вызов при загрузке. Как и таймер, это асинхронная задача. Естественно, она стоит позади задачи синхронизации (рисуем линии ниже).
Таким образом, onload кажется хорошим решением, но здесь также раскрываются его недостатки.
Очень хорошо, кажется, что обещанный план обучения следует включить в расписание как можно скорее! Ха-ха-ха
Выше приведено все содержание этой статьи. Я надеюсь, что она будет полезна для изучения всеми. Я также надеюсь, что все поддержат сеть VeVb Wulin.