HTML / Javascript Canvas Функция drawImg

Я пытаюсь отразить часть изображения на холсте ниже точно такого же размера на основе фиксированных значений. Например, представьте ему изображение карты и отразите его внизу в том же месте и того же размера, что и здание на этом исходном изображении карты. Однако по какой-то неизвестной причине он каждый раз меняет размер зеркального раздела? Единственное исправление ошибки - применить множитель ко всем переменным "d" в функции рисования изображения, как показано здесь: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage

Есть идеи, почему это так?

Код (без множителя, при необходимости доступен мультипликатор):

<!DOCTYPE html>
<html>
<body>

<img id = "scream" src = "image1.jpg" alt = "The Scream" width = "100%" height = "100%">
<!--<canvas id = "myCanvas" style = "border:1px solid #d3d3d3;">-->
Your browser does not support the HTML5 canvas tag.

<script>
document.getElementById("scream").onload = function() {
    var c = document.createElement('canvas');
    var imgData = document.getElementById("scream");
    c.width = imgData.width;
    c.height = imgData.height;
    var body = document.getElementsByTagName("body")[0];
    body.appendChild(c);
    var ctx = c.getContext("2d");
    var img = document.getElementById("scream");
    console.info(img);
    //ctx.drawImage(img, 0, 0);
    //ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
    ctx.drawImage(img, 200, 200, 100, 143, 200, 200, 100*1.87, 143*1.87);
    //console.info(ctx);
};
</script>

<p><strong>Note:</strong> The canvas tag is not supported in Internet
Explorer 8 and earlier versions.</p>

</body>
</html>

Попробуйте удалить width = "100%" height = "100%" из образа, чтобы он отображался в исходном размере. Прямо сейчас браузер, вероятно, масштабирует изображение, но копия, которую вы рисуете на холсте, использует исходные пиксели. Если вы хотите, чтобы копия была увеличена, вам необходимо динамически рассчитать масштабный коэффициент, разделив увеличенную ширину на исходную ширину изображения.

Chris G 09.11.2018 12:56

Или просто используйте img.naturalWidth / img.naturalHeight

Kaiido 09.11.2018 13:40

@ChrisG, это сработало впервые! Спасибо, я тупо думал, что они обеспечивают отображение изображения в полном размере, но на самом деле устанавливал его на высоту / ширину окна просмотра - если вы добавите его в качестве ответа, я подтвердю?

T.Davidson 09.11.2018 14:20

@Kaiido Это тоже сработало - спасибо!

T.Davidson 09.11.2018 14:20

@ChrisG, мне не удалось найти правильный обман, вы можете дать ответ (вы были правы, браузер преобразует значение% в вычисленное значение px, а drawImage использует естественные размеры)

Kaiido 09.11.2018 15:46
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
5
88
2

Ответы 2

Чтобы отразить изображение, вам нужно перевести контекст ctx.translate(0, this.height), а затем масштабировать его ctx.scale(1,-1);. Однако при изменении размера холст останется в исходном размере, в то время как изображение будет адаптироваться к размеру окна. Если вам нужно, чтобы холст также адаптировался, вам нужно будет пересчитать все при изменении размера.

var imgData = document.getElementById("scream");
imgData.onload = function() {
    
    var c = document.createElement('canvas');
 
    c.width = this.width;
    c.height = this.height;
    var body = document.getElementsByTagName("body")[0];
    body.appendChild(c);
    var ctx = c.getContext("2d");

    ctx.translate(0, this.height);
    ctx.scale(1,-1);
    ctx.drawImage(this, 0, 0,this.width,this.height);


};
<img id = "scream" src = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/imgres.jpg" alt = "The Scream" width = "100%" height = "100%">

Далее идет пример, в котором размер холста изменяется при изменении размера. В этом случае вам нужно переместить весь код, который рисует изображение внутри функции, которая будет вызываться при изменении размера.

Цитата из MDN:

Since resize events can fire at a high rate, the event handler shouldn't execute computationally expensive operations such as DOM modifications. Instead, it is recommended to throttle the event using requestAnimationFrame, setTimeout or customEvent"

window.onload = function() {

  var imgData = document.getElementById("scream");
  var c = document.createElement("canvas");
  var body = document.getElementsByTagName("body")[0];
  body.appendChild(c);
  var ctx = c.getContext("2d");

  imgData.onload = function() {
    init();
  };

  function init() {
    c.width = imgData.width;
    c.height = imgData.height;

    ctx.translate(0, imgData.height);
    ctx.scale(1, -1);
    ctx.drawImage(imgData, 0, 0, imgData.width, imgData.height);
 
  }

  setTimeout(function() {
    init();

    addEventListener("resize", init, false);
  }, 15);
};
<img id = "scream" src = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/imgres.jpg" alt = "The Scream" width = "100%" height = "100%">

Я не искал ctx.translate, но сделаю, если это означает, что макет будет адаптивным. Ваше здоровье.

T.Davidson 09.11.2018 14:21

Я думаю, вас смутило использование здесь слова "зеркало". Они не пытаются применить масштаб (-1,0), также известный как «зеркальный эффект», но зеркально отобразить изображение в другом месте, то есть клонировать его где-нибудь еще.

Kaiido 09.11.2018 15:39

Это потому, что вы используете свойства .ширина и .ростImageElement. При получении они должны вернуть вычисленное значение своего соответствующего атрибута в px.
В разметке этим атрибутам было присвоено относительное значение 100%, что означает, что их вычисленное значение будет относиться к размеру родительского элемента ImageElement.

Поэтому, когда вы просите drawIamge нарисовать ваше изображение, используя этот выходной размер, он действительно изменит размер / растянет ваше изображение. Чтобы этого избежать, вам нужно использовать исходный размер изображения, а не ImageElement.

Для этого, если все, что вам нужно, это нарисовать того же размера, что и исходное изображение, вы можете просто вызвать версию длина 3drawImage(source, x, y), которая по умолчанию будет использовать исходный размер источник. Но вам все равно нужно изменить размер холста до правильного, прежде чем это делать, и для этого вам нужно получить доступ к исходному размеру изображения.

К счастью, этот исходный размер изображения доступен в свойствах ImageElement naturalWidth и naturalHeight.

document.getElementById("scream").onload = function() {
    var c = document.createElement('canvas');
    var imgData = document.getElementById("scream");
    
    console.info('computed width: ', imgData.width);
    console.info('original width: ', imgData.naturalWidth);
    
    c.width = imgData.naturalWidth;
    c.height = imgData.naturalHeight;
    var body = document.body;
    body.appendChild(c);
    var ctx = c.getContext("2d");
    // the 3 length version is enough here
    ctx.drawImage(imgData, 0, 0);
};
<img id = "scream" src = "https://upload.wikimedia.org/wikipedia/commons/thumb/8/86/Edvard_Munch_-_The_Scream_-_Google_Art_Project.jpg/190px-Edvard_Munch_-_The_Scream_-_Google_Art_Project.jpg" alt = "The Scream" width = "100%" height = "100%">

Другие вопросы по теме