Попытка создать эффект отслеживания мыши, который вызывает изменение Transform3d в блоке и содержимом, а также добавляет вспышку в месте, где находится мышь.
Как бы вы написали это на vanilla js, чтобы оно было стабильным - я не уверен в формуле, используемой для расчета этих изменений градусов - поскольку они, кажется, составляют от -8 до максимум 9 градусов.
https://jsfiddle.net/qzo3ck5m/46/
var myElement = $("#p1");
function setTranslate(xPos, yPos, zPos, el) {
console.info("test");
el.style.transform = `translate3d(0, 0, 0) scale3d(1, 1, 1) rotateX(${xPos}deg) rotateY(${yPos}deg) rotateZ(0deg) skew(0deg, 0deg)`;
}
myElement.mousemove(function(event) {
console.info("mousemoveY---", event.clientX, event.clientY);
let y = event.clientY;
let x = event.clientX;
var position = {
top: myElement[0].offsetTop,
left: myElement[0].offsetLeft
};
console.info("x", x);
console.info("y", y);
console.info("position", position);
let degx = position.left - x;
let degy = position.top - y;
console.info("degx", degx);
console.info("degy", degy);
let fullDegrees = 8;
setTranslate(-degx / 20, -degy / 20, 0, myElement[0]);
});
myElement.mouseleave(function() {
console.info("mouseleave");
setTranslate(0, 0, 0, myElement[0]);
});
.container {
padding: 40px;
}
.blockwrapper {
will-change: transform;
transform: translate3d(0, 0, 0) scale3d(1, 1, 1) rotateX(0deg) rotateY(0deg) rotateZ(0deg) skew(0deg, 0deg);
margin: 10px;
}
.block {
background-color: skyblue;
width: 160px;
height: 160px;
}
.moved {
background-color: pink;
}
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div class = "container">
<div class = "blockwrapper">
<div class = "block moved">Moved</div>
</div>
<div id = "p1" class = "blockwrapper">
<div class = "block">Movable</div>
</div>
</div>
Вероятно, вы захотите создать вектор от центра объекта до мыши и либо получить углы поворота вектора xyz и использовать их (может сработать сразу), либо создать функцию LookAt.
Выполните расчет ограничивающей рамки и разделите ширину и высоту на 2 - используйте его для расчета положений x, y?
как создать что-то подобное без добавления каких-либо модулей и т. д.. путь на чистом js
Как насчет вычисления расстояния между центром блока и позицией курсора?
Кроме того, если вы хотите использовать jQuery, используйте метод $.fn.on
для подключения слушателей.
let sensitivity = 0.5;
function setTranslate($el, x, y, z=0) {
$el.css({
transform: `rotateX(${x}deg) rotateY(${y}deg) rotateZ(${z}deg)`
});
}
$('.blockwrapper').on({
mousemove: function(event) {
const $block = $(event.currentTarget).find('.block');
const $spotlight = $block.find('.spotlight');
let { clientX: x, clientY: y } = event;
let rect = $block[0].getBoundingClientRect();
// Calculate the center of the element
let centerX = rect.left + rect.width / 2;
let centerY = rect.top + rect.height / 2;
// Calculate the relative position from the center
let deltaX = (x - centerX);
let deltaY = (y - centerY);
// Calculate the rotation angles to move away from the cursor
let rotateX = -deltaY * sensitivity; // Invert to tilt away
let rotateY = deltaX * sensitivity; // Invert to tilt away
setTranslate($block, rotateX, rotateY);
// Move the spotlight
let spotlightSize = $spotlight.width();
let spotlightX = x - rect.left - spotlightSize / 2;
let spotlightY = y - rect.top - spotlightSize / 2;
$spotlight.css({
transform: `translate(${spotlightX}px, ${spotlightY}px)`,
opacity: 1
});
},
mouseleave: function(event) {
const $block = $(event.currentTarget).find('.block');
const $spotlight = $block.find('.spotlight');
setTranslate($block, 0, 0);
// Hide the spotlight
$spotlight.css({ opacity: 0 });
}
});
body {
background: #000;
}
.container {
padding: 0.5rem;
}
.blockwrapper {
display: inline-block;
perspective: 1000px;
position: relative;
overflow: visible;
margin: 0.5rem;
background: red;
width: fit-content;
border-radius: 2rem;
will-change: transform;
transform: translate3d(0, 0, 0) scale3d(1, 1, 1) rotateX(0deg) rotateY(0deg) rotateZ(0deg) skew(0deg, 0deg);
}
.block {
position: relative;
z-index: 1;
overflow: hidden;
width: 120px;
height: 120px;
padding: 1rem;
border: thin solid #444;
border-radius: 1.8rem;
background-color: #222;
color: #eee;
transition: transform 0.5s ease;
}
.spotlight {
position: absolute;
top: 0;
left: 0;
width: 80px;
height: 80px;
border-radius: 50%;
pointer-events: none;
background: rgb(255,255,0);
background: radial-gradient(circle, rgba(255,255,0,0.5) 0%, rgba(255,255,0,0.1) 25%, transparent 75%);
transform: translate(-50%, -50%);
transition: opacity 0.2s ease;
z-index: 2;
opacity: 0;
}
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div class = "container">
<div class = "blockwrapper">
<div class = "block">
Movable #1
<div class = "spotlight"></div>
</div>
</div>
<div class = "blockwrapper">
<div class = "block">
Movable #2
<div class = "spotlight"></div>
</div>
</div>
<div class = "blockwrapper">
<div class = "block">
Movable #3
<div class = "spotlight"></div>
</div>
</div>
</div>
Это хорошо — как бы нам улучшить его с помощью смягчения, чтобы оно не возвращалось так быстро. Уменьшите силу эффекта, чтобы мы могли лишь немного наклонить плитку, и она медленнее возвращалась в нейтральное положение, а не возвращалась обратно.
Я получил эффект прожектора, чтобы иметь эти качества - .light-outside { width: 200px; высота: 200 пикселей; непрозрачность: .3; фильтр: размытие (70 пикселей); цвет фона: #fff; }
ссылка на раздел опыта здесь -- az-black.webflow.io/#experince
@TheOldCounty привязка — это чувствительность. Вы можете установить более низкое значение, например 0,1.
как бы мы улучшили его с помощью смягчения, чтобы оно не возвращалось так быстро.
@TheOldCounty Я добавил правило стиля transition
к .block
.
@Mr.Polywhirl, отличный ответ.
Я бы сказал, что первый шаг к созданию этого ванильного js — изменить
var myElement = $("#p1");
наconst myElement = document.querySelector('#p1');
. Немного неясно, как HTML фрагмента соответствует анимации.