Курсоры, обновление документации

This commit is contained in:
2023-03-29 00:36:23 +04:00
parent 0ca319ae0f
commit 1ec33d6a80
20 changed files with 1118 additions and 106 deletions
-48
View File
@@ -1,48 +0,0 @@
# Список реализованых шуток
## `shake` - Форумо-трясение
Страница форума начинает трястись
Настройки:
* `chance` - Вероятность срабатывания в процентах (по умолчанию: `1%`)
* `directions` - Направление тряски (по умолчанию: `['top', 'left', 'bottom', 'left']`)
* `selector` - Селектор всех элементов, которые будут трястись (по умолчанию: `[id^=pun]`)
* `interval` - Частота тряски (по умолчанию: `100`)
* `force` - Сила тряски (по умолчанию: `0.5`)
## `mirror` - Зеркало
Элементы форума отражаются (по крайней мере, пытаются)
Настройки:
* `chance` - Вероятность срабатывания в процентах (по умолчанию: `30%`)
## `carnival` - Карнавал
Аватарки приобретают интересные цвета
Настройки:
* `chance` - Вероятность срабатывания в процентах (по умолчанию: `30%`)
* `selector` - Селектор всех элементов, которые будут перекрашены (по умолчанию: `img[src*="/avatars/"]`)
* `variant_chance` - Вероятность применения некоторого фильтра (по умолчанию: `20%`)
* `variants` - Список фильтров и диапозона случайных параметров
## `humanitarian_hell` - Ад гуманитария
Все "тся" заменяются на "ться", а все "ться" на "тся"
Настройки:
* `chance` - Вероятность срабатывания в процентах (по умолчанию: `20%`)
* `selector` - Селектор всех элементов, которые будут затронуты: `.post-content`)
## `crazy_letters` - Мама, Я сОшЛа С уМа!
иМеНа ЗаБоРчИкОм
Настройки:
* `chance` - Вероятность срабатывания в процентах (по умолчанию: `20%`)
* `selector` - Селектор всех элементов, которые будут затронуты: `.pa-author a`)
## `letter_chaos` - Буквенный хаос
Все буквы в словах, кроме первой и последней, перемешены.
Настройки:
* `chance` - Вероятность срабатывания в процентах (по умолчанию: `20%`)
* `selector` - Селектор всех элементов, которые будут затронуты: `.post-content`)
* `shuffle_chance` - Вероятность того, что буквы будут перемешаны (по умолчанию: `50%`)
+111 -9
View File
@@ -2,6 +2,7 @@
Базовое использование:
```html
<!-- Первоапрельские шутки -->
<script src="https://static.kozhilya.ru/script/april-fools.min.js"></script>
<script>
// Установка настроек системы
@@ -9,8 +10,114 @@
// ...
};
</script>
<!-- Конец первоапрельских шуток -->
```
---
## Полный список шуток
* `shake` — **Форумо-трясение**. Страница форума начинает трястись.
* `mirror` — **Зеркало**. Элементы форума отражаются... По крайней мере, пытаются.
* `carnival` — **Карнавал**. Аватарки приобретают интересные цвета.
* `humanitarian_hell` — **Ад гуманитария**. Все "тся" заменяются на "ться", а все "ться" на "тся".
* `crazy_letters` — **Мама, Я сОшЛа С уМа!** иМеНа ЗаБоРчИкОм
* `letter_chaos` — **Буквенный хаос**. Все буквы в словах, кроме первой и последней, перемешены.
* `cursor` — **Красивые курсоры**. Эффекты, следующие за курсором.
---
## Настройка шуток
Настройка шуток происходит при присвоении объекта `window.AprilJokes.settings`.
Это присвоедние должно произойти **после** загрузки скрипта.
Для всех шуток определны 2 общих поля:
```js
window.AprilJokes.settings = {
// ...
example: {
/**
* Активность шутки.
* Установите это значение `false`, что бы отключить шутку.
* Если `true`, то шутка будет обработана как обычно.
*/
enabled: true,
/**
* Вероятность срабатывания в процентах.
* Если установлено значение `100`, шутка будет срабатывать всегда.
* Если установлено значение `0`, шутка никогда не сработает.
* Лучше отключать шутку, используя enabled = false!
*/
chance: 20,
},
// ...
};
```
Полный список настроек с объяснениями вы можете посмотреть в файле [`settings.example.js`](./settings.example.js). Также представлен файл [`settings.compact.js`](./settings.compact.js), который также содержит все настройки, но без коментариев.
При этом, объективно, вставлять весь этот код в HTML-начало может быть "немного" неудобно, поэтому вы можете скачать код (кнопка "Raw" над файлом), изменить его, и загрузить в файлы форума, подключив скрипт таким образом:
```html
<!-- Первоапрельские шутки -->
<script src="https://static.kozhilya.ru/script/april-fools.min.js"></script>
<script src="https://forumstatic.ru/files/$$$$/$$/$$/$$$$$.js"></script>
<!-- Конец первоапрельских шуток -->
```
Заметьте, что во всех примерах приведены значения настроек по умолчанию. Вы *можете* удалять строки, значения по умолчанию которых вас устраивают.
Если вас интерсует только несколько шуток, вы можете использовать метод `disableAll()`, что бы выключить выполнение всех шуток, а потом включать отдельные шутки через установку настройки `enabled`:
```js
window.AprilJokes.disableAll();
window.AprilJokes.settings = {
// ...
example: {
enabled: true,
// ...
},
// ...
};
```
Обратите внимание, что метод `disableAll()` должен быть вызван *до* установки настроек `settings`, иначе заданные значения `enabled` будут сброшены.
---
### Настройка `shake` (Форумо-трясение)
Тряска элементов происходит путём изменения перечисленных направлений `margin` на значение ±`force` от стандартного значения.
> **Важно**: эта шутка может вызвать дискомфорт у пользователей. Настоятельно рекомендуется оставить вероятность срабатывания шутки (`chance`) очень низкой, что бы у пользователей была возможность избавиться от шутки простым обновлением страницы! Вариант отключить шутку (`enabled: false`) тоже вариант.
---
### Настройка `mirror` (Зеркало)
Элементы форума отражаются по весьма специфичному алгоритму... И из-за этого, шутка может работать *очень* плохо на некоторых дизайнах, поэтому данная шутка по умолчанию **отключена**
Для того, что бы попробовать, сработает ли шутка для вашего дизайна, используйте в консоли разработчика:
```js
window.AprilJokes.start("mirror", true);
```
Так же можете [посмотреть](./src/jokes/mirror.ts#L16) на метод `MirrorJoke.start`, что бы узнать как именно проиходит отражение.
---
### Настройка `cursor` (Красивые курсоры)
Эффекты, следующие за курсором.
Используются курсоры, предложенные в библотеке `tholman/cursor-effects` от Tim Holman ([Github](https://github.com/tholman/cursor-effects), [сайт](https://tholman.com/cursor-effects/)).
Код предусматривает, что одновременно активировано не более 1 курсора из этой библиотеки. Так же для каждого курсора установлен свой шанс срабатывания, однако из-за необходимости активации строго одного эффекта, предусмотрено использование весового коэффициента `weight`: если говорить просто, то чем больше это значение, то тем больше шанс срабатывания эффекта относительно других эффектов.
Так же для каждого эффекта определена настройка `enabled`, позволяющая отключить эффекты, и метод `disableAll` для отключения эффектов:
```js
window.AprilJokes.jokes.cursor.disableAll();
```
---
## Разработка дополнений
Использование для тестирования:
```html
<script src="https://static.kozhilya.ru/script/april-fools.js"></script>
@@ -26,10 +133,13 @@
'alert',
// Вызываемая функция шутки
settings => alert(settings.text),
settings => {
alert(settings.text)
},
// Стандартные настройки
{
enabled: true,
chance: 30,
text: 'Fooled!',
}
@@ -40,11 +150,3 @@
window.AprilJokes.start('alert', true);
</script>
```
В планах:
* Отключение отдельных шуток для пользователей.
О том, какие шутки определены по умолчанию, смотрите [на странице со списком их настроек](JOKES.md).
Если же вам интересна их реализация, то ищите её в папке [с их исходным кодом](src/jokes).
+39 -19
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+6
View File
@@ -8,6 +8,7 @@
"name": "mybb-april-fools",
"version": "1.0.0",
"dependencies": {
"cursor-effects": "^1.0.11",
"jquery": "^3.6.4",
"webpack-utf8-bom": "^1.4.0"
},
@@ -4188,6 +4189,11 @@
"node": "*"
}
},
"node_modules/cursor-effects": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/cursor-effects/-/cursor-effects-1.0.11.tgz",
"integrity": "sha512-P+nV/8Bfxk6RQvsg2uq7wW+WncJLBx8bmqT80QU1nlW15qSb5fpaCLfZ9nl2BZSRyz+u+sxKhAESPNoAkAfJmw=="
},
"node_modules/dargs": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz",
+1
View File
@@ -32,6 +32,7 @@
"watch": "webpack --watch"
},
"dependencies": {
"cursor-effects": "^1.0.11",
"jquery": "^3.6.4",
"webpack-utf8-bom": "^1.4.0"
},
+130
View File
@@ -0,0 +1,130 @@
window.AprilJokes.disableAll();
window.AprilJokes.jokes.cursor.disableAll();
window.AprilJokes.settings = {
shake: {
enabled: true,
chance: 1,
directions: ['top', 'left', 'bottom', 'left'],
force: 0.5,
selector: '[id^=pun]',
interval: 100,
},
mirror: {
enabled: false,
chance: 30,
},
carnival: {
enabled: true,
chance: 30,
selector: 'img[src*="/avatars/"]',
variant_chance: 20,
variants: {
'sepia({0}%)': 100,
'saturate({0}%)': 100,
'hue-rotate({0}deg)': 360,
'invert({0}%)': 100,
},
},
humanitarian_hell: {
enabled: true,
chance: 20,
selector: '.post-content',
},
crazy_letters: {
enabled: true,
chance: 20,
selector: '.pa-author a'
},
letter_chaos: {
enabled: true,
chance: 20,
selector: '.post-content',
shuffle_chance: 50,
},
cursor: {
enabled: true,
chance: 100,
effects: {
rainbow: {
enabled: true,
weight: 50,
length: 20,
size: 3,
colors: [
"#9400D3",
"#4B0082",
"#0000FF",
"#00FF00",
"#FFFF00",
"#FF7F00",
"#FF0000"
],
},
springy_emoji: {
enabled: true,
weight: 50,
emoji: "🤪",
},
emoji: {
enabled: true,
weight: 50,
emoji: ["🔥", "🐬", "🦆"],
},
fairy_dust: {
enabled: true,
weight: 50,
colors: ["#ff0000", "#00ff00", "#0000ff"],
},
ghost: {
enabled: true,
weight: 50,
},
trailing: {
enabled: true,
weight: 50,
particles: 15,
rate: 0.4,
baseImageSrc: null,
},
text_flag: {
enabled: true,
weight: 50,
text: "С днём смеха!",
color: "#000000",
font: "monospace",
textSize: 12,
gap: 14,
},
following_dot: {
enabled: true,
weight: 50,
color: "#323232a6",
},
bubbles: {
enabled: true,
weight: 50,
},
snowflake: {
enabled: false,
weight: 50,
},
clock: {
enabled: true,
weight: 50,
dateColor: string = "blue",
faceColor: string = "black",
secondsColor: string = "red",
minutesColor: string = "black",
hoursColor: string = "black",
},
},
},
}
+382
View File
@@ -0,0 +1,382 @@
/**
* Отключение всех шуток
*/
window.AprilJokes.disableAll();
/**
* Отключение всех эффектов курсора
*/
window.AprilJokes.jokes.cursor.disableAll();
window.AprilJokes.settings = {
/**
* Глобальные настройки
*/
core: {
/**
* Активность шутки.
* Установите это значение `false`, что бы отключить шутку.
* Если `true`, то шутка будет обработана как обычно.
*/
enabled: true,
/**
* Вероятность срабатывания в процентах.
* Если установлено значение `100`, шутка будет срабатывать всегда.
* Если установлено значение `0`, шутка никогда не сработает.
* Лучше отключать шутку, используя enabled = false!
*/
chance: 100,
},
/**
* Форумо-трясение
*
* Страница форума начинает трястись.
*
* @author Kozhilya
*/
shake: {
enabled: true,
chance: 1,
/**
* Направление тряски
*/
directions: ['top', 'left', 'bottom', 'left'],
/**
* Сила тряски
*/
force: 0.5,
/**
* Селектор всех элементов, которые будут трястись
*/
selector: '[id^=pun]',
/**
* Частота тряски
*/
interval: 100,
},
/**
* Зеркало
*
* Элементы форума отражаются (по крайней мере, пытаются)
*
* @author Kozhilya
*/
mirror: {
enabled: false,
chance: 30,
},
/**
* Карнавал
*
* Аватарки приобретают интересные цвета
*
* @author Kozhilya
*/
carnival: {
enabled: true,
chance: 30,
/**
* Селектор всех элементов, которые будут перекрашены.
*/
selector: 'img[src*="/avatars/"]',
/**
* Вероятность применения фильтра (может сработать нескольк раз).
*/
variant_chance: 20,
/**
* Список фильтров и диапозона случайных параметров.
*/
variants: {
'sepia({0}%)': 100,
'saturate({0}%)': 100,
'hue-rotate({0}deg)': 360,
'invert({0}%)': 100,
},
},
/**
* Ад гуманитария
*
* Все "тся" заменяются на "ться", а все "ться" на "тся"
*
* @author Kozhilya
*/
humanitarian_hell: {
enabled: true,
chance: 20,
/**
* Селектор всех элементов, которые будут затронуты.
*/
selector: '.post-content',
},
/**
* Мама, Я сОшЛа С уМа!
*
* иМеНа ЗаБоРчИкОм
*
* @author Kozhilya
*/
crazy_letters: {
enabled: true,
chance: 20,
/**
* Селектор всех элементов, которые будут затронуты.
*/
selector: '.pa-author a'
},
/**
* **Буквенный хаос**
*
* Все буквы в словах, кроме первой и последней, перемешены.
*
* @author Kozhilya
*/
letter_chaos: {
enabled: true,
chance: 20,
/**
* Селектор всех элементов, которые будут затронуты
*/
selector: '.post-content',
/**
* Вероятность того, что буквы будут перемешаны
*/
shuffle_chance: 50,
},
/**
* **Красивый курсор**
*
* Эффекты, следующие за курсором
*
* @author Tim Holman
* @author Kozhilya
*
* @link https://tholman.com/cursor-effects/
*/
cursor: {
enabled: true,
chance: 100,
/**
* Список эффектов курсора
*/
effects: {
/**
* Радужный след за курсором
*/
rainbow: {
enabled: true,
weight: 50,
/**
* Длина полосы
*/
length: 20,
/**
* Ширина полосы
*/
size: 3,
/**
* Цвета полос (сверху вниз)
*/
colors: [
"#9400D3",
"#4B0082",
"#0000FF",
"#00FF00",
"#FFFF00",
"#FF7F00",
"#FF0000"
],
},
/**
* Цепочка из эмодзи "на резинке" под курсором
*/
springy_emoji: {
enabled: true,
weight: 50,
/**
* Висящий эмодзи
*/
emoji: "🤪",
},
/**
* Падающие от курсора эмодзи
*/
emoji: {
enabled: true,
weight: 50,
/**
* Падающие эмодзи
*/
emoji: ["🔥", "🐬", "🦆"],
},
/**
* Падающие от курсора пылинки
*/
fairy_dust: {
enabled: true,
weight: 50,
/**
* Цвет пылинок
*/
colors: ["#ff0000", "#00ff00", "#0000ff"],
},
/**
* След "зависших" курсоров
*/
ghost: {
enabled: true,
weight: 50,
},
/**
* След курсоров "на резинке"
*/
trailing: {
enabled: true,
weight: 50,
/**
* Количество элементов
*/
particles: 15,
/**
* Скорость частиц
*/
rate: 0.4,
/**
* Ссылка на картинку с курсором
* Используйте `null`, что бы использовать картинку курсора по умолчанию
*/
baseImageSrc: null,
},
/**
* Текст, развивающийся флагом от курсора
*/
text_flag: {
enabled: true,
weight: 50,
/**
* Отображаемый текст
*/
text: "С днём смеха!",
/**
* Цвет текста
*/
color: "#000000",
/**
* Шрифт текста
*/
font: "monospace",
/**
* Размер текста
*/
textSize: 12,
/**
* Растояние между бквами
*/
gap: 14,
},
/**
* Точка, преследующая курсор
*/
following_dot: {
enabled: true,
weight: 50,
/**
* Цвет догоняющей точки
*/
color: "#323232a6",
},
/**
* Пузырьки от курсора
*/
bubbles: {
enabled: true,
weight: 50,
},
/**
* Снежинки, летящие от курсора
*
* Отключено, потому что сейчас не зима :D
*/
snowflake: {
enabled: false,
weight: 50,
},
/**
* Циферблат вокруг курсора
*/
clock: {
enabled: true,
weight: 50,
/**
* Цвет даты
*/
dateColor: string = "blue",
/**
* Цвет циферблата
*/
faceColor: string = "black",
/**
* Цвет секундной стрелки
*/
secondsColor: string = "red",
/**
* Цвет минутной стрелки
*/
minutesColor: string = "black",
/**
* Цвет часовой стрелки
*/
hoursColor: string = "black",
},
},
},
}
+35 -2
View File
@@ -2,6 +2,11 @@
* Объект настроек шутки
*/
export interface JokeSettings {
/**
* Флаг блокировки срабатывания
*/
enabled: boolean;
/**
* Вероятность срабатывания в процентах
*/
@@ -23,9 +28,36 @@ export abstract class Joke {
settings: JokeSettings;
/**
* Флаг, указывающий, должна ли шутка быть запущена
* Проверка вероятности
*
* @param {number} chance Вероятность срабатывания
* @returns {boolean} Флаг срабатывания (true - сработало)
*/
enabled: boolean = true;
check(chance: number): boolean {
return Math.random() < 0.01 * chance;
}
/**
* Разблокировать шутку
*/
enable() {
this.settings.enabled = true;
}
/**
* Заблокировать шутку
*/
disable() {
this.settings.enabled = false;
}
/**
* Переключить блокировку шутки
* @param value Новое значение
*/
toggle(value: boolean|null = null) {
this.settings.enabled = (value === null) ? !this.settings.enabled : value;
}
/**
* Запуск шутки
@@ -43,3 +75,4 @@ export abstract class StopableJoke extends Joke
*/
abstract stop(): void;
}
+57 -12
View File
@@ -5,31 +5,38 @@ import { Joke, JokeSettings } from "./joke";
*
* @author Kozhilya
*/
export class AprilFoolsJokeClass {
export class JokerClass {
/**
* Проверка вероятности
*
* @param {number} chance Вероятность срабатывания
* @returns {boolean} Флаг срабатывания (true - сработало)
*/
static check(chance: number): boolean {
check(chance: number): boolean {
return Math.random() < 0.01 * chance;
}
/**
* Добавление шутки
*
* @param joke
* @param joke Объект шутки
*/
add(joke: Joke): void {
this.jokes[joke.id] = joke;
}
/**
* Регистрация новой шутки
*
* @param id Идентификатор шутки
* @param handler Метод, выполняющий шутку
* @param settings Объект настроек шутки
*/
addCustom(id: string, handler: Function, settings: JokeSettings|null = null) {
const joke = new class extends Joke {
id = id;
settings: JokeSettings = { chance: 10 };
settings: JokeSettings = { chance: 10, enabled: true };
start() {
handler.call(this, this.settings);
@@ -41,8 +48,9 @@ export class AprilFoolsJokeClass {
this.add(joke);
}
core_settings = new CoreSettings;
/**
* Получение полного списка настроек
*/
get settings(): SettingsMap {
const result: SettingsMap = {};
@@ -73,6 +81,38 @@ export class AprilFoolsJokeClass {
}
}
/**
* Разблокировать систему
*/
enable() {
this.core_settings.enabled = true;
}
/**
* Заблокировать систему
*/
disable() {
this.core_settings.enabled = false;
}
/**
* Разблокировать все шутки
*/
enableAll() {
for (const key of Object.keys(this.jokes)) {
this.jokes[key].enable();
}
}
/**
* Заблокировать все шутки
*/
disableAll() {
for (const key of Object.keys(this.jokes)) {
this.jokes[key].disable();
}
}
/**
* Запуск шутки
*
@@ -85,7 +125,7 @@ export class AprilFoolsJokeClass {
const joke = this.jokes[id];
if (!forced && !AprilFoolsJokeClass.check(joke.settings.chance)) {
if (!forced && (!joke.settings.enabled || !this.check(joke.settings.chance))) {
return;
}
@@ -106,10 +146,17 @@ export class AprilFoolsJokeClass {
const month = today.getMonth() + 1; // Note that getMonth() returns 0-indexed month, so we need to add 1
const day = today.getDate();
if (month === 4 && day === 1 && AprilFoolsJokeClass.check(this.core_settings.chance)) {
if (month !== 4 || day !== 1 || !this.core_settings.enabled || !this.check(this.core_settings.chance)) {
return;
}
this.startAll();
}
}
/**
* Общие настройки системы
*/
core_settings = new CoreSettings;
/**
* Перечисление всех шуток
@@ -131,9 +178,7 @@ interface SettingsMap {
[key: string]: JokeSettings;
}
/**
*
*/
class CoreSettings implements JokeSettings {
chance = 100;
enabled = true;
}
+4 -2
View File
@@ -1,6 +1,6 @@
import { Joke, JokeSettings, StopableJoke } from "../joke";
import $ from "jquery";
import { AprilFoolsJokeClass } from "../handler";
import { JokerClass } from "../joker";
/**
* **Карнавал**
@@ -19,7 +19,7 @@ export class CarnivalJoke extends Joke {
const filters: string[] = [];
for (const entry of Object.entries(this.settings.variants)) {
if (!AprilFoolsJokeClass.check(this.settings.variant_chance)) {
if (!this.check(this.settings.variant_chance)) {
continue;
}
@@ -34,6 +34,8 @@ export class CarnivalJoke extends Joke {
}
export class CarnivalJokeSettings implements JokeSettings {
enabled: boolean = true;
chance: number = 30;
/**
+2
View File
@@ -28,6 +28,8 @@ export class CrazyLettersJoke extends Joke {
}
export class CrazyLettersJokeSettings implements JokeSettings {
enabled: boolean = true;
chance: number = 20;
/**
+2
View File
@@ -54,6 +54,8 @@ export class CrazyPunctuationJoke extends Joke {
}
export class CrazyPunctuationJokeSettings implements JokeSettings {
enabled: boolean = true;
chance: number = 20;
/**
+320
View File
@@ -0,0 +1,320 @@
import { Joke, JokeSettings, StopableJoke } from "../joke";
import $ from "jquery";
import { Interface } from "readline";
// import * as cursor_effects from "cursor-effects";
const cursor_effects = require("cursor-effects");
/**
* **Красивый курсор**
*
* Эффекты, следующие за курсором
*
* @author Tim Holman
* @link https://tholman.com/cursor-effects/
*/
export class CursorEffectsJoke extends StopableJoke {
id = 'cursor_effects';
settings = new CursorEffectsJokeSettings;
active_cursor_effect: any;
/**
* Разблокировать все варианты курсоров
*/
enableAll() {
for (const key of Object.keys(this.settings.effects)) {
this.settings.effects[<CursorEffectsEnum> key].enabled = true;
}
}
/**
* Заблокировать все варианты курсоров
*/
disableAll() {
for (const key of Object.keys(this.settings.effects)) {
this.settings.effects[<CursorEffectsEnum> key].enabled = false;
}
}
private weight(effect: CursorEffectsEnum): number {
const s = this.settings.effects[effect];
return s.enabled ? s.weight : 0;
}
getRandomEffect(): CursorEffectsEnum {
const elements = Object.keys(CursorEffectsEnum).map(e => <CursorEffectsEnum>e);
const totalWeight = elements.reduce((sum, element) => sum + this.weight(element), 0);
const randomWeight = Math.random() * totalWeight;
let currentWeight = 0;
for (const element of elements) {
currentWeight += this.weight(element);
if (randomWeight <= currentWeight) {
return element;
}
}
throw new Error("Тебя быть тут не должно...");
}
start(): void {
const effect = this.getRandomEffect();
const settings = this.settings.effects[effect];
this.active_cursor_effect = resolveCursorEffectsEnum(effect, settings);
}
stop(): void {
this.active_cursor_effect.destroy();
}
}
enum CursorEffectsEnum {
Rainbow = 'rainbow',
FairyDust = 'fairy_dust',
SpringyEmoji = 'springy_emoji',
Emoji = 'emoji',
Ghost = 'ghost',
Trailing = 'trailing',
TextFlag = 'text_flag',
FollowingDot = 'following_dot',
Bubbles = 'bubbles',
Snowflake = 'snowflake',
Clock = 'clock'
}
function resolveCursorEffectsEnum(effect: CursorEffectsEnum|string, options: CursorEffectsSetting): any {
switch (effect) {
case CursorEffectsEnum.Rainbow:
return cursor_effects.rainbowCursor(options);
case CursorEffectsEnum.FairyDust:
return cursor_effects.fairyDustCursor(options);
case CursorEffectsEnum.SpringyEmoji:
return cursor_effects.springyEmojiCursor(options);
case CursorEffectsEnum.Emoji:
return cursor_effects.emojiCursor(options);
case CursorEffectsEnum.Ghost:
return cursor_effects.ghostCursor(options);
case CursorEffectsEnum.Trailing:
return cursor_effects.trailingCursor(options);
case CursorEffectsEnum.TextFlag:
return cursor_effects.textFlag(options);
case CursorEffectsEnum.FollowingDot:
return cursor_effects.followingDotCursor(options);
case CursorEffectsEnum.Bubbles:
return cursor_effects.bubbleCursor(options);
case CursorEffectsEnum.Snowflake:
return cursor_effects.snowflakeCursor(options);
case CursorEffectsEnum.Clock:
return cursor_effects.clockCursor(options);
}
}
export class CursorEffectsJokeSettings implements JokeSettings {
enabled: boolean = true;
chance: number = 100;
effects: { [key in CursorEffectsEnum]?: CursorEffectsSetting } = {
/**
* Радужный след за курсором
*/
[CursorEffectsEnum.Rainbow]: new class extends DefaultCursorEffectsSetting {
/**
* Длина полосы
*/
length: number = 20;
/**
* Ширина полосы
*/
size: number = 3;
/**
* Цвета полос (сверху вниз)
*/
colors: string[] = [
"#9400D3",
"#4B0082",
"#0000FF",
"#00FF00",
"#FFFF00",
"#FF7F00",
"#FF0000"
];
},
/**
* Цепочка из эмодзи "на резинке" под курсором
*/
[CursorEffectsEnum.SpringyEmoji]: new class extends DefaultCursorEffectsSetting {
/**
* Висящий эмодзи
*/
emoji: string = "🤪"
},
/**
* Падающие от курсора эмодзи
*/
[CursorEffectsEnum.Emoji]: new class extends DefaultCursorEffectsSetting {
/**
* Падающие эмодзи
*/
emoji: string[] = ["🔥", "🐬", "🦆"]
},
/**
* Падающие от курсора пылинки
*/
[CursorEffectsEnum.FairyDust]: new class extends DefaultCursorEffectsSetting {
/**
* Цвет пылинок
*/
colors: string[] = ["#ff0000", "#00ff00", "#0000ff"];
},
/**
* След "зависших" курсоров
*/
[CursorEffectsEnum.Ghost]: new DefaultCursorEffectsSetting,
/**
* След курсоров "на резинке"
*/
[CursorEffectsEnum.Trailing]: new class extends DefaultCursorEffectsSetting {
/**
* Количество элементов
*/
particles: number = 15;
/**
* Скорость частиц
*/
rate: number = 0.4;
/**
* Ссылка на картинку с курсором
* Используйте `null`, что бы использовать картинку курсора по умолчанию
*/
baseImageSrc: string | null = null;
},
/**
* Текст, развивающийся флагом от курсора
*/
[CursorEffectsEnum.TextFlag]: new class extends DefaultCursorEffectsSetting {
/**
* Отображаемый текст
*/
text: string = "С днём смеха!";
/**
* Цвет текста
*/
color: string = "#000000";
/**
* Шрифт текста
*/
font: string = "monospace";
/**
* Размер текста
*/
textSize: number = 12;
/**
* Растояние между бквами
*/
gap: number = 14;
/**
* Размер... чего-то.
*/
size: number = 3;
},
/**
* Точка, преследующая курсор
*/
[CursorEffectsEnum.FollowingDot]: new class extends DefaultCursorEffectsSetting {
/**
* Цвет догоняющей точки
*/
color: string = "#323232a6";
},
/**
* Пузырьки от курсора
*/
[CursorEffectsEnum.Bubbles]: new DefaultCursorEffectsSetting,
/**
* Снежинки, летящие от курсора
*
* Отключено, потому что сейчас не зима :D
*/
[CursorEffectsEnum.Snowflake]: new class extends DefaultCursorEffectsSetting {
weight: number = 0;
},
/**
* Циферблат вокруг курсора
*/
[CursorEffectsEnum.Clock]: new class extends DefaultCursorEffectsSetting {
/**
* Цвет даты
*/
dateColor: string = "blue";
/**
* Цвет циферблата
*/
faceColor: string = "black";
/**
* Цвет секундной стрелки
*/
secondsColor: string = "red";
/**
* Цвет минутной стрелки
*/
minutesColor: string = "black";
/**
* Цвет часовой стрелки
*/
hoursColor: string = "black";
},
};
}
interface CursorEffectsSetting {
[key: string]: any;
}
class DefaultCursorEffectsSetting implements CursorEffectsSetting {
/**
* Флаг возможности срабатывания
*/
enabled: boolean = true;
/**
* Весовой коэффициент вероятности курсора
*/
weight: number = 50;
}
+2
View File
@@ -23,6 +23,8 @@ export class HumanitarianHellJoke extends Joke {
}
export class HumanitarianHellJokeSettings implements JokeSettings {
enabled: boolean = true;
chance: number = 20;
/**
+4 -2
View File
@@ -1,6 +1,6 @@
import { Joke, JokeSettings, StopableJoke } from "../joke";
import $ from "jquery";
import { AprilFoolsJokeClass } from "../handler";
import { JokerClass } from "../joker";
/**
* **Буквенный хаос**
@@ -18,7 +18,7 @@ export class LetterChaosJoke extends Joke {
private shuffleLetters(word: string): string {
// Check if the word has two or more letters
if ((word.length < 3) || !AprilFoolsJokeClass.check(this.settings.shuffle_chance)) {
if ((word.length < 3) || !this.check(this.settings.shuffle_chance)) {
return word;
}
@@ -48,6 +48,8 @@ export class LetterChaosJoke extends Joke {
}
export class LetterChaosJokeSettings implements JokeSettings {
enabled: boolean = true;
chance: number = 20;
/**
+2
View File
@@ -22,5 +22,7 @@ export class MirrorJoke extends Joke {
}
export class MirrorJokeSettings implements JokeSettings {
enabled: boolean = false;
chance: number = 30;
}
+8 -6
View File
@@ -63,13 +63,20 @@ export class ShakeJoke extends StopableJoke {
}
export class ShakeJokeSettings implements JokeSettings {
enabled: boolean = true;
chance: number = 1;
/**
* Направление тряски
* Направление тряски (тряска происходит путём изменения перечисленных направлений margin на значение ±force от стандартного значения)
*/
directions: string[] = ['top', 'left', 'bottom', 'left'];
/**
* Сила тряски - насколько отклоняется элемент от стандартного значения
*/
force: number = 0.5;
/**
* Селектор всех элементов, которые будут трястись
*/
@@ -79,11 +86,6 @@ export class ShakeJokeSettings implements JokeSettings {
* Частота тряски
*/
interval: number = 100;
/**
* Сила тряски
*/
force: number = 0.5;
}
export interface ShakeJokeMargin {
+5 -3
View File
@@ -1,4 +1,4 @@
import { AprilFoolsJokeClass } from "./handler";
import { JokerClass } from "./joker";
import { Joke } from "./joke";
import { ShakeJoke } from "./jokes/shake";
import { HumanitarianHellJoke } from "./jokes/humanitarian_hell";
@@ -7,9 +7,10 @@ import { CarnivalJoke } from "./jokes/carnival";
import { CrazyLettersJoke } from "./jokes/crazy_letters";
import { CrazyPunctuationJoke } from "./jokes/crazy_punctuation";
import { LetterChaosJoke } from "./jokes/letter_chaos";
import { CursorEffectsJoke } from "./jokes/cursor"
(window as any).AprilJokes = ((jokes: JokeClassList): AprilFoolsJokeClass => {
const cl = new AprilFoolsJokeClass();
(window as any).AprilJokes = ((jokes: JokeClassList): JokerClass => {
const cl = new JokerClass();
jokes.forEach(joke => {
cl.add(new joke());
@@ -26,6 +27,7 @@ import { LetterChaosJoke } from "./jokes/letter_chaos";
CrazyLettersJoke,
CrazyPunctuationJoke,
LetterChaosJoke,
CursorEffectsJoke,
]);
interface JokeClassList extends Array<new () => Joke> {}
+6 -1
View File
@@ -4,7 +4,12 @@
"noImplicitAny": true,
"module": "es6",
"target": "es5",
"allowJs": true
"allowJs": true,
"moduleResolution": "node",
"typeRoots": [
"./node_modules/@types",
"./types"
]
},
"files": ["src/main.ts"]
}