MediaWiki:Modules/random-logo.js

Материал из Мракопедии
Перейти к: навигация, поиск

Замечание. Возможно, после сохранения вам придётся очистить кэш своего браузера, чтобы увидеть изменения.

  • Firefox / Safari: Удерживая клавишу Shift, нажмите на панели инструментов Обновить либо нажмите Ctrl-F5 или Ctrl-R (⌘-R на Mac)
  • Google Chrome: Нажмите Ctrl-Shift-R (⌘-Shift-R на Mac)
  • Internet Explorer: Удерживая Ctrl, нажмите Обновить либо нажмите Ctrl-F5
  • Opera: Выберите очистку кэша в меню Инструменты → Настройки
/********************************************************************************
* Этот модуль управляет показом разных логотипов.
* 
* TODO:
* - заставить этот скрипт вызываться из тела страницы, чтобы избежать мерцания 
    логотипа при загрузке
********************************************************************************/

~function() {

function configureLogos(url, add, addFor, uniform, only, falloff, dual) {
  /* Добавление логотипов в ротацию (гыгы, прикинь, Бивис, он сказал "вротацию")

  Каждый логотип может быть добавлен больше одного раза, их вес суммируется.

  Весовые функции:
      uniform(вес)
          в любое время суток выпадает с указанным весом.
      only(вес, начало, конец, длительность_спада)
          начинает расти с нуля за некоторое время до начала, затем держится на уровне до конца и так же 
          плавно спадает.
      falloff(вес, начало, конец, длительность_спада, вес_неактивности)
          по аналогии с only, только в период неактивности вес не нулевой.
      dual(а_вес, а_начало, а_конец, б_вес, б_начало, б_конец)
          два диапазона постоянных значений с плавными переходами между.

  Чтобы посмотреть на диаграмму вероятностей, используйте вот этот скрипт: http://jsfiddle.net/toriningen/jf9cag7x/47/embedded/result/ и скопируйте туда весь блок с add().
  */

  add("default",         uniform(0.1));

  // редкие
  add("Нам пять лет",    uniform(0.1));
  add("Пека в пледе",    uniform(0.1));
  add("Замок с ведьмой", uniform(0.01));
  add("Замок",           uniform(0.01));
  add("Джа-Джа Бинкс",   uniform(0.001));
  add("Вракопедия",      uniform(0.001));
  add("НГ 2013",         uniform(0.001));
  add("НГ 2015",         uniform(0.001));
  add("Дятел",           uniform(0.001));

  // дневные
  add("Подмигивающий",   dual(1.0, 9, 18, 0.0, 24, 24));
  add("Nyan",            falloff(1.0, 12, 14, 2, 0.0001));
  add("Убийца Джефф",    falloff(0.01, 10, 17, 1, 0.0001));

  // ночные
  add("Многоглазый",     falloff(1.0, 23, 6, 1, 0.05));
  add("Убоа",            falloff(0.1, 23, 6, 1, 0.001));

  // персональные
  addFor("Musteline",       "Пека в пледе",    uniform(5.0));
  addFor("Ignis Fatuus",    "Игнис, вернись",  uniform(0.1));
  addFor("Jack The Ripper", "Замок с ведьмой", uniform(1.0));
  addFor("Jack The Ripper", "Замок",           uniform(1.0));

  /* Список логотипов по именам: */
  url("default",         "https://mrakopedia.org/w/animationlogo.gif");
  url("Nyan",            "https://mrakopedia.org/w/images/7/70/Logo-v2-0.gif");
  url("Вракопедия",      "https://mrakopedia.org/w/images/e/ec/FoolsDayLogo.gif");
  url("Джа-Джа Бинкс",   "https://mrakopedia.org/w/images/c/cd/%D0%9F%D1%80%D0%B5%D0%B4%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BF%D0%BE_%D0%BF%D0%BE%D0%B2%D0%BE%D0%B4%D1%83_%D0%BB%D0%BE%D0%B3%D0%BE%D1%82%D0%B8%D0%BF%D0%B0.png");
  url("Дятел",           "https://mrakopedia.org/w/images/b/bd/B-dyatel-135.png");
  url("Замок с ведьмой", "https://mrakopedia.org/w/images/4/4f/203316-05-02_17-11-27.png");
  url("Замок",           "https://mrakopedia.org/w/images/e/ec/Newlogo31.png");
  url("Игнис, вернись",  "http://ximages.net/images/53515651714604595618.png");
  url("Многоглазый",     "https://mrakopedia.org/logo26april.png");
  url("Нам пять лет",    "https://mrakopedia.org/w/images/a/ad/Fiveyears.png");
  url("НГ 2013",         "https://mrakopedia.org/w/images/2/2d/Logo3.png");
  url("НГ 2015",         "https://mrakopedia.org/w/images/a/a5/Nylogo.png");
  url("Пека в пледе",    "https://mrakopedia.org/w/images/1/1a/Mrakopeka.png");
  url("Подмигивающий",   "https://mrakopedia.org/w/animationlogo.gif");
  url("Убийца Джефф",    "https://mrakopedia.org/w/images/e/e8/UltraNewLogo.png");
  url("Убоа",            "https://mrakopedia.org/w/images/1/1e/Uboa_logo1.png");
}

function setLogo(url) {
  $('.mw-wiki-logo').css({
    'background-image': 'url(' + JSON.stringify(url) + ')',
    'visibility': 'visible'
  });
}

function randomizeLogo() {
  var d = new Date();
  var ts = (d.getHours() + d.getMinutes() / 60);
  var namedLogos = {};
  var stack = [];

  function url(name, url) { namedLogos[name] = url; }
  function add(name, prob) { stack.push([name, prob(ts)]); }
  function addFor(user, name, prob) {
    if (mw.user.getName() === user) {
      add(name, prob);
    }
  }

  function uniform(value) { return function(ts) { return value; } }

  function dual(highValue, highFrom, highTo, lowValue, lowFrom, lowTo) {
    highFrom = mod(highFrom, 24);
    highTo = mod(highTo, 24);
    lowFrom = mod(lowFrom, 24);
    lowTo = mod(lowTo, 24);

    function mod(x, m) {
      return ((x % m) + m) % m;
    }

    function inrange(x, f, t) {
      if (f <= t) {
        return (f <= x) && (x <= t);
      } else {
        return (f <= x) || (x <= t);
      }
    }

    function sigmoid(x, f, t) {
      return 1 - (Math.cos((x - f + (x < f) * 24) * Math.PI / mod(t - f, 24)) + 1) / 2;
    }

    function pure(ts) {
      if (inrange(ts, highFrom, highTo)) {
        return 1;
      } else if (inrange(ts, highTo, lowFrom)) {
        return 1 - sigmoid(ts, highTo, lowFrom);
      } else if (inrange(ts, lowFrom, lowTo)) {
        return 0;
      } else {
        return sigmoid(ts, lowTo, highFrom);
      }
    }
  
    return function(ts) {
      var value = pure(ts);
      return Math.min(highValue, lowValue) + value * Math.abs(highValue - lowValue);
    }
  }

  function falloff(weight, timeFrom, timeTo, falloffTime, falloffWeight) {
    return dual(weight, timeFrom, timeTo, falloffWeight, timeTo + falloffTime, timeFrom - falloffTime);
  }

  function only(weight, timeFrom, timeTo, falloff) {
    if (falloff == null) {
      falloff = 0.01;
    }
    return falloff(weight, timeFrom, timeTo, falloff, 0);
  }

  function search(v, cdf) {
    var l = 0;
    var r = cdf.length;
    var m;
  
    while ((r - l) > 1) {
      m = l + Math.floor((r - l) / 2);
      if (v < cdf[m]) {
        r = m;
      } else {
        l = m;
      }
    }
  
    return l;
  }

  function rollCDF() {
    var sum = 0;
    var cdf = [];
    var names = [];
  
    for (var i = 0; i < stack.length; i++) {
      names.push(stack[i][0]);
      cdf.push(sum);
      sum += stack[i][1];
    }
  
    var p = search(Math.random() * sum, cdf);
    return names[p];
  }
  
  function update() {
    setLogo(namedLogos[rollCDF()]);
  }
  
  configureLogos(url, add, addFor, uniform, only, falloff, dual);
  
  update();
}

$(function() {
  randomizeLogo();
  finishLoading('randomLogo');
});

}();