Решил провести эксперимент в конвертацию старых смайликов gif в apng. Результат мне не очень понравился, но решил поделиться. Сам скрипт по мотивам старого Деффовского скрипта. Скрипт поддерживает два формата apng и gif. Сами ссылки в двух форматах содержатся в файле https://forumstatic.ru/files/000f/3e/e5/46478.js . Скрипт заменяет стандартный вывод смайликов на вкладки. Название вкладок так же в файле https://forumstatic.ru/files/000f/3e/e5/46478.js . Пример:
"Пирожки": [
{
"apng": "https://iili.io/qFNCqnj.png",
"gif": "https://iili.io/qFkzEcG.gif",
"id": "pirozhki1"
},
Пирожки - название вкладки, pirozhki1 - то что будет выводится в поле ответа. CSS можно настроить на свой вкус. Вот скрипт как есть:
<!-- Смайлики вкладками в двух форматах apng и gif. НАЧАЛО -->
<style>
#SmileDrom{
background:transparent;
box-shadow:0 7px 10px rgba(50,50,50,.75);
padding:1em;
display:none;
position:relative;
z-index:9999;
}
#KnopK_Sml{
display:grid;
grid-template-columns:repeat(auto-fit,minmax(80px,1fr));
gap:4px;
margin-bottom:8px;
}
#KnopK_Sml div{
text-align:center;
height:28px;
line-height:28px;
cursor:pointer;
background:#eee;
font-size:12px;
}
#KnopK_Sml div.Active{
background:#837059;
color:#fff;
}
.smile_Cnt{
display:none;
overflow:auto;
max-height:430px;
}
.smile_Cnt img{
padding:3px;
max-height:65px;
max-width:67px;
cursor:pointer;
}
</style>
<script src="https://forumstatic.ru/files/000f/3e/e5/46478.js?v=1.0"></script>
<script>
(function(){
if(typeof window.SMILES_DATA === 'undefined'){
console.error('SMILES_DATA не найден');
return;
}
var SMILE_INDEX = {};
var LOAD_MODE = localStorage.getItem('smile_mode') || 'gif';
// apng | gif
/* ---------- Создание контейнера ---------- */
function createContainer(){
if($('#SmileDrom').length) return;
var html = `
<div id="SmileDrom">
<div style="margin-bottom:8px; text-align:right;">
<label style="cursor:pointer; font-size:12px;">
<input type="radio" name="smileMode" value="apng"> APNG
</label>
<label style="cursor:pointer; margin-left:10px; font-size:12px;">
<input type="radio" name="smileMode" value="gif"> GIF
</label>
</div>
<div id="KnopK_Sml"></div>
<div id="SmileTabs"></div>
</div>
`;
if($('#form-buttons').length){
$('#form-buttons').before(html);
} else if($('#post').length){
$('#post').after(html);
} else {
$('body').append(html);
}
$('input[name="smileMode"][value="'+LOAD_MODE+'"]').prop('checked', true);
}
/* ---------- Переключатель режима ---------- */
$(document).on('change','input[name="smileMode"]',function(){
LOAD_MODE = $(this).val();
localStorage.setItem('smile_mode', LOAD_MODE);
buildSmiles();
renderPosts();
});
/* ---------- Вкладки ---------- */
function buildTabs(){
var tabs = $('#KnopK_Sml');
tabs.empty();
var index = 0;
Object.keys(window.SMILES_DATA).forEach(function(name){
tabs.append('<div data-tab="'+index+'">'+name+'</div>');
index++;
});
$('#KnopK_Sml div').first().addClass('Active');
}
/* ---------- Смайлы ---------- */
function buildSmiles(){
var container = $('#SmileTabs');
container.empty();
SMILE_INDEX = {};
var tabIndex = 0;
Object.keys(window.SMILES_DATA).forEach(function(name){
var block = $('<div class="smile_Cnt"></div>');
if(tabIndex===0) block.show();
window.SMILES_DATA[name].forEach(function(smile){
SMILE_INDEX[smile.id] = smile;
var src = (LOAD_MODE === 'apng' && smile.apng)
? smile.apng
: smile.gif;
var img = $('<img>')
.attr('src', src)
.attr('alt', smile.id)
.attr('loading','lazy')
.on('error', function(){
if(this.src !== smile.gif){
this.src = smile.gif;
}
})
.on('click', function(){
insertSmile(smile.id);
});
block.append(img);
});
container.append(block);
tabIndex++;
});
}
/* ---------- Переключение вкладок ---------- */
$(document).on('click','#KnopK_Sml div',function(){
var index = $(this).data('tab');
$('#KnopK_Sml div').removeClass('Active');
$(this).addClass('Active');
$('.smile_Cnt').hide().eq(index).show();
});
/* ---------- Вставка ---------- */
function insertSmile(id){
if(typeof smile === 'function'){
smile('[smile='+id+']');
}
$('#SmileDrom').hide();
}
/* ---------- Рендер постов ---------- */
function renderPosts(){
$('.post-content').each(function(){
var html = $(this).html();
html = html.replace(/\[smile=(.*?)\]/g,function(match,id){
if(!SMILE_INDEX[id]) return match;
var s = SMILE_INDEX[id];
var src = (LOAD_MODE === 'apng' && s.apng)
? s.apng
: s.gif;
return '<img class="postimg" src="'+src+'" alt="'+id+'" onerror="this.src=\''+s.gif+'\'">';
});
$(this).html(html);
});
}
/* ---------- Кнопка ---------- */
function overrideButton(){
$('#button-smile')
.off('click')
.html('<img src="/i/blank.gif" style="cursor:pointer;">')
.on('click',function(e){
e.preventDefault();
$('#SmileDrom').toggle();
});
}
/* ---------- INIT ---------- */
$(document).ready(function(){
createContainer();
buildTabs();
buildSmiles();
renderPosts();
overrideButton();
});
})();
</script>
<!-- Смайлики вкладками в двух форматах apng и gif. КОНЕЦ -->Формат по умолчанию в скрипте:
var LOAD_MODE = localStorage.getItem('smile_mode') || 'gif';
Сейчас стоит gif, если поставить apng, то будет выводится apng, а в старых браузерах, в теории, gif, но я не проверял, могут быть накладки. Ставить скрипт в НТМЛ верх.