Подтвердить что ты не робот

Маскирование/перекрытие изображения холста

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

Переопределенное изображение должно быть изменено в другом выбранном цвете. Мой вопрос. Есть ли способ использовать холст из того, что мы можем изменить цвет изображения, который нарисован холстом, или нам нужно всегда использовать разные изображения и применять с CSS/jQuery.

Я читал о маскировании и перекрытии изображения холста. Но не могу понять мои образы, потому что они не квадратные или круглые, тогда прежде всего я рисую несколько форм волны на одном изображении. Я не знаю, что я искал, но не смог найти идеальное решение.

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

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

4b9b3361

Ответ 1

Вы можете использовать компоновку контекста для замены части изображения.

Например, если у вас есть этот синий логотип уже как изображение:

enter image description here

Любую вы хотите, чтобы верхняя часть логотипа была окрашена в фиолетовый цвет:

enter image description here

Вы можете использовать компоновку, чтобы перекрасить верхнюю часть изображения.

Во-первых, используйте свой любимый редактор изображений, чтобы обрезать любую часть, которую вы dont хотите перекрасить.

Осталось называть оверлей.

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

enter image description here

Этот оверлей можно программно перекрасить в любой цвет.

enter image description hereenter image description here

Как оверлей был программно перекрашен:

  • Нарисуйте наложение на пустой холст.
  • Установите режим компоновки на "источник".
  • Эффект: заменены только существующие пиксели - прозрачные пиксели остаются прозрачными
  • Теперь нарисуем прямоугольник любого цвета, покрывающий холст
  • (помните, что только существующее наложение будет заменено новым цветом)

Как заполнить логотип с измененным цветом наложения

  • Установите режим компоновки на "destination-atop"
  • Эффект: заменены только прозрачные пиксели - существующие пиксели остаются неизменными
  • Теперь нарисуйте оригинальный логотип
  • (помните, что существующее цветное оверлей не будет заменено)

Этот эффект компоновки "destination-atop" иногда называют "рисованием под".

Этот оверлей можно даже заменить текстурами!

enter image description here

Вот код и скрипт: http://jsfiddle.net/m1erickson/bfUPr/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; padding:20px; }
    #canvas{border:1px solid red;}
</style>

<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");

    var truck,logo,overlay;
    var newColor="red";

    var imageURLs=[];
    var imagesOK=0;
    var imgs=[];
    imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/boxTruck.png");
    imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/TVlogoSmall.png");
    imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/TVlogoSmallOverlay.png");
    loadAllImages();

    function loadAllImages(){
        for (var i = 0; i < imageURLs.length; i++) {
          var img = new Image();
          imgs.push(img);
          img.onload = function(){ imagesOK++; imagesAllLoaded(); };
          img.src = imageURLs[i];
        }      
    }

    var imagesAllLoaded = function() {
      if (imagesOK==imageURLs.length ) {
         // all images are fully loaded an ready to use
         truck=imgs[0];
         logo=imgs[1];
         overlay=imgs[2];
         start();
      }
    };


    function start(){

        // save the context state
        ctx.save();

        // draw the overlay
        ctx.drawImage(overlay,150,35);

        // change composite mode to source-in
        // any new drawing will only overwrite existing pixels
        ctx.globalCompositeOperation="source-in";

        // draw a purple rectangle the size of the canvas
        // Only the overlay will become purple
        ctx.fillStyle=newColor;
        ctx.fillRect(0,0,canvas.width,canvas.height);

        // change the composite mode to destination-atop
        // any new drawing will not overwrite any existing pixels
        ctx.globalCompositeOperation="destination-atop";

        // draw the full logo
        // This will NOT overwrite any existing purple overlay pixels
        ctx.drawImage(logo,150,35);

        // draw the truck
        // This will NOT replace any existing pixels
        // The purple overlay will not be overwritten
        // The blue logo will not be overwritten
        ctx.drawImage(truck,0,0);

        // restore the context to it original state
        ctx.restore();

    }


}); // end $(function(){});
</script>

</head>

<body>
    <canvas id="canvas" width=500 height=253></canvas>
</body>
</html>

Ответ 2

Вопрос в том, что он стоит, немного нечеткая ИМО. Чтобы дать более общий ответ, который вы можете применить к сценарию, где вам нужно обрезать, вы можете использовать (по крайней мере) два подхода:

Способ 1 - Использование композитного режима для клипа

Композитный режим является самым простым способом, но также наименее гибким, поскольку вам необходимо предварительно определить обтравочную маску как изображение с прозрачным фоном (обычно PNG).

Вы можете использовать твердые части изображения, чтобы обрезать следующую нарисованную вещь или использовать прозрачные области для заполнения.

Вот подход, в котором мы используем сплошные части для клипа следующей обрамленной фигуры/изображения:

/// draw the shape we want to use for clipping
ctx1.drawImage(imgClip, 0, 0);

/// change composite mode to use that shape
ctx1.globalCompositeOperation = 'source-in';

/// draw the image to be clipped
ctx1.drawImage(img, 0, 0);

Здесь globalCompositeOperation изменен на source-in, что означает, что исходное изображение (тот, который мы собираемся сделать рядом с пунктом назначения) будет нарисован внутри существующих твердых данных. Для прозрачных областей ничего не будет.

Если наша обтравочная маска выглядит так (случайное использование из сети):

Clip mask

И наш образ выглядит следующим образом:

Main image

Результат будет таким:

Composited image

Способ 2 - Использование пути к клику

Вы также можете определить Путь для обрезки. Это очень гибко, поскольку вы можете настроить путь или оживить его, если хотите.

Примечание. Просто имейте в виду, что обрезание с использованием Path в настоящее время является "хрупким" в браузерах, поэтому вам следует рассмотреть возможность использования save() и restore() до и после установки и использования пути клипа, поскольку браузеры не могут reset клип в настоящий момент (restore будет восстанавливать клип по умолчанию = полный холст);

Позволяет определить простой путь зигзага (это будет ваши волны в вашем случае):

/// use save when using clip Path
ctx2.save();

ctx2.beginPath();
ctx2.moveTo(0, 20);
ctx2.lineTo(50,0);
/// ... more here - see demo
ctx2.lineTo(400, 20);
ctx2.lineTo(400, 100);
ctx2.lineTo(0, 100);
ctx2.closePath();

/// define this Path as clipping mask
ctx2.clip();

/// draw the image
ctx2.drawImage(img, 0, 0);

/// reset clip to default
ctx2.restore();

Теперь, когда мы установили обтравочную маску с помощью clip, все, что нарисовано на холсте, будет обрезано, чтобы вписаться в эту форму (обратите внимание, что мы уверены, что форма может закончиться там, где она началась):

Path clipped image

Смотрите демо-версию этих методов здесь