Top.Mail.Ru
Buddilov | Плюшки для дизайнера

Как сделать чернильный курсор

Шаг 1 СОЗДАЙТЕ БЛОК T123 и добавьте в него скрипт #1
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.8.0/gsap.min.js"></script> <svg class='ink-icon' xmlns="http://www.w3.org/2000/svg" version="1.1" width="800"><defs><filter id="goo"><feGaussianBlur in="SourceGraphic" stdDeviation="6" result="blur" /><feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 35 -15" result="goo" /><feComposite in="SourceGraphic" in2="goo" operator="atop"/></filter></defs></svg> <div class="page"><div class="container"><div class="child"><div class="content"><div id="button" class="HoverButton"></div></div></div></div><div class="stamp"><div class="circle"><p id="circle-content"></p></div></div> </div> <div id="cursor" class="Cursor"> </div>
Шаг 2 СОЗДАЙТЕ ЕЩЁ ОДИН БЛОК T123 и добавьте в него скрипт #2
<style> .ink-icon { display: none; } .Cursor { pointer-events: none; position: fixed; display: block; border-radius: 0; transform-origin: center center; top: 0; left: 0; z-index: 1000; filter: url("#goo"); mix-blend-mode: difference; } .Cursor span { position: absolute; display: block; width: 26px; height: 26px; border-radius: 20px; background-color: #fff; transform-origin: center center; transform: translate(-50%, -50%); } @media screen and (max-width: 480px) { .Cursor { display: none; } </style>
((.cursor span {background-color: #fff;} - меняем цвет курсора))
Шаг 3 СОЗДАЙТЕ ЕЩЁ ОДИН БЛОК T123 и добавьте в него скрипт #3
<script>function _defineProperty(obj, key, value) {if (key in obj) {Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true });} else {obj[key] = value;}return obj;}const cursor = document.getElementById("cursor"); const amount = 20; const sineDots = Math.floor(amount * 0.3); const width = 26; const idleTimeout = 150; let lastFrame = 0; let mousePosition = { x: 0, y: 0 }; let dots = []; let timeoutID; let idle = false; let hoverButton; let hoverTL; class HoverButton { constructor(id) {_defineProperty(this, "onMouseEnter", () => { this.hoverInAnim(); });_defineProperty(this, "hoverInAnim", () => { if (!this.hovered) { this.hovered = true; this.animatingHover = true; this.forceOut = false; TweenMax.fromTo( this.bg, this.timing, { x: "-112%" }, { x: "-12%", ease: Power3.easeOut, onComplete: () => { this.animatingHover = false; if (this.forceOut) { this.foceOut = false; this.hoverOutAnim(); } } }); } });_defineProperty(this, "onMouseLeave", () => { if (!this.animatingHover) { this.hoverOutAnim(); } else { this.forceOut = true; } });_defineProperty(this, "hoverOutAnim", () => { this.hovered = false; TweenMax.to(this.bg, this.timing, { x: "100%", ease: Power3.easeOut, onComplete: () => { } }); });this.hovered = false;this.animatingHover = false;this.forceOut = false;this.timing = 0.65;this.el = document.getElementById(id);this.bg = this.el.getElementsByClassName("bg")[0];this.el.addEventListener("mouseenter", this.onMouseEnter);this.el.addEventListener("mouseleave", this.onMouseLeave);}} class Dot { constructor(index = 0) { this.index = index; this.anglespeed = 0.05; this.x = 0; this.y = 0; this.scale = 1 - 0.05 * index; this.range = width / 2 - width / 2 * this.scale + 2; this.limit = width * 0.75 * this.scale; this.element = document.createElement("span"); TweenMax.set(this.element, { scale: this.scale }); cursor.appendChild(this.element); } lock() { this.lockX = this.x; this.lockY = this.y; this.angleX = Math.PI * 2 * Math.random(); this.angleY = Math.PI * 2 * Math.random(); } draw(delta) { if (!idle || this.index <= sineDots) { TweenMax.set(this.element, { x: this.x, y: this.y }); } else { this.angleX += this.anglespeed; this.angleY += this.anglespeed; this.y = this.lockY + Math.sin(this.angleY) * this.range; this.x = this.lockX + Math.sin(this.angleX) * this.range; TweenMax.set(this.element, { x: this.x, y: this.y }); } }} class Circle { constructor(id) { const el = document.getElementById(id); const parent = el.parentElement; parent.removeChild(el); const chars = el.innerText.split(""); chars.push(" "); for (let i = 0; i < chars.length; i++) { const span = document.createElement("span"); span.innerText = chars[i]; span.className = `char${i + 1}`; parent.appendChild(span); } }} function init() { window.addEventListener("mousemove", onMouseMove); window.addEventListener("touchmove", onTouchMove); hoverButton = new HoverButton("button"); // eslint-disable-next-line no-newnew Circle("circle-content"); lastFrame += new Date(); buildDots(); render(); } /*function limit(value, min, max) { return Math.min(Math.max(min, value), max); }*/ function startIdleTimer() { timeoutID = setTimeout(goInactive, idleTimeout); idle = false; } function resetIdleTimer() { clearTimeout(timeoutID); startIdleTimer(); } function goInactive() { idle = true; for (let dot of dots) { dot.lock(); } } function buildDots() { for (let i = 0; i < amount; i++) { let dot = new Dot(i); dots.push(dot); } } const onMouseMove = event => { mousePosition.x = event.clientX - width / 2; mousePosition.y = event.clientY - width / 2; resetIdleTimer(); }; const onTouchMove = () => { mousePosition.x = event.touches[0].clientX - width / 2; mousePosition.y = event.touches[0].clientY - width / 2; resetIdleTimer(); }; const render = timestamp => { const delta = timestamp - lastFrame; positionCursor(delta); lastFrame = timestamp; requestAnimationFrame(render); }; const positionCursor = delta => { let x = mousePosition.x; let y = mousePosition.y; dots.forEach((dot, index, dots) => { let nextDot = dots[index + 1] || dots[0]; dot.x = x; dot.y = y; dot.draw(delta); if (!idle || index <= sineDots) { const dx = (nextDot.x - dot.x) * 0.35; const dy = (nextDot.y - dot.y) * 0.35; x += dx; y += dy; } }); }; init(); </script>
Автор кода - https://mt-webdesign.ru
Модификации
Made on
Tilda