<script src='https://unpkg.co/gsap@3/dist/gsap.min.js'></script>
<style>
@media screen and (max-width: 480px) {
.cb-cursor {
display: none;
}
}
body {
height: 100%;
margin: 0;
padding: 0;
background: #fff;
color: var(--BackgroundColorСircle);
font-family: var(--FontFamily);
font-size: 14px;
letter-spacing: normal;
line-height: normal;
text-align: left;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.cb-cursor {
position: fixed;
top: 0;
left: 0;
z-index: 150;
contain: layout style size;
pointer-events: none;
will-change: transform;
transition: opacity 0.3s, color 0.4s;
}
.cb-cursor:before {
content: "";
position: absolute;
top: -24px;
left: -24px;
display: block;
width: 48px;
height: 48px;
transform: scale(0);
background: currentColor;
border-radius: 50%;
transition: transform 0.3s ease-in-out, opacity 0.1s;
}
.cb-cursor-text {
position: absolute;
top: -18px;
left: -18px;
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
transform: scale(0) rotate(10deg);
opacity: 0;
color: var(--FontColor);
font-size: var(--FontSize);
line-height: 20px;
text-align: center;
letter-spacing: -0.01em;
transition: opacity 0.4s, transform 0.3s;
}
@supports (mix-blend-mode: exclusion) {
.cb-cursor.-exclusion, .cb-cursor.-opaque {
mix-blend-mode: exclusion;
}
}
@supports (mix-blend-mode: exclusion) {
.cb-cursor.-exclusion:before, .cb-cursor.-opaque:before {
background: white;
}
}
.cb-cursor.-normal, .cb-cursor.-text {
mix-blend-mode: normal;
}
.cb-cursor.-normal:before, .cb-cursor.-text:before {
background: var(--BackgroundColorСircleHoverText);
}
.cb-cursor.-inverse {
color: white;
}
.cb-cursor.-visible:before {
transform: scale(var(--СircleSize));
}
.cb-cursor.-visible.-active:before {
transform: scale(0.23);
transition-duration: 0.2s;
}
.cb-cursor.-pointer:before {
transform: scale(0.15);
}
.cb-cursor.-text:before {
opacity: 1;
transform: scale(var(--СircleTextScale));
}
.cb-cursor.-text .cb-cursor-text {
opacity: 1;
transform: scale(1);
}
.cb-cursor.-text.-active:before {
transform: scale(1.6);
transition-duration: 0.2s;
}
.cb-cursor.-opaque:before {
transform: scale(var(--СircleScale));
}
.cb-cursor.-opaque.-active:before {
transform: scale(var(--СircleScale));
}
.cb-cursor.-lg:before {
color: var(--BackgroundColorСircleHover);
transform: scale(var(--СircleScale));
}
.cb-cursor.-hidden:before {
transform: scale(0);
}
.-color-blue {
color: #1F28BF;
}
.-color-white {
color: #fff;
}
.cb-demo {
background: #fff;
}
.cb-demo-content {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
}
.cb-demo-container {
padding: 0 20px;
}
@media (min-width: 1600px) {
.cb-demo-container {
padding: 0 120px;
}
}
.cb-demo-row {
display: flex;
justify-content: center;
text-align: center;
margin: 30px 0;
}
@media (min-width: 1600px) {
.cb-demo-row {
margin: 60px 0;
}
}
.cb-demo-item {
position: relative;
flex: 1;
padding: 50px 30px;
margin: 0 20px;
color: #000;
}
@media (min-width: 1600px) {
.cb-demo-item {
padding: 90px 30px;
margin: 0 30px;
}
}
.cb-demo-item-title {
position: relative;
margin: 0 0 25px 0;
font-size: 30px;
font-weight: bold;
}
.cb-demo-item-text {
position: relative;
max-width: 70%;
margin: 0 auto;
color: rgba(0, 0, 0, 0.5);
font-size: 16px;
font-weight: 300;
line-height: 150%;
}
.cb-demo-item:before {
content: "";
display: block;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border-radius: 30px;
background: currentColor;
transition: box-shadow 0.2s;
}
</style>
<script>
function _classCallCheck(instance, Constructor) { if (!(instance instanceof 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; }
var Magnetic = /*#__PURE__*/function () {
"use strict";
function Magnetic(el) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
_classCallCheck(this, Magnetic);
this.el = $(el);
this.options = $.extend(true, {
y: 0.2,
x: 0.2,
s: 0.2,
rs: 0.7
}, this.el.data('magnetic') || options);
this.y = 0;
this.x = 0;
this.width = 0;
this.height = 0;
if (this.el.data('magnetic-init')) return;
this.el.data('magnetic-init', true);
this.bind();
}
_createClass(Magnetic, [{
key: "bind",
value: function bind() {
var _this = this;
this.el.on('mouseenter', function () {
_this.y = _this.el.offset().top - window.pageYOffset;
_this.x = _this.el.offset().left - window.pageXOffset;
_this.width = _this.el.outerWidth();
_this.height = _this.el.outerHeight();
});
this.el.on('mousemove', function (e) {
var y = (e.clientY - _this.y - _this.height / 2) * _this.options.y;
var x = (e.clientX - _this.x - _this.width / 2) * _this.options.x;
_this.move(x, y, _this.options.s);
});
this.el.on('mouseleave', function (e) {
_this.move(0, 0, _this.options.rs);
});
}
}, {
key: "move",
value: function move(x, y, speed) {
gsap.to(this.el, {
y: y,
x: x,
force3D: true,
overwrite: true,
duration: speed
});
}
}]);
return Magnetic;
}();
var Cursor = /*#__PURE__*/function () {
"use strict";
function Cursor(options) {
_classCallCheck(this, Cursor);
this.options = $.extend(true, {
container: "body",
speed: 0.7,
ease: "expo.out",
visibleTimeout: 300
}, options);
this.body = $(this.options.container);
this.el = $('<div class="cb-cursor"></div>');
this.text = $('<div class="cb-cursor-text"></div>');
this.init();
}
_createClass(Cursor, [{
key: "init",
value: function init() {
this.el.append(this.text);
this.body.append(this.el);
this.bind();
this.move(-window.innerWidth, -window.innerHeight, 0);
}
}, {
key: "bind",
value: function bind() {
var _this2 = this;
var self = this;
this.body.on('mouseleave', function () {
self.hide();
}).on('mouseenter', function () {
self.show();
}).on('mousemove', function (e) {
_this2.pos = {
x: _this2.stick ? _this2.stick.x - (_this2.stick.x - e.clientX) * 0.15 : e.clientX,
y: _this2.stick ? _this2.stick.y - (_this2.stick.y - e.clientY) * 0.15 : e.clientY
};
_this2.update();
}).on('mousedown', function () {
self.setState('-active');
}).on('mouseup', function () {
self.removeState('-active');
}).on('mouseenter', 'a,input,textarea,button', function () {
self.setState('-pointer');
}).on('mouseleave', 'a,input,textarea,button', function () {
self.removeState('-pointer');
}).on('mouseenter', 'iframe', function () {
self.hide();
}).on('mouseleave', 'iframe', function () {
self.show();
}).on('mouseenter', '[data-cursor]', function () {
self.setState(this.dataset.cursor);
}).on('mouseleave', '[data-cursor]', function () {
self.removeState(this.dataset.cursor);
}).on('mouseenter', '[data-cursor-text]', function () {
self.setText(this.dataset.cursorText);
}).on('mouseleave', '[data-cursor-text]', function () {
self.removeText();
}).on('mouseenter', '[data-cursor-stick]', function () {
self.setStick(this.dataset.cursorStick);
}).on('mouseleave', '[data-cursor-stick]', function () {
self.removeStick();
});
}
}, {
key: "setState",
value: function setState(state) {
this.el.addClass(state);
}
}, {
key: "removeState",
value: function removeState(state) {
this.el.removeClass(state);
}
}, {
key: "toggleState",
value: function toggleState(state) {
this.el.toggleClass(state);
}
}, {
key: "setText",
value: function setText(text) {
this.text.html(text);
this.el.addClass('-text');
}
}, {
key: "removeText",
value: function removeText() {
this.el.removeClass('-text');
}
}, {
key: "setStick",
value: function setStick(el) {
var target = $(el);
var bound = target.get(0).getBoundingClientRect();
this.stick = {
y: bound.top + target.height() / 2,
x: bound.left + target.width() / 2
};
this.move(this.stick.x, this.stick.y, 5);
}
}, {
key: "removeStick",
value: function removeStick() {
this.stick = false;
}
}, {
key: "update",
value: function update() {
this.move();
this.show();
}
}, {
key: "move",
value: function move(x, y, duration) {
gsap.to(this.el, {
x: x || this.pos.x,
y: y || this.pos.y,
force3D: true,
overwrite: true,
ease: this.options.ease,
duration: this.visible ? duration || this.options.speed : 0
});
}
}, {
key: "show",
value: function show() {
var _this3 = this;
if (this.visible) return;
clearInterval(this.visibleInt);
this.el.addClass('-visible');
this.visibleInt = setTimeout(function () {
return _this3.visible = true;
});
}
}, {
key: "hide",
value: function hide() {
var _this4 = this;
clearInterval(this.visibleInt);
this.el.removeClass('-visible');
this.visibleInt = setTimeout(function () {
return _this4.visible = false;
}, this.options.visibleTimeout);
}
}]);
return Cursor;
}(); // Init cursor
var cursor = new Cursor(); // Init magnetic
$('[data-magnetic]').each(function () {
new Magnetic(this);
});
</script>
<!--Настройки курсора-->
<style>
:root {
--BackgroundColorСircle: #000; /*Цвет курсора*/
--BackgroundColorСircleHover: #1F29BF; /*Цвет курсора при наведении*/
--СircleSize: 0.2; /*Размер курсора*/
--СircleScale: 3; /*Увеличение курсора при наведении, работает по принципу scale, чем выше цифра, тем больше круг*/
--FontFamily: "Helvetica", sans-serif; /*Название вашего шрифта*/
--FontSize: 14px; /*Размер шрифта в круге*/
--FontColor: #000; /*Цвет шрифта в круге*/
--BackgroundColorСircleHoverText: #1F29BF; /*Цвет круга при наведении с текстом*/
--СircleTextScale: 2; /*Увеличение круга с текстом, работает по принципу scale, чем выше цифра, тем больше круг*/
}
</style>
<!--Изменение курсора, при наведении на объект (увеличение)-->
<script>
$('.yourclass-element').attr('data-cursor','-lg');
</script>
<!--Подсказки, при наведении на объект (вместо Открыть пишем свое значение)-->
<script>
$('.yourclass-element').attr('data-cursor-text','Открыть');
</script>
<!--Примагничивание объекта к курсору, при наведении на объект-->
<script>
$('.yourclass-element').attr('data-magnetic','data-magnetic');
</script>
<!--Прилипание курсора к объекту с классом .yourclass-element-stick, при наведении на объект с классом .yourclass-elemen -->
<script>
$('.yourclass-element').attr('data-cursor-stick','.yourclass-element-stick');
</script>
<!--Инверсия курсора, при наведении -->
<script>
$('.yourclass-element').attr('data-cursor','-opaque');
</script>
<!--Добавляем своё изображение, при наведении-->
<script>
$('.cursor-img-1').attr('data-cursor','-img-1');
</script>
<style>
.cb-cursor.-img-1:before {
content: " ";
background-size: cover;
background-position: center;
background-image: url(url);
transform: scale(var(--СircleScale));
}
</style>