Изображение как трафарет для HTML-холста - PullRequest
0 голосов
/ 25 сентября 2018

Я пытаюсь, чтобы пользователь вручную раскрасил определенные части изображения.Например, вот кошка https://techflourish.com/images/3-cat-clipart-9.png. Пользователь должен иметь возможность раскрашивать ноги кошки, если они того пожелают.Я хочу, чтобы они окрашивали только часть изображения тела кота на холсте (а не фоновую часть изображения или пробелы на холсте, но, думаю, я мог бы просто обрезать изображение вручную).

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

`

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

    var pos = { x: 0, y: 0 };

    // new position from mouse events
    function setPosition(e) {
        pos.x = e.clientX;
        pos.y = e.clientY;
    }

    function rgbToHex(r, g, b) {
        if (r > 255 || g > 255 || b > 255)
            throw "Invalid color component";
        return ((r << 16) | (g << 8) | b).toString(16);
    }

    function draw(e) {
        if (e.buttons !== 1) return; // if mouse is pressed.....

        var color = "#cb3594";

        ctx.beginPath(); // begin the drawing path

        ctx.lineWidth = 5; // width of line
        ctx.lineCap = "round"; // rounded end cap
        ctx.strokeStyle = color; // hex color of line

        var p = ctx.getImageData(pos.x, pos.y, 1, 1).data;
        var sourceColor = rgbToHex(p[0], p[1], p[2]);
        if(sourceColor != "BACKGROUNDHEX" && sourceColor != color) {
            ctx.moveTo(pos.x, pos.y); // from position
            setPosition(e);
            p = ctx.getImageData(pos.x, pos.y, 1, 1).data;
            targetColor = rgbToHex(p[0], p[1], p[2]);

            if(targetColor != "BACKGROUNDHEX" && targetColor != color) {
                ctx.lineTo(pos.x, pos.y); // to position
                ctx.stroke(); // draw it!
            }
        }

    }

    var outlineImage = new Image();
    outlineImage.onload = function() {
        ctx.drawImage(outlineImage, 0, 0, 704, 720);
    }
    outlineImage.src = "IMAGE.png";

    space.addEventListener("mousemove", draw);
    space.addEventListener("mousedown", setPosition);
    space.addEventListener("mouseenter", setPosition);


</script>

`

(связанные изменения: кровотечение вызвано тем, что «sourceColor! = color» неправильно, но вопрос все еще актуален, так как это не похоже на отличное решение)

1 Ответ

0 голосов
/ 26 сентября 2018

Поскольку части изображения, которые вы не хотите окрашивать, являются прозрачными, вы можете установить для контекста globalCompositeOperation на 'source-atop'.После этого любые пиксели, которые вы рисуете на холсте, автоматически приобретают непрозрачность перезаписанных пикселей, и вам не нужно связываться с getImageData:

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

var pos = {
  x: 0,
  y: 0
};

// new position from mouse events
function setPosition(e) {
  // offsetX/Y gives the correct coordinates within the canvas
  // assuming it has no padding
  pos.x = e.offsetX;
  pos.y = e.offsetY;
}

function draw(e) {
  if (e.buttons !== 1) return; // if mouse is pressed.....

  var color = "#cb3594";

  ctx.beginPath(); // begin the drawing path

  ctx.lineWidth = 5; // width of line
  ctx.lineCap = "round"; // rounded end cap
  ctx.strokeStyle = color; // hex color of line

  ctx.moveTo(pos.x, pos.y); // from position
  setPosition(e);
  ctx.lineTo(pos.x, pos.y); // to position
  ctx.stroke(); // draw it!
}

var outlineImage = new Image();
outlineImage.onload = function() {
  // the default, set explicitly because we're changing it elsewhere
  ctx.globalCompositeOperation = 'source-over';
  
  ctx.drawImage(outlineImage, 0, 0);

  // don't draw over the transparent parts of the canvas
  ctx.globalCompositeOperation = 'source-atop';
  
  // wait until the stencil is loaded before handing out crayons
  space.addEventListener("mousemove", draw);
  space.addEventListener("mousedown", setPosition);
  space.addEventListener("mouseenter", setPosition);
}
outlineImage.src = "https://i.stack.imgur.com/so095.png";
<canvas id="space" width="610" height="733"></canvas>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...