在悬停时为图像显示的移动添加一点滞后/弹性



我在一些文本上设置了图像显示效果。目前,当你四处移动时,图像会粘在鼠标光标上,但我需要它有一点滞后/弹性,这样它感觉更自然,最好像这里的图像。请参阅此处的示例代码笔。

我一直在绞尽脑汁想办法让它发挥作用,所以我们非常感谢任何帮助!

function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
/**
* demo.js
* http://www.codrops.com
*
* Licensed under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
*
* Copyright 2018, Codrops
* http://www.codrops.com
*/
{
// from http://www.quirksmode.org/js/events_properties.html#position
var getMousePos = function getMousePos(e) {
var posx = 0;
var posy = 0;
if (!e) e = window.event;
if (e.pageX || e.pageY) {
posx = e.pageX;
posy = e.pageY;
} else if (e.clientX || e.clientY) {
posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
return {
x: posx,
y: posy
};
}; // Effect 15

var HoverImgFx15 = /*#__PURE__*/function () {
"use strict";
function HoverImgFx15(el) {
_classCallCheck(this, HoverImgFx15);
this.DOM = {
el: el
};
this.DOM.reveal = document.createElement('div');
this.DOM.reveal.className = 'hover-reveal';
this.totalImages = 5;
var inner = '';
for (var i = 0; i <= this.totalImages - 1; ++i) {
inner += "<div class="hover-reveal__img" style="position: absolute; background-image:url(".concat(this.DOM.el.dataset.img, ")"></div>");
}
this.DOM.reveal.innerHTML = inner;
this.DOM.el.appendChild(this.DOM.reveal);
this.DOM.revealImgs = _toConsumableArray(this.DOM.reveal.querySelectorAll('.hover-reveal__img'));
this.initEvents();
}
_createClass(HoverImgFx15, [{
key: "initEvents",
value: function initEvents() {
var _this = this;
this.positionElement = function (ev) {
var mousePos = getMousePos(ev);
var docScrolls = {
left: document.body.scrollLeft + document.documentElement.scrollLeft,
top: document.body.scrollTop + document.documentElement.scrollTop
};
_this.DOM.reveal.style.top = "".concat(mousePos.y + 20 - docScrolls.top, "px");
_this.DOM.reveal.style.left = "".concat(mousePos.x + 20 - docScrolls.left, "px");
};
this.mouseenterFn = function (ev) {
_this.positionElement(ev);
_this.showImage();
};
this.mousemoveFn = function (ev) {
return requestAnimationFrame(function () {
_this.positionElement(ev);
});
};
this.mouseleaveFn = function () {
_this.hideImage();
};
this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
}
}, {
key: "showImage",
value: function showImage() {
var _this2 = this;
TweenMax.killTweensOf(this.DOM.revealImgs);
this.tl = new TimelineMax({
onStart: function onStart() {
_this2.DOM.reveal.style.opacity = 1;
TweenMax.set(_this2.DOM.el, {
zIndex: 1000
});
}
}).set(this.DOM.revealImgs, {
opacity: 0
});
for (var i = 0; i <= this.totalImages - 1; ++i) {
TweenMax.set(this.DOM.revealImgs[i], {
x: "".concat((this.totalImages - 1 - i) * 5, "%"),
y: "".concat((this.totalImages - 1 - i) * 10, "%")
});
this.tl.add(new TweenMax(this.DOM.revealImgs[i], i === this.totalImages - 1 ? 1.2 : 0.55, {
ease: i === this.totalImages - 1 ? Quint.easeOut : Quad.easeOut,
startAt: i === this.totalImages - 1 ? {
opacity: 1,
x: '5%',
y: '10%'
} : {
opacity: 1
},
opacity: i === this.totalImages - 1 ? 1 : 0,
x: i === this.totalImages - 1 ? '0%' : null,
y: i === this.totalImages - 1 ? '0%' : null
}), i * 0.04);
}
}
}, {
key: "hideImage",
value: function hideImage() {
var _this3 = this;
TweenMax.killTweensOf(this.DOM.revealImgs);
this.tl = new TimelineMax({
onStart: function onStart() {
TweenMax.set(_this3.DOM.el, {
zIndex: 999
});
},
onComplete: function onComplete() {
TweenMax.set(_this3.DOM.el, {
zIndex: ''
});
TweenMax.set(_this3.DOM.reveal, {
opacity: 0
});
}
}).add(new TweenMax(this.DOM.revealImgs[this.totalImages - 1], 0.15, {
ease: Sine.easeOut,
opacity: 0
}));
}
}]);
return HoverImgFx15;
}();
_toConsumableArray(document.querySelectorAll('[data-fx="15"] > a, .hometext[data-fx="15"]')).forEach(function (link) {
return new HoverImgFx15(link);
}); // Demo purspose only: Preload all the images in the page..

var contentel = document.querySelector('.content');
_toConsumableArray(document.querySelectorAll('.block__title, .block__link, .content__text-link')).forEach(function (el) {
var imgsArr = el.dataset.img.split(',');
for (var i = 0, len = imgsArr.length; i <= len - 1; ++i) {
var imgel = document.createElement('img');
imgel.style.visibility = 'hidden';
imgel.style.width = 0;
imgel.src = imgsArr[i];
imgel.className = 'preload';
contentel.appendChild(imgel);
}
});
}
:root {
font-size: 50px;
}
body {
--color-text: #fff;
--color-bg: #181a1e;
--color-link: #fff;
--color-link-hover: #ffcbd6;
--color-blocklink: #515151;
--color-blocklink-hover: #fff;
--color-blocktitle: #fff;
--color-blocktitle-hover: #ff4081;
--color-text: #767676;
font-family: titling-gothic-fb, sans-serif;
min-height: 100vh;
color: #57585c;
color: var(--color-text);
background-color: #fff;
background-color: var(--color-bg);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
main {
position: relative;
width: 100%;
}
@keyframes loop {
0% { transform-origin: 0% 50%; transform: scale3d(0,1,1); }
50% { transform-origin: 0% 50%; transform: scale3d(1,1,1); }
51% { transform-origin: 100% 50%; }
100% { transform-origin: 100% 50%; transform: scale3d(0,1,1); }
}
.hover-reveal {
position: fixed;
width: 200px;
height: 150px;
top: 0;
left: 0;
pointer-events: none;
opacity: 0;
}
.hover-reveal__inner,
.hover-reveal__img {
width: 100%;
height: 100%;
position: relative;
}
.hover-reveal__deco {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
background-color: #181314;
}
.hover-reveal__img {
background-size: cover;
background-position: 50% 50%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.3.4/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</div>
<div class="block" data-fx="15">
<a class="block__title" data-img="http://placehold.it/300x300">Effect 15</a>

由于您使用的是TweenMax,因此可以使用TweenMax缓和功能。事实上,您已经这样做了,图像当前在动画结束时会减慢一点。这被称为easeOut。您可以在代码笔的第135行中看到easeOut效应:

this.tl.add(new TweenMax(this.DOM.revealImgs[i], i === this.totalImages - 1 ? 1.2 : 0.55, {
ease: i === this.totalImages - 1 ? Quint.easeOut : Quad.easeOut,
...etc...

这意味着,如果i等于totalImages-1,那么宽松就是Quint.easeOut,否则就是Quad.easeOut

您可以自由更改这些宽松类型!如果你想要更有弹性的感觉,你可以试试

ease:Back.easeOut

你可以在这里找到所有可能的放松功能:https://greensock.com/ease-visualizer/

更新

我添加了一个功能,可以调整图像的位置,而不仅仅是在鼠标移动时设置X和Y位置。现在你可以使用与上面相同的缓解功能:

// new function tweenElement

this.tweenElement = function (ev) {
var mousePos = getMousePos(ev);
var docScrolls = {
left: document.body.scrollLeft + document.documentElement.scrollLeft,
top: document.body.scrollTop + document.documentElement.scrollTop
};

// here you can add easing functions to tweenmax
TweenMax.to(_this.DOM.reveal, 1, {"top":mousePos.y + 20 - docScrolls.top, "left":mousePos.x + 20 - docScrolls.left, ease:Quad.easeOut})
};

// this function is changed and now calls tweenElement instead of positionElement when the mouse moves
this.mousemoveFn = function (ev) {
return requestAnimationFrame(function () {
_this.tweenElement(ev);
});
};

代码笔https://codepen.io/eerk/pen/BajOqrW?editors=0010

相关内容

最新更新