Оберните изображение вокруг цилиндра, используя проблему непрозрачности canvas drawImage - PullRequest
2 голосов
/ 02 мая 2020

Мне нужно обернуть изображение вокруг другого изображения кружки, используя javascript, и я нашел это: Обернуть изображение вокруг цилиндрического объекта в HTML5 / JavaScript

Это помогает при загрузке изображения с ручкой кружки слева. Однако при использовании той же функции (с измененными значениями положения) к изображению применяется непрозрачность. Я искал бесконечно, чтобы выяснить, по какой причине это происходит, однако я ничего не нашел: /

Mug image with left handle

Mug image with right handle

Эта функция используется для оборачивания изображения для кружки правой ручкой:

function canvas2() {
 var canvas = document.getElementById('canvas2');
 var ctx = canvas.getContext('2d');

 var productImg = new Image();
 productImg.onload = function() {
   var iw = productImg.width;
   var ih = productImg.height;

   canvas.width = iw;
   canvas.height = ih;

   ctx.drawImage(
     productImg,
     0,
     0,
     productImg.width,
     productImg.height,
     0,
     0,
     iw,
     ih
   );
   loadUpperIMage();
 };

 productImg.src =
   'https://i.ibb.co/B2G8y1m/white-right-ear.jpg';

 function loadUpperIMage() {
   var img = new Image();
   img.src =
     'https://i.ibb.co/BnQP0TL/my-mug-image.png';

   img.onload = function() {
     var iw = img.width;
     var ih = img.height;

     var xOffset = 48, //left padding
         yOffset = 68; //top padding

     var a = 70; //image width
     var b = 8; //round ness

     var scaleFactor = iw / (6 * a);

     // draw vertical slices
     for (var X = 0; X < iw; X += 1) {
       var y = (b / a) * Math.sqrt(a * a - (X - a) * (X - a)); // ellipsis equation

       if (!isNaN(y)) {
         ctx.drawImage(
           img,
           X * scaleFactor,
           0,
           iw / 0.78,
           ih,
           X + xOffset,
           y + yOffset,
           1,
           162
         );
       }
     }
   };
 }

}

Надеюсь, что кто-то может помочь с этим!

Вот скрипка с вопросом https://jsfiddle.net/L20aj5xr/

1 Ответ

2 голосов
/ 02 мая 2020

Это из-за 4-го аргумента, который вы передаете drawImage - iw / 0.78. Умножая ширину изображения на значение меньше единицы, вы получаете значение, превышающее ширину изображения. spe c для drawImage говорит:

Когда исходный прямоугольник находится за пределами исходного изображения, исходный прямоугольник должен быть обрезан до исходного изображения, а целевой прямоугольник должен быть обрезается в той же пропорции.

ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);

enter image description here

Поскольку используемая ширина источника (sw) больше, чем исходное изображение размер, прямоугольник назначения "обрезается в той же пропорции". Ширина прямоугольника назначения составляет 1 пиксель, потому что вы выбрали его в качестве ширины для каждой вертикальной линии, которую вы рисуете, и после обрезки ее ширина становится 1 * 0,78 = 0,78 пикселей. Ширина теперь меньше 1px, и, честно говоря, я не совсем уверен, как это на самом деле работает под капотом, но я предполагаю, что браузер все еще должен отрисовывать этот 1px, но, поскольку источник - 0.78px, он как бы растягивает источник в 1px и добавляет сглаживание для сглаживания перехода, что приводит к дополнительной прозрачности (т. е. браузеру не хватает информации для этого 1px, и он пытается заполнить его как можно лучше). Вы можете поэкспериментировать с этим, увеличивая sw еще больше и наблюдая увеличение прозрачности.

Чтобы исправить вашу проблему, я использовал значение 20 вместо 0.78, как для первой чашки, и это выглядело как ок.

...