MediaWiki:FlipCounter.js: differenze tra le versioni
Vai alla navigazione
Vai alla ricerca
Contenuto aggiunto Contenuto cancellato
Wedhro (rosica | curriculum) Nessun oggetto della modifica |
Wedhro (rosica | curriculum) (Annullata la modifica 2581617 di Wedhro (discussione)) |
||
Riga 1: | Riga 1: | ||
*/ |
|||
var initializedCounter = false; |
var initializedCounter = false; |
||
var myCounter; |
var myCounter; |
||
Riga 397: | Riga 398: | ||
initialDigitCheck(options.value); |
initialDigitCheck(options.value); |
||
}; |
}; |
||
/* |
Versione delle 20:21, 1 mar 2018
*/
var initializedCounter = false;
var myCounter;
var flipCounter = function(divId, options) {
// Default values
var defaults = {
value: 0,
inc: 1,
pace: 1000,
auto: true,
tFH: 39,
bFH: 64,
fW: 53,
bOffset: 390
};
options = options || {};
divId = typeof divId !== 'undefined' && divId !== '' ? divId : 'flip-counter';
var div = $('#' + divId);
for(var opt in defaults) {
options[opt] = (opt in options) ? options[opt] : defaults[opt];
}
var nextCount = null;
var best = {
q: null,
pace: 0,
inc: 0
};
// Imposta il valore del contatore e avvia l'animazione per il nuovo valore
// Parametri:
// n: Nuovo valore
this.setValue = function(n) {
if(isNumber(n)) {
var x = options.value;
var y = n;
options.value = n;
digitCheck(x, y);
}
return this;
};
// Imposta l'incremento per il contatore ma non avvia l'animazione
// Parametri:
// n: Incremento
this.setIncrement = function(n) {
options.inc = isNumber(n) ? n : defaults.inc;
return this;
};
// Imposta il passo per il contatore, serve solo se auto == true
// Parametri:
// n: Nuovo ritmo
this.setPace = function(n) {
options.pace = isNumber(n) ? n : defaults.pace;
return this;
};
// Imposta l'autoincremento
// Parametri:
// a: Se true l'incremento è automatico, se è false no
this.setAuto = function(a) {
if(a && !options.auto) {
options.auto = true;
doCount();
}
if(!a && options.auto) {
if(nextCount) {
clearNext();
}
options.auto = false;
}
return this;
};
// Aumenta il contatore di un'animazione basandosi sul valore di inc
this.step = function() {
if(!options.auto) {
doCount();
}
return this;
};
// Aggiunge un numero al contatore senza influire su inc o pace
// Parametri:
// n: Numero da aggiungere
this.add = function(n) {
if(isNumber(n)) {
var x = options.value;
options.value += n;
var y = options.value;
digitCheck(x, y);
}
return this;
};
// Sottrae un numero al contatore senza influire su inc o pace
// Parametri:
// n: Numero da sottrarre
this.subtract = function(n) {
if(isNumber(n)) {
var x = options.value;
options.value -= n;
if (options.value >= 0) {
var y = options.value;
}
else {
var y = '0';
options.value = 0;
}
digitCheck(x, y);
}
return this;
};
// Incrementa il contatore animando secondo inc e pace
// Parametri:
// n: Incremento
// t: Durata in millisecondi
// p: Passo desiderato se è impostata la durata
this.incrementTo = function(n, t, p) {
if(nextCount) {
clearNext();
}
// Incremento intelligente
if(typeof t != 'undefined') {
var time = isNumber(t) ? t * 1000 : 10000;
var pace = typeof p != 'undefined' && isNumber(p) ? p : options.pace;
var diff = typeof n != 'undefined' && isNumber(n) ? n - options.value : 0;
best.q = null;
// Migliore stima iniziale
pace = (time / diff > pace) ? Math.round(time / (diff * 10)) * 10 : pace;
var cycles = Math.floor(time / pace);
var inc = Math.floor(diff / cycles);
var check = checkSmartValues(diff, cycles, inc, pace, time);
if(diff > 0) {
var i = 0;
while(check.result === false && i < 100) {
pace += 10;
cycles = Math.floor(time / pace);
inc = Math.floor(diff / cycles);
check = checkSmartValues(diff, cycles, inc, pace, time);
i++;
}
if(i == 100) {
// Non riesce a trovare le impostazioni migliori, usa le migliori trovate finora
options.inc = best.inc;
options.pace = best.pace;
}
else {
// Ha trovato le impostazioni migliori
options.inc = inc;
options.pace = pace;
}
doIncrement(n, true, cycles);
}
}
// Incremento regolare
else {
doIncrement(n);
}
};
// Restituisce il valore corrente del contatore
this.getValue = function() {
return options.value;
};
// Ferma tutti gli incrementi
this.stop = function() {
if(nextCount) {
clearNext();
}
return this;
};
//---------------------------------------------------------------------------//
function doCount() {
var x = options.value;
options.value += options.inc;
var y = options.value;
digitCheck(x, y);
if(options.auto === true) {
nextCount = setTimeout(doCount, options.pace);
}
}
function doIncrement(n, s, c) {
var val = options.value;
var smart = (typeof s == 'undefined') ? false : s;
var cycles = (typeof c == 'undefined') ? 1 : c;
if(smart === true) {
cycles--;
}
if(val != n) {
var x = options.value;
options.auto = true;
if(val + options.inc <= n && cycles != 0) {
val += options.inc;
}
else {
val = n;
}
options.value = val;
var y = options.value;
digitCheck(x, y);
nextCount = setTimeout(function() {doIncrement(n, smart, cycles);}, options.pace);
}
else {
options.auto = false;
}
}
function digitCheck(x, y) {
var digitsOld = splitToArray(x);
var digitsNew = splitToArray(y);
var xlen = digitsOld.length;
var ylen = digitsNew.length;
if(ylen > xlen) {
var diff = ylen - xlen;
while(diff > 0) {
addDigit(ylen - diff + 1, digitsNew[ylen - diff]);
diff--;
}
}
else if(ylen < xlen) {
var diff = xlen - ylen;
while(diff > 0) {
removeDigit(xlen - diff);
diff--;
}
}
for(var i = 0; i < xlen; i++) {
if(digitsNew[i] != digitsOld[i]) {
animateDigit(i, digitsOld[i], digitsNew[i]);
}
}
}
function animateDigit(n, oldDigit, newDigit) {
var speed = 80;
var step = 0;
var bp = [
'-' + options.fW + 'px -' + (oldDigit * options.tFH) + 'px',
(options.fW * -2) + 'px -' + (oldDigit * options.tFH) + 'px',
'0 -' + (newDigit * options.tFH) + 'px',
'-' + options.fW + 'px -' + (oldDigit * options.bFH + options.bOffset) + 'px',
(options.fW * -2) + 'px -' + (newDigit * options.bFH + options.bOffset) + 'px',
(options.fW * -3) + 'px -' + (newDigit * options.bFH + options.bOffset) + 'px',
'0 -' + (newDigit * options.bFH + options.bOffset) + 'px'
];
if(options.auto === true && options.pace <= 300) {
switch(n) {
case 0:
speed = options.pace/6;
break;
case 1:
speed = options.pace/5;
break;
case 2:
speed = options.pace/4;
break;
case 3:
speed = options.pace/3;
break;
default:
speed = options.pace/1.5;
break;
}
}
speed = (speed > 80) ? 80 : speed;
function animate() {
if(step < 7) {
var w = step < 3 ? 't' : 'b';
var a = $('#' + divId + '_' + w + '_d' + n);
if(a.length) {
a.css('background-position', bp[step]);
}
step++;
if(step != 3) {
setTimeout(animate, speed);
}
else {
animate();
}
}
}
animate();
}
// Crea un array di cifre per una manipolazione più facile
function splitToArray(input) {
return input.toString().split('').reverse();
}
// Aggiunge una nuova cifra
function addDigit(len, digit) {
var li = Number(len) - 1;
var newDigit = $('<ul></ul>').attr({
'class': 'cd',
'id': divId + '_d' + li
}).html('<li class="t" id="' + divId + '_t_d' + li + '"></li><li class="b" id="' + divId + '_b_d' + li + '"></li>');
if(li % 3 == 0) {
var newComma = $('<ul></ul>').attr('class', 'cd').html('<li class="s"></li>');
div.prepend(newComma);
}
div.prepend(newDigit);
$('#' + divId + '_t_d' + li).css('background-position', '0 -' + (digit * options.tFH) + 'px');
$('#' + divId + '_b_d' + li).css('background-position', '0 -' + (digit * options.bFH + options.bOffset) + 'px');
}
// Rimuove una cifra
function removeDigit(id) {
$('#' + divId + '_d' + id).remove();
// Controlla le virgole
var first = $(':first-child', div);
if((' ' + $(':first-child', first).attr('class') + ' ').indexOf(' s ') > -1) {
first.remove();
}
}
// Imposta le cifre corrette al caricamento
function initialDigitCheck(init) {
// Crea il numero giusto di cifre
var initial = init.toString();
var count = initial.length;
var bit = 1;
for(var i = 0; i < count; i++) {
var newDigit = $('<ul></ul>').attr({
'class': 'cd',
'id': divId + '_d' + i
}).html('<li class="t" id="' + divId + '_t_d' + i + '"></li><li class="b" id="' + divId + '_b_d' + i + '"></li>');
div.prepend(newDigit);
if(bit != count && bit % 3 == 0) {
var newComma = $('<ul></ul>').attr('class', 'cd').html('<li class="s"></li>');
div.prepend(newComma);
}
bit++;
}
// Le imposta al numero giusto
var digits = splitToArray(initial);
for(var i = 0; i < count; i++) {
$('#' + divId + '_t_d' + i).css('background-position', '0 -' + (digits[i] * options.tFH) + 'px');
$('#' + divId + '_b_d' + i).css('background-position', '0 -' + (digits[i] * options.bFH + options.bOffset) + 'px');
}
// Esegue la prima animazione
if(options.auto === true) {
nextCount = setTimeout(doCount, options.pace);
}
}
// Controlla i valori per l'incremento intelligente e restituisce il testo di debug
function checkSmartValues(diff, cycles, inc, pace, time) {
var r = {result: true};
// Controlla le condizioni, devono passare tutte per continuare:
// 1: Il valore non arrotondato di inc deve essere almeno 1
r.cond1 = (diff / cycles >= 1) ? true : false;
// 2: Non bisogna sorpassare il numero voluto
r.cond2 = (cycles * inc <= diff) ? true : false;
// 3: Bisogna essere entro 10 dal numero voluto
r.cond3 = (Math.abs(cycles * inc - diff) <= 10) ? true : false;
// 4: Il tempo totale deve essere entro 100ms dal tempo voluto
r.cond4 = (Math.abs(cycles * pace - time) <= 100) ? true : false;
// 5: Calculated time should not be over target time
r.cond5 = (cycles * pace <= time) ? true : false;
// Tiene traccia dei valori "abbastanza buoni" se non si riesce a trovare i migliori entro 100 cicli
if(r.cond1 && r.cond2 && r.cond4 && r.cond5) {
var q = Math.abs(diff - (cycles * inc)) + Math.abs(cycles * pace - time);
if(best.q === null) {
best.q = q;
}
if(q <= best.q) {
best.pace = pace;
best.inc = inc;
}
}
for(var i = 1; i <= 5; i++) {
if(r['cond' + i] === false) {
r.result = false;
break;
}
}
return r;
}
// http://stackoverflow.com/questions/18082/validate-numbers-in-javascript-isnumeric/1830844
function isNumber(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
function clearNext() {
clearTimeout(nextCount);
nextCount = null;
}
// Avviamento
initialDigitCheck(options.value);
};
/*