J'essaie de créer une animation dans une page Web où l'ombre de la boîte d'un élément répond à la position de la souris, c'est-à-dire (X rouge = souris):
J'ai déjà trouvé une fonction qui suit le mouvement de la souris, mais je ne sais pas comment l'appliquer à l'objet. Voici mon code:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <p id="shadow-test">This is a shadow test</p>
#shadow-test {
box-shadow: -10px -10px red;
border: 1px solid white;
}$(document).ready(function() {
function shadowAnimation() {
var objectToAnimate = $("#shadow-test");
document.onmousemove = handleMouseMove;
function handleMouseMove(event) {
var eventDoc, doc, body;
event = event || window.event;
if (event.pageX == null && event.clientX != null) {
eventDoc = (event.target && event.target.ownerDocument) || document;
doc = eventDoc.documentElement;
body = eventDoc.body;
event.pageX = event.clientX +
(doc && doc.scrollLeft || body && body.scrollLeft || 0) -
(doc && doc.clientLeft || body && body.clientLeft || 0);
event.pageY = event.clientY +
(doc && doc.scrollTop || body && body.scrollTop || 0) -
(doc && doc.clientTop || body && body.clientTop || 0);
}
console.log(event.pageX + " " + event.pageY);
}
}
});3 Réponses :
Si je comprends bien, vous avez implémenté le suivi de la souris. Dans votre capture d'écran et votre description, ce n'est pas clair lorsque la propriété box-shadow change en fonction de la position de la souris. Une fois que vous avez capturé la position de la souris et que vous pouvez calculer la position du pointeur de la souris, utilisez simplement ce code js pour mettre à jour la propriété box-shadow de votre entrée de texte. trois cas
$("#shadow-test").css('box-shadow', '0px 10px red');
$("#shadow-test").css('box-shadow', '10px 10px red');
$("#shadow-test").css('box-shadow', '-10px -10px red');
Votre logique pour capturer la position de la souris est beaucoup plus compliquée que nécessaire. Il vous suffit de suivre la pageX et la pageY de l'événement mousemove.
Pour déplacer l'ombre, il vous suffit de calculer la distance entre la souris et le milieu de chaque dimension de l'élément cible. Ensuite, vous pouvez appliquer cette distance, limitée par la hauteur disponible de l'élément, à la taille de la box-shadow , quelque chose comme ceci:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <p id="shadow-test">This is a shadow test</p>
body {
height: 2000px;
}
#shadow-test {
box-shadow: -10px -10px red;
border: 1px solid white;
margin: 100px;
background-color: #CCC;
}jQuery($ => {
let $shadow = $('#shadow-test');
let shadowMax = $shadow.height();
let shadowMin = shadowMax * -1;
let shadowMidPoints = [
$shadow.offset().left + $shadow.width() / 2,
$shadow.offset().top + $shadow.height() / 2
];
$(document).on('mousemove', e => {
let shadowX = Math.min(shadowMax, Math.max(shadowMin, shadowMidPoints[0] - e.pageX));
let shadowY = Math.min(shadowMax, Math.max(shadowMin, shadowMidPoints[1] - e.pageY));
$shadow.css('box-shadow', `${shadowX}px ${shadowY}px red`);
});
});Cela fonctionne parfaitement et est beaucoup plus efficace, merci pour votre aide.
Veuillez jeter un œil aux exemples suivants (sans jquery).
<div class="center">
<button>
More
</button>
</div>
<p id="shadow-test">This is a shadow test</p>:root {
--primary-color: black;
--secondary-color: white;
--shadow-color: red;
--button-color: blue;
--color: white;
}
body {
background-color: var(--primary-color);
padding: 1rem;
}
.center {
text-align: center;
}
button {
background-color: var(--button-color);
color: var(--color);
border: 0;
border-radius: .25rem;
padding: .375rem 1rem;
}
#shadow-test {
border: 1px solid var(--secondary-color);
color: var(--secondary-color);
}const p = document.querySelector('#shadow-test');
const clamp = (a, m, n) => {
const max = Math.max(m, n);
const min = Math.min(m, n);
return Math.max(min, Math.min(max, a));
};
const MAX_SHADOW_OFFSET = 30;
const paint = (x, y) => {
const r = p.getBoundingClientRect();
const o = Math.min(r.width, r.height, MAX_SHADOW_OFFSET); // compute max shadow offset
const mx = clamp(x, r.left - o, r.right + o); // clamp mouse coordinates within the shadow projection bounding box.
const my = clamp(y, r.top - o, r.bottom + o);
const px = r.right - r.width / 2; // compute element bb midpoints.
const py = r.bottom - r.height / 2;
const nx = (mx - px) / (r.right - r.left + 2 * o); // project mouse position relative to the bounding box to [-.5, .5];
const ny = (my - py) / (r.bottom - r.top + 2 * o);
requestAnimationFrame(() => {
p.style.boxShadow = `${-1 * nx * o}px ${-1 * ny * o}px var(--shadow-color)`;
});
};
document.addEventListener('mousemove', (e) => paint(e.clientX, e.clientY), {
passive: true
});C'est certainement une bouchée par rapport aux autres solutions, mais ce n'est pas si complexe. L'algorithme peut être décomposé en deux étapes.
Nous calculons la boîte englobante de l'élément. Nous en avons besoin pour déterminer le décalage maximal de notre ombre de boîte ainsi que les projections vers notre espace de coordonnées de normalisation plus tard.
Nous fixons les coordonnées de la souris à notre nouvelle boîte englobante. Ceci est utilisé pour que si vous éloignez votre souris de l'élément, elle ne continue pas à bouger. Nous aurons également besoin des coordonnées de la souris pour projeter notre dans notre espace de coordonnées normalisé.
Nous trouvons le milieu de notre élément. Tout ce qui reste du milieu sera négatif, tout ce qui est juste sera positif et ainsi de suite. Nous pouvons utiliser les valeurs de signe pour déterminer le côté de l'ombre de la boîte. Une souris sur le côté gauche du milieu donnera à utiliser une valeur négative, sur le côté droit, elle sera positive.
Enfin, nous projetons les coordonnées de notre souris dans notre espace de coordonnées normalisé de [-0.5, .5] . Les coordonnées normalisées facilitent le calcul des décalages par une simple multiplication. Considérez (nx,ny) comme de simples valeurs d'échelle. Étant donné une valeur de décalage d'ombre maximale, combien devrions-nous appliquer au style? et dans quelle direction?
Autres notes
Je mets à jour le style dans un cadre d'animation de demande. C'est généralement meilleur pour les performances. Vous devriez également noter les css variables . Ceci est fait pour ne pas avoir à coder en dur la valeur de couleur de la box-shadow dans le code. Le thème vit complètement en css.
Vous pouvez peut-être vous inspirer de tilt.js et tobiasahlin.com/blog/how-to-animate-box-shadow .