#javascript #html #css
Возникла потребность сделать как бы подсветку курсора на кнопках. То-бишь, чтоб когда провожу им по кнопке, то под курсором был какой-то градиент, фон, кружок.. что- не очень важно. Вопрос вот в чём: как это лучше реализовать? Перемещать что-то на самом фоне кнопки или просто создать прозрачный блок с бекграундом и перемещать уже его?
Ответы
Ответ 1
Мы не ищем лёгких путей! var curBg = document.querySelectorAll('.cur-bg'), mouseBg = document.getElementById('mouse-bg'); for (var i = 0; i < curBg.length; i++) { curBg[i].addEventListener('mousemove', foo, false); curBg[i].addEventListener('mouseleave', boo, false); } function foo(event) { mouseBg.style.display = 'block'; mouseBg.style.left = (event.clientX - 7) + 'px' mouseBg.style.top = (event.clientY - 7) + 'px' } function boo() { mouseBg.style.display = 'none'; } #mouse-bg { width: 15px; height: 15px; border-radius: 8px; background: linear-gradient(270deg, #41bd9d, #d72222); background-size: 400% 400%; display: none; position: absolute; pointer-events: none; -webkit-animation: AnimationName 1s ease infinite; -o-animation: AnimationName 1s ease infinite; animation: AnimationName 1s ease infinite; } @-webkit-keyframes AnimationName { 0% {background-position: 0% 50%} 50% {background-position: 100% 50%} 100% {background-position: 0% 50%} } @-o-keyframes AnimationName { 0% {background-position: 0% 50%} 50% {background-position: 100% 50%} 100% {background-position: 0% 50%} } @keyframes AnimationName { 0% {background-position: 0% 50%} 50% {background-position: 100% 50%} buttonОтвет 2
Самое простое - нарисовать png-шку и подменять ею внешний вид курсора при ховере на кнопке button { padding: 5px; } button:hover { cursor: url("https://i.stack.imgur.com/QRS91.png"), default; }Ответ 3
Всем спасибо за ответы! По примеру Kirill Korushkin сделал следующее: (без использования class) (function () { "use strict"; var EX = function (f1, f2) { /**упрощение работы с get и set. возвращает {get:function(){return f1;},set:f2}, если f2=true, то set:f1, если f2 нет, то set:undefined **/ return { get: function () { return f1; }, set: f2 === true ? f1 : f2 || undefined }; }; EX.auto = function (f1, f2) { /**тоже упрощает работу с get и set. возвращает: если f2=setget, EX(f1,true) если f2=set, {set:f1} если f2=get, {get:function(){return f1;}} если f2=что-то-другое, {get:f1} **/ switch (f2) { case "setget": return EX(f1, !!1); case "set": return { set: fl }; case "get": return { get: function () { return f1; } }; default: return { get: f1 } } }; Object.defineProperties(Object.prototype, { Ainit: { /**конструктор объектов. принимает объект и помещает его свойства в тот, на котором вызван Init. если объект содержит конструкции типа l:{set:...,get:...}(только как прямые потомки), то они будут использованы как get l или set l (isEnumerable,isConfigurable,isWritable). если свойство __isParam__ установлено в false l:{__isParam__:false}, то все свойства будут приниматься НЕ как параметры свойствa l (enumerable,configurable,writable,get,set) также get и set можно создать, используя имя самой функции l:function get(){}- get - создаст get с обёрткой l:{ get:function (){ return get(){}; } } - функция не будет выполняться сама set - создаст set setget - создаст set и get для одной функции auto- создаст get без обёртки функции(она выполнится сама при вызове get) **/ enumerable: false, configurable: false, writable: true, value: function (vl) { var tmp = {}; for (var nm in vl) { var s = vl[nm] || {}, isp = s.__isParam__, sn = s.name || ""; delete s.__isParam__; tmp[nm] = (s.set === undefined && s.get === undefined && s.enumerable === undefined && s.configurable === undefined && s.writable === undefined && ["get", "auto", "setget", "set"].indexOf(sn) === -1 && isp !== true) || isp === false ? { enumerable: false, configurable: true, writable: true, value: vl[nm] } : (s.constructor !== Function ? s : EX.auto(s, sn)); } Object.defineProperties(this, tmp); } } }); var cp, //cursor position whp = {}, //width, height, position, css position, this dsp, gtc, //styles rect, win, sensor = !!("ontouchmove" in document), //проверка на сенсор newElem = function (attrs, statics) { //используется вместо class для создания элементов function felement() { return Reflect.construct(HTMLElement, [], felement); } Object.setPrototypeOf(felement.prototype, HTMLElement.prototype); Object.setPrototypeOf(felement, HTMLElement); felement.prototype.Ainit(attrs); felement.Ainit(statics); return felement; }, offset = {}, getProps = function (th) { offset = th.getBoundingClientRect(); gtc = getComputedStyle(th); return { w: parseFloat(gtc.width), h: parseFloat(gtc.height), p: {top:offset.top,left:offset.left}, f: gtc.position === "fixed", e: th }; }; window.elems = []; //все элементы подсветки !sensor && document.addEventListener("mousemove", function (e) { cp = { t: event.clientY, l: event.clientX }; elems.forEach(function (th) { whp = getProps(th[0]); whp.b = getProps(th[1]); dsp = { l: whp.e.getAttribute("b-left-despos"), t: whp.e.getAttribute("b-top-despos") }; dsp.t ? ( dsp.t = Function("it,cursor", "return " + dsp.t)(whp, cp)) : ( dsp.t = cp.t - whp.b.h / 2 - whp.p.top //выравнивание центра элемента ); dsp.l ? ( dsp.l = Function("it,cursor", "return " + dsp.l)(whp, cp)) : ( dsp.l = cp.l - whp.b.w / 2 - whp.p.left); whp.b.e.style.left = dsp.l + "px"; whp.b.e.style.top = dsp.t + "px"; }); }); customElements.define("f-dplane", newElem({ connectedCallback: function () { if (sensor) { this.setAttribute("sensor", ""); return; } var back = document.createElement("div"); back.setAttribute("b", ""); back.style.top = "200%"; back.style.left = "200%"; this.appendChild(back); elems.push([this, back]); }, disconnectedCallback: function () { var elem, th = this; elems.forEach(function (el, ind) { if (el[0] === th) { elem = ind; } }); elems.splice(elem, 1); } })); })(); /*f-dplane default*/ f-dplane:not([sensor]){ cursor:default; display:flex; position:absolute; width:100%; height:100%; overflow:hidden; } f-dplane:not([sensor]) div{ position:absolute; background:radial-gradient(rgba(255, 255, 255, 0.13),transparent,transparent) no-repeat; height:100px; width:100px; } /*other*/ .gg{ width:400px; height:50px; outline:none; border:none; background:black; position:relative; padding:0; color:white; } .gg > f-dplane { top:0; } .gg > f-dplane > [b] { width:400px; height:200px; }
Количество кода на js можно уменьшить почти в 2 раза, если использовать class: (function () { "use strict"; var cp, //cursor position whp = {}, //width, height, position, css position, this dsp, gtc, //styles rect, win, sensor = !!("ontouchmove" in document), //проверка на сенсор offset = {}, getProps = function (th) { offset = th.getBoundingClientRect(); gtc = getComputedStyle(th); return { w: parseFloat(gtc.width), h: parseFloat(gtc.height), p: {top:offset.top,left:offset.left}, f: gtc.position === "fixed", e: th }; }; window.elems = []; //все элементы подсветки !sensor && document.addEventListener("mousemove", function (e) { cp = { t: event.clientY, l: event.clientX }; elems.forEach(function (th) { whp = getProps(th[0]); whp.b = getProps(th[1]); dsp = { l: whp.e.getAttribute("b-left-despos"), t: whp.e.getAttribute("b-top-despos") }; dsp.t ? ( dsp.t = Function("it,cursor", "return " + dsp.t)(whp, cp)) : ( dsp.t = cp.t - whp.b.h / 2 - whp.p.top //выравнивание центра элемента ); dsp.l ? ( dsp.l = Function("it,cursor", "return " + dsp.l)(whp, cp)) : ( dsp.l = cp.l - whp.b.w / 2 - whp.p.left); whp.b.e.style.left = dsp.l + "px"; whp.b.e.style.top = dsp.t + "px"; }); }); class fdplane extends HTMLElement{ connectedCallback() { if (sensor) { this.setAttribute("sensor", ""); return; } var back = document.createElement("div"); back.setAttribute("b", ""); back.style.top = "200%"; back.style.left = "200%"; this.appendChild(back); elems.push([this, back]); } disconnectedCallback() { var elem, th = this; elems.forEach(function (el, ind) { if (el[0] === th) { elem = ind; } }); elems.splice(elem, 1); } } customElements.define("f-dplane", fdplane); })(); /*f-dplane default*/ f-dplane:not([sensor]){ cursor:default; display:flex; position:absolute; width:100%; height:100%; overflow:hidden; } f-dplane:not([sensor]) div{ position:absolute; background:radial-gradient(rgba(255, 255, 255, 0.13),transparent,transparent) no-repeat; height:100px; width:100px; } /*other*/ .gg{ width:400px; height:50px; outline:none; border:none; background:black; position:relative; padding:0; color:white; } .gg > f-dplane { top:0; } .gg > f-dplane > [b] { width:400px; height:200px; }
Комментариев нет:
Отправить комментарий