получать клики через HTML-холст - PullRequest
18 голосов
/ 01 сентября 2010

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

Вот пример: с изображением: http://www.1luckypixel.com/paranormal/canvas_test.html ссылка идет в Google, но не регистрируется.

Насколько я понимаю, холст по умолчанию прозрачен для мыши?

Ответы [ 8 ]

9 голосов
/ 11 января 2012

Если кросс-браузерная функциональность не обязательна, то есть простое решение. В браузерах, которые поддерживают его не для элементов SVG (webkit, Mozilla и, возможно, другие, но особенно не IE), вы можете использовать свойство css под названием pointer-events . Из МДН:

"Указатель-события свойства CSS позволяет авторам контролировать, при каких обстоятельствах (если они есть) конкретный графический элемент может становиться целью событий мыши. Если это свойство не указано, те же характеристики значения visiblePainted применяются к содержимому SVG. .

В дополнение к указанию, что элемент не является целью событий мыши, значение none инструктирует событие мыши проходить «через» элемент и нацеливать все, что находится «под» этим элементом.

Предупреждение. Использование событий указателя в CSS для элементов, не относящихся к SVG, является экспериментальным. В настоящее время определено в проекте спецификации пользовательского интерфейса CSS3, есть обсуждение, чтобы отложить его до CSS4. "

По крайней мере, вы можете использовать Modernizr для обнаружения поддержки событий указателя и выполнить трюк с непрозрачностью, упомянутый в Ответ Саймона Сарриса в браузерах, которые его не поддерживают.

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

Пример: http://www.patrick -wied.at / статический / heatmapjs / демо / maps_heatmap_layer / gmaps.php

5 голосов
/ 19 ноября 2013

Если вы не можете поместить ссылки выше холста ...

Для новых / приличных браузеров просто используйте этот CSS:

#canvas { pointer-events:none; }

И грязный обходной путь для IE +старые браузеры (вы могли бы удалить зависимость от jQuery):

jQuery('#canvas').click(function(e) {
    window.location = jQuery('#element-under-canvas').attr('href');
});

Очевидно, что это поддерживает только якоря в их нынешнем виде, и вам нужно знать определенный элемент под холстом (или найти его с помощью магии селектора jQuery).

2 голосов
/ 29 ноября 2014

Я смог сделать это, установив холст следующим образом:

<div>
    <a href='#'>my link</a>
    <canvas></canvas>
</div>

Затем я установил следующее в CSS:

canvas {
    display: block;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    position: absolute;
    z-index:-1; /* NOT SURE HOW SUPPORTED THIS IS, IT WORKED IN CHROME */
}

Ссылка внутри div была интерактивной, независимо от того, что я нарисовал на холсте во время выполнения.

Надеюсь, это поможет!

2 голосов
/ 01 сентября 2010

Ну, краткий ответ: вы не можете пройти через клик.

Но второй самый короткий ответ - вы действительно можете делать все, что душе угодно!Вам просто нужно быть немного странным с решением.

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

<!-- A visible button behind the canvas -->
<button id="but" type="button" style="position: absolute; top: 100px; left: 100px;">Click Me!</button>

<canvas id="can" width="500" height="500" style="position: absolute;"></canvas>

<!-- A near copy of the visible button, but this one is invisible and in front of the canvas! -->
<button id="but" type="button" onclick="alert('click!')" style="position: absolute; top: 100px; left: 100px; opacity: 0;">Click Me!</button>

Если вы хотите увидеть этот код в действии , нажмите здесь

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

1 голос
/ 10 апреля 2013

Заимствуя из ответа Саймона Сарриса, в некоторых ситуациях может быть проще разместить холст и элементы управления в одной плоскости. В зависимости от элемента управления он не всегда позволяет рисовать холст поверх элемента управления, но в первоначальном вопросе Джо это не требуется. Важно убедиться, что холст и элементы управления находятся в одной плоскости Z, оба имеют стиль, использующий ключевое слово position, и имеют HTML-код для элементов управления после оператора canvas. Ниже приведен пример холста, объединенного с элементами управления с использованием этого метода.

<canvas id="can" width="500" height="500" style="z-index:2; position: absolute;"></canvas>
<!-- Put text and a link on the same plane as the canvas -->
<div style="position: relative; z-index: 2;">
   <a href="http://www.google.com/">Click</a> this Google link.
</div>
0 голосов

Я думаю, что лучше изменить динамический z-индекс. Если вам нужно использовать элементы управления, установите их z-index выше, чем canvas. Если вам нужно использовать canvas - установите его z-index выше, чем элементы управления. Как это сделать, зависит от вашей ситуации. Вы можете прослушивать события mousedown / mouseup или перемещения мыши по некоторым областям.

0 голосов
/ 24 января 2014

Вот как я решил эту проблему ...

У меня устройство с круглым пользовательским интерфейсом (нарисовано на простом холсте HTML5, представляющем собой квадрат).Только круг окрашен, остальная часть холста прозрачна, и я хочу щелкнуть по нему.Под углами квадратного холста на сцене Kinetic JS находятся фигуры.

Обычно вы не можете щелкнуть по холсту.

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

    $( '#myCanvasUserInterfaceLayer' ).on( 'click', function( e ) {

        var pos = getMousePos( e );
        var obscuredKineticShape = kineticLayer.getIntersection( pos );

   // (Note: console.log(obscuredKineticShape) and you find that 
   // 'getIntersection' returns an object with the topmost shape 
   //  at the click point on the kinetic stage within it, called 'shape').

        obscuredKineticShape.shape.fire( 'mousedown' ); 

    });

     function getMousePos( e ) {

        return {
          x: e.pageX,
          y: e.pageY
        };
      }
0 голосов
/ 03 сентября 2010

Я не уверен, как проходит процедура для этого, но Саймон Саррис фактически предоставил решение в комментариях:

К сожалению, мой другой метод не будет работать в этом случае.:( Тем не менее, вы можете по-прежнему возиться с непрозрачностью, пока у вас не появится что-то близкое к тому, что вы хотите. Вот пример прозрачной карты, показывающей холст за ней. Кажется, что зеленое поле сверху, но на самом деле оно просто просматривается: jsfiddle.net / un9yW / 11 Конечно, использование этого метода означает, что невозможно создать зеленую рамку, чтобы полностью покрыть часть карты и т. Д., Что отчасти хромает.дай знать, если я подумаю о чем-нибудь еще, что подойдет для твоей ситуации - Саймон Саррис 7 часов назад

...