Страницы

Поиск по вопросам

воскресенье, 29 декабря 2019 г.

Просвечивающий изображение блок

#javascript #html #css #svg #canvas


Подобных вещей еще не приходилось реализовывать, по этому нуждаюсь в помощи выбора
оптимального способа реализации.
Постараюсь максимально понятно объяснить, что нужно сделать.
Есть блок с изображением, при попадании курсора в область этого блока, курсор заменяется
 на прямоугольный блок (возможно прозрачное изображение с рамкой), под которым начинает
просвечиваться блок с изображением, а под ним в свою очередь, находится другое изображение
часть которого становится видна. Получается что-то вроде clip-path как здесь http://www.cssplant.com/clip-path-generator
только вместо белого фона другое изображение и желательно иметь возможно как-то стилизовать
просвечиваемую область, возможно даже размещать в ней какие-то еще элементы. Также
на заднем фоне, есть активные области и если они попадают в область просмотра под курсором,
нужно это отлавливать.
Предполагаю, что нужно смотреть в сторону canvas'a. Если вдруг кто-то реализовывал
подобное или имеет понятие как это можно осуществить, возможно знаете готовые библиотеки
для подобных решений, буду рад любой помощи.
    


Ответы

Ответ 1



Что-то подобное соорудил на svg + js Эффект достигается за счет clip-path и подсчета расстояния от курсора до активных зон. // точка, для пересчета координат мыши в координаты svg холста var pt = svg.createSVGPoint(); // активные зоны var zones = document.querySelectorAll('.zone'); addEventListener('mousemove', e => { // так получаем координаты мыши относительно холста pt.x = e.clientX; pt.y = e.clientY; let p = pt.matrixTransform(svg.getScreenCTM().inverse()); // позиционируем clip-path clipRect.setAttribute('x', p.x - 7.5); clipRect.setAttribute('y', p.y - 17); // позиционируем телефон phone.setAttribute('x', p.x - 12.5); phone.setAttribute('y', p.y - 25); text.setAttribute('x', p.x); text.setAttribute('y', p.y + 13); text.innerHTML = ''; // перебираем все зоны zones.forEach(z => { // текущая прозрачность активной зоны let o = z.style.opacity; // новое значение прозрачности на основании теста попадания круга в прямоугольник z.style.opacity = test(z, clipRect) ? 1 : 0; +z.style.opacity && (text.innerHTML = z.id); // если значение прозрачности изменилось с 0 на 1 вызываем callback +z.style.opacity - o === 1 && callback(z.id); }) }) function test(zone, rect) { var zx = +zone.getAttribute('cx'); var zy = +zone.getAttribute('cy'); var zr = +zone.getAttribute('r'); var rx = +rect.getAttribute('x'); var ry = +rect.getAttribute('y'); var rw = +rect.getAttribute('width'); var rh = +rect.getAttribute('height'); return zx - zr > rx && zx + zr < rx + rw && zy - zr > ry && zy + zr < ry + rh; } function callback(id) { console.log(id) }

Комментариев нет:

Отправить комментарий