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

Как обрезать клики() в холсте html5 в Chrome Windows?

Я использую функцию clip() на холсте.

Результаты: using canvas clip in various browsers

Как вы можете видеть, версия chrome имеет ужасные jaggies/aliasing по краям. Как это исправить?

Код для воспроизведения:

http://jsfiddle.net/ZRA76/:

<canvas id="test" width="300" height="300"></canvas>​

<script type="text/javascript">
    cv = document.getElementById("test");
    ctx = cv.getContext("2d");

    var im = new Image();
    im.onload = function () {
        ctx.beginPath();
        ctx.arc(110, 110, 100, 0, 2*Math.PI, true);
        ctx.clip();
        ctx.drawImage(im, 0, 0);
    }
    im.src = "http://placekitten.com/300/300";
</script>
4b9b3361

Ответ 1

Если вы выполняете сложный многоуровневый чертеж, вы можете использовать globalCompositeOperation для эмуляции обрезки во втором холсте с нуля. Затем вы можете использовать drawImage для копирования холста с нуля в исходный холст. Я не могу гарантировать выполнение этого подхода, но это единственный способ узнать, что вы хотите.

//set-up - probably only needs to be done once
var scratchCanvas = document.createElement('canvas');
scratchCanvas.width = 100;
scratchCanvas.height = 100;
var scratchCtx = scratchCanvas.getContext('2d');


//drawing code
scratchCtx.clearRect(0, 0, scratchCanvas.width, scratchCanvas.height);

scratchCtx.globalCompositeOperation = 'source-over'; //default

//Do whatever drawing you want. In your case, draw your image.
scratchCtx.drawImage(imageToCrop, ...);


//As long as we can represent our clipping region as a single path, 
//we can perform our clipping by using a non-default composite operation.
//You can think of destination-in as "write alpha". It will not touch
//the color channel of the canvas, but will replace the alpha channel.
//(Actually, it will multiply the already drawn alpha with the alpha
//currently being drawn - meaning that things look good where two anti-
//aliased pixels overlap.)
//
//If you can't represent the clipping region as a single path, you can
//always draw your clip shape into yet another scratch canvas.

scratchCtx.fillStyle = '#fff'; //color doesn't matter, but we want full opacity
scratchCtx.globalCompositeOperation = 'destination-in';
scratchCtx.beginPath();
scratchCtx.arc(50, 50, 50, 0, 2 * Math.PI, true);
scratchCtx.closePath();
scratchCtx.fill();


//Now that we have a nice, cropped image, we can draw it in our
//actual canvas. We can even draw it over top existing pixels, and
//everything will look great!

ctx.drawImage(scratchCanvas, ...);

Причина, по которой мы делаем это на холсте с нуля, заключается в том, что назначение - это довольно разрушительная операция. Если вы уже нарисовали какие-то вещи в главном холсте (возможно, вы положили хороший градиент в фоновом режиме), а затем хотели нарисовать обрезанное изображение, обтравочный круг также вырезал бы все, что вы уже нарисовали. Конечно, если ваша конкретная ситуация проще (возможно, ВСЕ, которые вы хотите сделать, это обрезанное изображение), тогда вы можете отказаться от холста царапины.

Вы можете играть с различными режимами отсечения на моей демонстрационной странице. Нижняя строка (с градиентами) не слишком полезна для вас, но верхняя строка (с кругом и квадратом) гораздо важнее.

изменить

Убивает, я случайно разветкил ваш JSFiddle, чтобы продемонстрировать технику.

Ответ 2

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

Ответ 3

Я столкнулся с той же проблемой с Chrome и клипом().

В моих обстоятельствах я добился лучшей совместимости браузеров, установив холст globalCompositeOperation.

context.globalCompositeOperation = 'source-atop';

Итак, нарисуйте фигуру, круг в этом случае. Затем переключитесь на "source-atop" и нарисуйте изображение вашего котенка.

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

Ответ 5

Используйте svg-клип. Работает как шарм, но не так удобен в использовании.