MediaWiki:Gadget-freezeAPNG.js: различия между версиями
Материал из Space Station 14 Вики
Pok (обсуждение | вклад) мНет описания правки Метка: отменено |
Pok (обсуждение | вклад) Нет описания правки |
||
| (не показаны 3 промежуточные версии этого же участника) | |||
| Строка 1: | Строка 1: | ||
( function ( $, mw ) { | (function($, mw){ | ||
function detectAndPrepare(img){ | |||
if (img.dataset.freezeProcessed) return; | |||
var xhr = new XMLHttpRequest(); | |||
xhr.open('GET', img.src, true); | |||
xhr.responseType = 'arraybuffer'; | |||
xhr.onload = function(){ | |||
if (xhr.status < 200 || xhr.status >= 300) return; | |||
var bytes = new Uint8Array(xhr.response); | |||
for (var i = 0; i < bytes.length - 4; i++){ | |||
if ( | |||
bytes[i] === 0x61 && | |||
bytes[i+1] === 0x63 && | |||
bytes[i+2] === 0x54 && | |||
bytes[i+3] === 0x4C | |||
){ | |||
prepareSwap(img); | |||
break; | |||
} | } | ||
return | } | ||
}; | |||
xhr.onerror = function(){ /* ignore */ }; | |||
xhr.send(); | |||
} | |||
function prepareSwap(img){ | |||
if (img.dataset.freezeProcessed) return; | |||
img.dataset.freezeProcessed = '1'; | |||
var origW = img.getAttribute('width'), | |||
origH = img.getAttribute('height'); | |||
var animated = img.cloneNode(true); | |||
animated.classList.add('freezeAPNG__animation'); | |||
if (origW) animated.setAttribute('width', origW); | |||
if (origH) animated.setAttribute('height', origH); | |||
var ow = img.naturalWidth || img.width || 0, | |||
oh = img.naturalHeight || img.height || 0; | |||
if (!ow || !oh) { | |||
return; | |||
} | } | ||
var canvas = document.createElement('canvas'); | |||
canvas.width = ow; | |||
canvas.height = oh; | |||
var ctx = canvas.getContext('2d'); | |||
try { | |||
ctx.drawImage(img, 0, 0, ow, oh); | |||
} catch (e) { | |||
return; | |||
} | |||
var frozenData; | |||
try { | |||
frozenData = canvas.toDataURL('image/png'); | |||
} catch (e) { | |||
return; | |||
} | |||
var container = img.closest('.freezeAPNG') || img.parentNode; | |||
if (!container) return; | |||
container.classList.add('freezeAPNG'); | |||
img.classList.add('freezeAPNG__freeze'); | |||
try { | |||
img.src = frozenData; | |||
} catch (e){ /* ignore */ } | |||
if (origW) img.setAttribute('width', origW); | |||
if (origH) img.setAttribute('height', origH); | |||
container.appendChild(animated); | |||
container.addEventListener('focusin', function(){ container.classList.add('freezeAPNG--active'); }); | |||
container.addEventListener('focusout', function(){ container.classList.remove('freezeAPNG--active'); }); | |||
} | var touchTimer = null; | ||
container.addEventListener('touchstart', function(e){ | |||
container.classList.add('freezeAPNG--active'); | |||
if (touchTimer) clearTimeout(touchTimer); | |||
touchTimer = setTimeout(function(){ | |||
container.classList.remove('freezeAPNG--active'); | |||
touchTimer = null; | |||
}, 1400); | |||
}, {passive: true}); | |||
container.addEventListener('touchend', function(){ if (touchTimer) { clearTimeout(touchTimer); touchTimer = null; container.classList.remove('freezeAPNG--active'); } }, {passive: true}); | |||
} | |||
$(function(){ | |||
$('.freezeAPNG img[src$=".png"]').each(function(){ | |||
var img = this; | |||
if (img.dataset.freezeProcessed) return; | |||
if (img.complete) { | |||
detectAndPrepare(img); | |||
} else { | |||
img.addEventListener('load', function(){ detectAndPrepare(this); }); | |||
} | |||
} )( jQuery, mediaWiki ); | }); | ||
}); | |||
})(jQuery, mediaWiki); | |||
Текущая версия от 20:46, 17 марта 2026
(function($, mw){
function detectAndPrepare(img){
if (img.dataset.freezeProcessed) return;
var xhr = new XMLHttpRequest();
xhr.open('GET', img.src, true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(){
if (xhr.status < 200 || xhr.status >= 300) return;
var bytes = new Uint8Array(xhr.response);
for (var i = 0; i < bytes.length - 4; i++){
if (
bytes[i] === 0x61 &&
bytes[i+1] === 0x63 &&
bytes[i+2] === 0x54 &&
bytes[i+3] === 0x4C
){
prepareSwap(img);
break;
}
}
};
xhr.onerror = function(){ /* ignore */ };
xhr.send();
}
function prepareSwap(img){
if (img.dataset.freezeProcessed) return;
img.dataset.freezeProcessed = '1';
var origW = img.getAttribute('width'),
origH = img.getAttribute('height');
var animated = img.cloneNode(true);
animated.classList.add('freezeAPNG__animation');
if (origW) animated.setAttribute('width', origW);
if (origH) animated.setAttribute('height', origH);
var ow = img.naturalWidth || img.width || 0,
oh = img.naturalHeight || img.height || 0;
if (!ow || !oh) {
return;
}
var canvas = document.createElement('canvas');
canvas.width = ow;
canvas.height = oh;
var ctx = canvas.getContext('2d');
try {
ctx.drawImage(img, 0, 0, ow, oh);
} catch (e) {
return;
}
var frozenData;
try {
frozenData = canvas.toDataURL('image/png');
} catch (e) {
return;
}
var container = img.closest('.freezeAPNG') || img.parentNode;
if (!container) return;
container.classList.add('freezeAPNG');
img.classList.add('freezeAPNG__freeze');
try {
img.src = frozenData;
} catch (e){ /* ignore */ }
if (origW) img.setAttribute('width', origW);
if (origH) img.setAttribute('height', origH);
container.appendChild(animated);
container.addEventListener('focusin', function(){ container.classList.add('freezeAPNG--active'); });
container.addEventListener('focusout', function(){ container.classList.remove('freezeAPNG--active'); });
var touchTimer = null;
container.addEventListener('touchstart', function(e){
container.classList.add('freezeAPNG--active');
if (touchTimer) clearTimeout(touchTimer);
touchTimer = setTimeout(function(){
container.classList.remove('freezeAPNG--active');
touchTimer = null;
}, 1400);
}, {passive: true});
container.addEventListener('touchend', function(){ if (touchTimer) { clearTimeout(touchTimer); touchTimer = null; container.classList.remove('freezeAPNG--active'); } }, {passive: true});
}
$(function(){
$('.freezeAPNG img[src$=".png"]').each(function(){
var img = this;
if (img.dataset.freezeProcessed) return;
if (img.complete) {
detectAndPrepare(img);
} else {
img.addEventListener('load', function(){ detectAndPrepare(this); });
}
});
});
})(jQuery, mediaWiki);