Gecko (firefox)
- -moz-cell – устаревший курсор (с версии Gecko 1.8 (Firefox 1.5), неподдерживается с версии Gecko 1.9.2 (Firefox 3.6)), вместо рекомендуется использовать курсор cell.
- -moz-alias – устаревший курсор (с версии Gecko 1.8 (Firefox 1.5), неподдерживается с версии Gecko 2 (Firefox 4)), вместо рекомендуется использовать курсор alias.
- -moz-context-menu – устаревший курсор (с версии Gecko 1.8 (Firefox 1.5), неподдерживается с версии Gecko 2 (Firefox 4)), вместо рекомендуется использовать курсор context-menu.
- -moz-copy – устаревший курсор (с версии Gecko 1.8 (Firefox 1.5), неподдерживается с версии Gecko 2 (Firefox 4)), вместо рекомендуется использовать курсор copy.
- -moz-spinning – устаревший курсор (с версии Gecko 1.7.1 (Firefox 1.0), неподдерживается с версии Gecko 2 (Firefox 4)), вместо рекомендуется использовать курсор progress.
- -moz-grab – указывает, что элемент может быть захвачен. Обычно отображается как расжатая рука. Аналогичен -webkit-grab.
- -moz-grabbing – указывает, что элемент в текущий момент захвачен. Обычно отображается как сжатая рука. Аналогичен -webkit-grabbing.
- -moz-zoom-in – указывает, что элемент может быть увеличен, или в данные момент уже увеличен. Аналогичен -webkit-zoom-in.
- -moz-zoom-out – указывает, что элемент может быть уменьшен, или в данные момент уже уменьшен. Аналогичен -webkit-zoom-out.
Webkit (safari, chrome)
- -webkit-grab – указывает, что элемент может быть захвачен. Обычно отображается как расжатая рука. Аналогичен -moz-grab.
- -webkit-grabbing – указывает, что элемент в текущий момент захвачен. Обычно отображается как сжатая рука. Аналогичен -moz-grabbing.
- -webkit-zoom-in – указывает, что элемент может быть увеличен, или в данные момент уже увеличен. Аналогичен -moz-zoom-in.
- -webkit-zoom-out – указывает, что элемент может быть уменьшен, или в данные момент уже уменьшен. Аналогичен -moz-zoom-out.
Зачем нужен собственный курсор?
С точки зрения UX применение собственного курсора — это, если не сказать больше, весьма мутная тема. Для начала — такой курсор вторгается на территорию стандартных механизмов поведения браузера и операционной системы. Добавление дополнительного визуального элемента поверх существующего значка курсора или полная замена стандартного значка приводят к изменению стандартного интерфейса сайта, к которому привыкли посетители.
В результате появление особого курсора на сайте мгновенно вызывает у всех удивление. Однако если речь идёт о ресурсе, дизайн которого допускает достаточно креативный подход к элементам фронтенда, то устоявшиеся, отчасти строгие, представления о дизайне можно подвергнуть сомнению, ориентируясь на ту пользу, которую что-то новое может принести конкретному проекту.
Собственный курсор может играть несколько ролей. Например, он может быть ярлыком, сообщающим посетителю о том, что указатель мыши находится над неким особым элементом. Или он может представлять собой индикатор прокрутки страницы. То есть — показывать пользователю то, насколько далеко он прокрутил страницу.
Ещё одна интересная идея заключается в том, чтобы сделать курсор неотъемлемой частью сайта, сделать его чем-то вроде смеси индикатора загрузки и элемента, участвующего в процессе смены одних страниц другими. Можно даже показывать некий контент, вроде картинок или видеоклипов, следующий за курсором, меняющийся при взаимодействии пользователя с разными частями сайта.
Одно из мест, где можно найти реализацию некоторых из вышеозвученных идей — это данная коллекция проекта Awwwards.
Примеры особых курсоров
Интересно… а можно сделать такой курсор самому? и как его сделать?
Есть много подходов к разработке собственного указателя мыши. Выбор конкретного подхода зависит от того, с какими именно технологиями лучше всего знаком разработчик. Можно, в плане рендеринга, положиться на WebGL (именно это решение используется на сайте
Курсоры для изменения размеров и прокрутки:
- CSS2CSS3e-resize, ne-resize, nw-resize, n-resize, se-resize, sw-resize, s-resize, w-resize – группа курсоров обозначаемых стрелочками, используется как правило при обозначении возможности подвинуть край какого-нибудь блока в соотетствующую сторону
- CSS3ew-resize, ns-resize, nesw-resize, nwse-resize
- Indicates a bidirectional resize cursor.
- CSS3col-resize – Indicates that the item/column can be resized horizontally. Often rendered as arrows pointing left and right with a vertical bar separating them.
- CSS3row-resize – Indicates that the item/row can be resized vertically. Often rendered as arrows pointing up and down with a horizontal bar separating them.
- CSS3all-scroll – Indicates that the something can be scrolled in any direction. Often rendered as arrows pointing up, down, left, and right with a dot in the middle.
Курсоры для ссылок и текущего статуса:
- CSS3context-menu – указывает, что для элемента под курсором доступно контекстное меню. Обычно отображается как стрелочка с небольшой иконкой меню рядом. Практически не поддреживается браузерами на основе WebKit (Safari, Chrome) и Gecko (Firefox)
- CSS2CSS3 help – указывает, что для элемента под курсором доступна справочная информация. Обычно отображается как стрелочка с небольшим вопросительным знаком рядом, либо как просто вопросительный знак.
- CSS2CSS3 pointer – указатель, такой типа по умолчанию используется для всех ссылок.
- CSS2CSS3 progress – указывает, что система занята выполнением задачи, но у пользователя есть возможность продолжать взаимодействие с системой.
- CSS2CSS3 wait – указывает, что система занята выполением задачи, и пользователю необходимо подождать.
Перемещение мыши
Для того чтобы использовать собственное изображение для курсора, нам надо воспользоваться стандартным событием
mousemove
и получить позицию курсора на экране. Это позволит нам применить полученные данные при настройке собственного курсора (то есть — элемента
). Поговорим о том, что происходит в
onMouseMove
Если мы будем рассматривать экран в виде области, в которой расположен курсор, мы сможем описать границы координатной системы, в которой происходят перемещения. Пусть координаты верхнего левого угла этого пространства будут {x: 0, y: 0}, а координаты нижнего правого угла — {x: 1, y: 1}.
Координатная система экрана
Прослушивая событие mousemove, мы получаем сведения о позиции мыши. Сведения о горизонтальной координате мы читаем из свойства e.clientX, а сведения о вертикальной координате — из свойства e.clientY. Эти значения выражены в пикселях, поэтому их, чтобы нормализовать, приведя к диапазону (0, 1), представляющему границы нашей системы координат, нужно поделить на длину соответствующей оси координат (то есть — на ширину или высоту области просмотра содержимого в пикселях).
И, наконец, мы проверяем, активен ли вышеупомянутый цикл рендеринга (то есть — узнаём, был ли до этого курсор в неподвижном состоянии) и, если надо, перезапускаем этот цикл, поступая так в том случае, если было зарегистрировано новое событие mousemove, что указывает на необходимость перемещения нашего курсора, следом за указателем мыши, в новое место.
onMouseMove(e) {
this.target.x = e.clientX / window.innerWidth;
this.target.y = e.clientY / window.innerHeight;
if (!this.raf) this.raf = requestAnimationFrame(this.render);
}
Полный список значений cursor
Браузеры на мобильных устройствах не поддерживают свойство cursor, но при этом в jQuery событие clik не сработает если у элемента нет свойства cursor: pointer.
Пользовательские курсоры:
- CSS2CSS3
uri
– курсор из ресурса, обозначенного в URI. Если браузер не может обработать первый курсор из списка курсоров, он должен попытаться обработать второй, и т.д. Если браузер не может обработать ни один из курсоров, определённый пользователем, он обязан использовать общий курсор в конце списка, например:.element { cursor: url(1.cur), url(1.png), auto; }
- CSS3
uri
x
y
– расширенный формат пользовательского курсора, когда возможно задать координаты точки для курсора, которая будет являться основной для данного курсора. Еслиx
иy
не заданы, то берется точка 0 0 – верхний левый угол изображения. Координаты можно задавать для каждого файла с изображением, например:.element { cursor: url(1.cur) 5 5, url(1.png) 7 7, auto; }
Доступные форматы изображений для курсоров зависят от браузера:
Internet Explorer Firefox Chrome Safari Opera .ani
анимированные курсоры> 6.0 – – – – .cur > 6.0 >1.5 >1.0 >3.0 – .png, .jpg, .gif* и другие форматы распозноваемые браузером как изображения – >1.5 >1.0 >3.0 – .svg – >4.0 >6.0 – – *Анимированные GIF не делают анимированных курсоров, отображается только первый кадр
Понятие курсора
Запрос к реляционной базе данных обычно возвращает несколько рядов
(записей) данных, но приложение за один раз обрабатывает лишь одну
запись. Даже если оно имеет дело одновременно с несколькими рядами
(например, выводит данные в форме электронных таблиц), их количество
по-прежнему ограничено.
Кроме того, при модификации, удалении или
добавлении данных рабочей единицей является ряд. В этой ситуации на
первый план выступает концепция курсора, и в таком контексте курсор –
указатель на ряд.
Курсор в SQL – это область в памяти базы данных, которая
предназначена для хранения последнего оператора SQL. Если текущий
оператор – запрос к базе данных, в памяти сохраняется и строка данных
запроса, называемая текущим значением, или текущей строкой курсора.
Указанная область в памяти поименована и доступна для прикладных
программ.
Обычно курсоры используются для выбора из базы данных некоторого
подмножества хранимой в ней информации. В каждый момент времени
прикладной программой может быть проверена одна строка курсора. Курсоры часто применяются в операторах SQL, встроенных в написанные
на языках процедурного типа прикладные программы.
В соответствии со стандартом SQL при работе с курсорами можно
выделить следующие основные действия:
В разных реализациях определениекурсора может иметь некоторые
отличия. Так, например, иногда разработчик должен явным образом
освободить выделяемую для курсорапамять.
После освобождения курсора
ассоциированная с ним память также освобождается. При этом становится
возможным повторное использование его имени. В других реализациях при закрытии курсораосвобождение памяти происходит неявным образом.
В некоторых случаях применение курсора неизбежно. Однако по
возможности этого следует избегать и работать со стандартными
командами обработки данных: SELECT, UPDATE, INSERT, DELETE.
Помимо
того, что курсоры не позволяют проводить операцииизменения над всем
объемом данных, скорость выполнения операций обработки данных
посредством курсора заметно ниже, чем у стандартных средств SQL.
Примечание о requestanimationframe
Логика нашего курсора основана на цикле
rAF
requestAnimationFrame
— это часть API
window
. Этот метод принимает коллбэк, который вызывается тогда, когда у системы имеется достаточно ресурсов для перерисовки экрана. При таком подходе мы отправляем браузеру запрос, уведомляющий его о том, что мы собираемся произвести анимирование чего-либо. Делается это путём вызова указанного коллбэка до следующей операции перерисовки экрана, до следующего кадра.
Обычно коллбэк requestAnimationFrame должен, после выполнения некоего внутреннего кода (например — обсчёта очередного шага анимации), позаботиться о новом собственном вызове. Это позволит данной функции постоянно вызываться, то есть — будет выполняться последовательный вызов этой функции и будет организован цикл рендеринга анимации.
Тут важен ещё один момент, который заключается в том, что rAF возвращает ID, который позволяет остановить этот цикл. То есть — у нас нет необходимости абсолютно всегда выполнять вышеописанный цикл. Например, остановить его можно тогда, когда пользователь не перемещает мышь.
Произвольный курсор
Вы также можете установить свой курсор в виде изображения:
cursor: url(<адрес>), url(<адрес>), …, <курсор>
Если указано несколько изображений, браузер будет переходить к следующему варианту, если не удалось загрузить текущее изображение. Заканчиваться выражение должно одним из предустановленных свойств, например, pointer. Если не указать такое ключевое слово, можно получить сообщение об ошибке “invalid property value”.
После изображения также можно указать пару чисел (со значениями не более 32), которые будут координатами для смещения изображения относительно верхнего левого угла. Например:
cursor: url(cursor.png) 4 8, auto;
Можно использовать разные графические форматы, в том числе SVG.
Реализация курсоров в среде ms sql server
SQLServer поддерживает три вида курсоров:
Различные типы многопользовательских приложений требуют и различных
типов организации параллельного доступа к данным. Некоторым
приложениям необходим немедленный доступ к информации об изменениях в
базе данных.
Это характерно для систем резервирования билетов. В
других случаях, например, в системах статистической отчетности, важна
стабильность данных, ведь если они постоянно модифицируются,
программы не смогут эффективно отображать информацию. Различным
приложениям нужны разные реализации курсоров.
В среде SQLServer типы курсоров различаются по предоставляемым
возможностям. Тип курсора определяется на стадии его создания и не
может быть изменен.
Некоторые типы курсоров могут обнаруживать изменения, сделанные другими пользователями в строках, включенных в
результирующий набор. Однако SQLServer отслеживает изменения таких
строк только на стадии обращения к строке и не позволяет
отслеживать изменения, когда строка уже считана.
Курсоры делятся на две категории: последовательные и прокручиваемые. Последовательные позволяют выбирать данные только в одном направлении
– от начала к концу. Прокручиваемые же курсоры предоставляют большую
свободу действий – допускается перемещение в обоих направлениях и
переход к произвольной строке результирующего набора курсора.
Если
программа способна модифицировать данные, на которые указывает курсор, он называется прокручиваемым и модифицируемым. Говоря о курсорах, не следует забывать об изолированности транзакций.
Когда
один пользователь модифицирует запись, другой читает ее при помощи
собственного курсора, более того, он может модифицировать ту же
запись, что делает необходимым соблюдение целостности данных.
SQLServer поддерживает курсорыстатические, динамические, последовательные и управляемые набором ключей.
В схеме со статическим курсором информация читается из базы данных
один раз и хранится в виде моментального снимка (по состоянию на
некоторый момент времени), поэтому изменения, внесенные в базу данных
другим пользователем, не видны.
На время открытия курсорасервер
устанавливает блокировку на все строки, включенные в его полный
результирующий набор. Статический курсор не изменяется после создания
и всегда отображает тот набор данных, который существовал на момент
его открытия.
Если другие пользователи изменят в исходной таблице включенные в курсор данные, это никак не повлияет на статический курсор.
В статический курсор внести изменения невозможно, поэтому он всегда
открывается в режиме “только для чтения”.
Динамический курсор поддерживает данные в “живом” состоянии, но это
требует затрат сетевых и программных ресурсов. При использовании динамических курсоров не создается полная копия исходных данных, а
выполняется динамическая выборка из исходных таблиц только при
обращении пользователя к тем или иным данным.
На время выборки сервер
блокирует строки, а все изменения, вносимые пользователем в полный
результирующий набор курсора, будут видны в курсоре. Однако если
другой пользователь внес изменения уже после выборки данных курсором,
то они не отразятся в курсоре .
Курсор, управляемый набором ключей, находится посередине между этими
крайностями. Записи идентифицируются на момент выборки, и тем самым
отслеживаются изменения .
Такой тип курсора полезен при реализации
прокрутки назад – тогда добавления и удаления рядов не видны, пока
информация не обновится, а драйвер выбирает новую версию записи, если
в нее были внесены изменения.
Последовательные курсоры не разрешают выполнять выборку данных в
обратном направлении. Пользователь может выбирать строки только от
начала к концу курсора . Последовательный курсор не хранит набор всех
строк.
Они считываются из базы данных, как только выбираются в курсоре, что позволяет динамически отражать все изменения, вносимые
пользователями в базу данных с помощью команд INSERT, UPDATE, DELETE.
В курсоре видно самое последнее состояние данных.
Статические курсоры обеспечивают стабильный взгляд на данные. Они
хороши для систем “складирования” информации: приложений для систем
отчетности или для статистических и аналитических целей. Кроме того, статический курсор лучше других справляется с выборкой большого
количества данных.
Напротив, в системах электронных покупок или
резервирования билетов необходимо динамическое восприятие обновляемой
информации по мере внесения изменений. В таких случаях используется динамический курсор. В этих приложениях объем передаваемых данных,
как правило, невелик, а доступ к ним осуществляется на уровне рядов
(отдельных записей). Групповой доступ встречается очень редко.
Синтаксис
Значение свойство указывается в следующем виде:
cursor: pointer;
При этом вместо pointer нужно указать нужное значение из таблицы со всеми видами значений ниже. По умолчанию установлено значение auto.
Специфические курсоры:
Данная группа курсоров работает только в конкретных браузерах и их не рекомендуется использовать в дизайне веб-страниц, вместо лучше использовать пользовательские курсоры подгруженные как изображения. А данную группу можно использовать при создании расширений и дополнений для конкретных браузеров.
Стандартные курсоры
Вид курсора можно задать с помощью значения – названия, например курсор со знаком вопроса:
Структура кода
Начнём с нескольких строк JavaScript-кода. Для начала мы создадим простой
и дадим ему имя
Cursor
. Конструктор этого класса содержит команды по настройке некоторых конфигурационных свойств объекта, касающихся скорости и позиционирования курсора. Тут же вызывается и метод
init
class Cursor {
constructor() {
this.target = { x: 0.5, y: 0.5 }; //координаты указателя мыши
this.cursor = { x: 0.5, y: 0.5 }; //координаты нового курсора
this.speed = 0.3; //скорость курсора
this.init();
}
}
Метод
init
отвечает за создание собственной области видимости для логики курсора. В этом методе мы решаем несколько задач. Так, мы сразу же вызываем вспомогательный метод для привязки к экземпляру класса двух основных методов, которыми пользуемся —
onMouseMove
render
. Затем мы подключаем прослушиватель события
mousemove
, который поставляет нам необходимые данные о перемещениях указателя мыши. И, наконец, мы регистрируем
requestAnimationFrame
init() {
this.bindAll();
window.addEventListener("mousemove", this.onMouseMove);
this.raf = requestAnimationFrame(this.render);
}
Установка своего курсора
Все браузеры дают возможность установить элементу свой курсор из файла по URL, например:
Вторым параметром задаются координаты активной точки, в которой регистрируется нажатие мыши. По умолчанию это левый верхний угол (0,0).
Цикл рендеринга
Теперь нам надо применить вычисленные значения к чему-то, что видно на экране. При реализации нашего подхода используются
, поэтому управлять мы можем практически всем, чем угодно. Обсудим это.
Сначала мы интерполируем значения, задающие позицию нашего курсора, основываясь на его текущей позиции и на позиции указателя мыши. Под «интерполяцией» мы понимаем вычисление необходимого значения на базе двух заданных значений. То есть, поиск следующей позиции, в которой должен оказаться курсор, должен быть основан на текущей позиции курсора и на той позиции, в которой находится указатель мыши, которым управляет пользователь. При таком подходе мы можем достаточно плавно перевести наш курсор в новое место.
Задержка перемещения курсора задаётся третьим аргументом функции lerp, который мы изначально, в конструкторе класса, задали как свойство speed. Это свойство принимает значение между 0 и 1. Чем ближе его значение к 0 — тем больше и задержка. А если оно равняется 1 — наш курсор перемещается в новую позицию моментально.
this.cursor.x = lerp(this.cursor.x, this.target.x, this.speed);
this.cursor.y = lerp(this.cursor.y, this.target.y, this.speed);
Далее, мы назначаем интерполированные значения CSS-переменным. Тут мы задаём переменные корневого элемента (тега
), поэтому обратиться к ним можно из любого CSS-селектора, который имеется в дереве DOM.
document.documentElement.style.setProperty("--cursor-x", this.cursor.x);
document.documentElement.style.setProperty("--cursor-y", this.cursor.y);
Обратите внимание на то, что
lerp
— это наша внутренняя вспомогательная функция следующего вида:
const lerp = (a, b, n) => (1 - n) * a n * b;
И, наконец, мы проверяем, совпадают ли, с учётом небольшого отклонения, позиции указателя мыши и нашего курсора. Если это так — это значит, что мышь остановилась и никуда не двигается. Поэтому мы останавливаем анимацию вместо того, чтобы её продолжать, и производим жёсткий возврат из метода для того чтобы не допустить ненужных операций рендеринга.
render() {
this.cursor.x = lerp(this.cursor.x, this.target.x, this.speed);
this.cursor.y = lerp(this.cursor.y, this.target.y, this.speed);
document.documentElement.style.setProperty("--cursor-x", this.cursor.x);
document.documentElement.style.setProperty("--cursor-y", this.cursor.y);
const delta = Math.sqrt(
Math.pow(this.target.x - this.cursor.x, 2)
Math.pow(this.target.y - this.cursor.y, 2)
);
if (delta < 0.001) {
cancelAnimationFrame(this.raf);
this.raf = null;
return;
}
this.raf = requestAnimationFrame(this.render);
}
Итоги
Вышеописанная реализация собственного курсора не ограничена возможностью перемещения обычной точки, как это сделано
. Подобная конструкция способна не только порадовать кошку, которая любит сидеть у компьютера. Она ещё и позволяет, например, анимировать
с помощью CSS, настраивать непрозрачность элементов или наборов элементов,
элементы, «подтягивать» элементы поближе к курсору по мере его перемещения на странице, показывать картинки и видеоклипы при перемещении курсора над определёнными словами. С её помощью можно достичь и многого другого.
То, о чём мы рассказали, имеет смысл воспринимать как начальную точку разработки собственного курсора для очередного креативного веб-проекта.
Делали ли вы когда-нибудь собственные курсоры для веб-сайтов?