Шрифт в постах

Стиль оформления

Тема

Дополнительно

Размер элементов форума
вверх
вниз

Shadows of Old

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Shadows of Old » Организационный раздел » Оформление профиля


Оформление профиля

Сообщений 1 страница 20 из 141

1

В этой теме можно попросить сделать себе аватар, а также примерить одну из форумных плашек, фонов и описание в профиле. Также можно попросить прикрепить к плашке тему дневника или заполнить твинков.

• В какой форме можно попросить ссылки в плашку или в твинков?
В абсолютно свободной, все найдём-поймём.
• Это все плашки и фоны?
Они будут постоянно пополняться, не волнуйтесь.
• А можно ли попросить сделать свою плашку или фон?
Можно. Приносите исходник, сделаем. Размеры для фонов 240x330, размеры для плашек 180x40.
• А будут ли какие-то уникальные плашки и фоны?
Да, будут. За участие в конкурсах.
• Можно ли приносить гиф-исходники?
Можно для плашек, если они по весу не превышают 500МБ.
• А это обязательно?
Нет, конечно, все исключительно по желанию.
• Поставить только тут?
Вы можете ставить плашки и фоны самостоятельно через "Профиль" -> "Дополнительно".

[html]
<script>
// --------- СОСТОЯНИЕ DOM ------------

let iframeDomReady = document.readyState !== 'loading';

document.addEventListener('DOMContentLoaded', function () {
    iframeDomReady = true;
    initializeIframeForm();
});

// --------- ЭКРАНИРОВАНИЕ ------------

function escapeAttr(value) {
    return String(value)
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '\'');
}

// --------- FILL BACKGROUNDS ------------

function labelBg(className, nameCategory, src) {
    const safeSrc = escapeAttr(src);
    return `
        <label class="${className}">
            <input
                type="radio"
                name="${nameCategory}"
                id="${safeSrc}"
                onchange="handleBgRadioChange()"
            >
            <img src="${safeSrc}" loading="lazy">
        </label>
    `;
}

function fillBgs(bgs) {
    const container = document.getElementById('bgContainer');

    if (!container) return;

    container.innerHTML = (Array.isArray(bgs) ? bgs : [])
        .map(function (bg) {
            return labelBg('profileBgLabel', 'profileBg', bg);
        })
        .join('');
}

// --------- FILL STRIPES ------------

function labelStripe(className, nameCategory, src) {
    const safeSrc = escapeAttr(src);
    return `
        <label class="${className}">
            <input
                type="radio"
                name="${nameCategory}"
                id="${safeSrc}"
                onchange="handleStripeRadioChange()"
            >
            <img src="${safeSrc}" loading="lazy">
        </label>
    `;
}

function fillStripes(stripes) {
    const container = document.getElementById('stripeContainer');

    if (!container) return;

    container.innerHTML = (Array.isArray(stripes) ? stripes : [])
        .map(function (stripe) {
            return labelStripe('profileStripeLabel', 'profileStripe', stripe);
        })
        .join('');
}

// --------- CUSTOM FIELD HANDLERS ------------

function handleStripeCustomInput() {
    const customField = document.getElementById('stripeCustomLabel');
    const customValue = customField ? customField.value : '';

    if (customValue.trim()) {
        document
            .getElementsByName('profileStripe')
            .forEach(function (radio) {
                radio.checked = false;
            });
    }

    updateProfilePreview();
}

function handleBgCustomInput() {
    const customField = document.getElementById('bgCustomLabel');
    const customValue = customField ? customField.value : '';

    if (customValue.trim()) {
        document
            .getElementsByName('profileBg')
            .forEach(function (radio) {
                radio.checked = false;
            });
    }

    updateProfilePreview();
}

function handleStripeRadioChange() {
    const customField = document.getElementById('stripeCustomLabel');

    if (customField) {
        customField.value = '';
    }

    updateProfilePreview();
}

function handleBgRadioChange() {
    const customField = document.getElementById('bgCustomLabel');

    if (customField) {
        customField.value = '';
    }

    updateProfilePreview();
}

// --------- USER DATA ------------

let userLatinName = '';
let userProfileUrl = '';
let userApplicationFormUrl = '';

let receivedStripes = [];
let receivedBackgrounds = [];
let profileDataReceived = false;
let profileRequestInterval = null;

function isAllowedParentOrigin(origin) {
    return /^https?:\/\/oldshadows\.rusff\.me(?::\d+)?$/.test(origin);
}

function applyReceivedProfileData() {
    if (!iframeDomReady) return;

    fillStripes(receivedStripes);
    fillBgs(receivedBackgrounds);

    const urlField = document.getElementById('applicationFormUrl');

    if (urlField && !urlField.value) {
        urlField.value = userApplicationFormUrl;
    }

    updateProfilePreview();
}

function sendProfileRequest() {
    window.parent.postMessage({
        eventName: 'profileFillingRequest'
    }, '*');
}

function startProfileRequesting() {
    sendProfileRequest();

    if (profileRequestInterval) {
        clearInterval(profileRequestInterval);
    }

    profileRequestInterval = setInterval(function () {
        if (profileDataReceived) {
            clearInterval(profileRequestInterval);
            profileRequestInterval = null;
            return;
        }

        sendProfileRequest();
    }, 1000);
}

// --------- COPY RESULTS ------------

function copyResults() {
    let copyContent = '';

    const cyrillicNameField = document.getElementById('cyrillicName');
    const applicationFormUrlField = document.getElementById('applicationFormUrl');
    const mainDescrField = document.getElementById('mainDescr');
    const addDescrField = document.getElementById('addDescr');
    const hrAddField = document.getElementById('hrAdd');

    const cyrillicName = cyrillicNameField
        ? cyrillicNameField.value.trim()
        : '';

    if (cyrillicName) {
        const applicationFormUrl =
            applicationFormUrlField?.value.trim() ||
            userApplicationFormUrl;

        const profileDescrName = mainDescrField
            ? mainDescrField.value
            : '';

        let profileForm =
            `<a href='${escapeAttr(applicationFormUrl)}'>${cyrillicName}</a>, ${profileDescrName}`;

        const profileAdd = addDescrField
            ? addDescrField.value
            : '';

        const defaultAdditionalDescription =
            `любое описание на ваш вкус <a href='ссылка на анкету персонажа'>имя на кириллице</a>`;

        const profileAddNotFilled =
            profileAdd.trim() === '' ||
            profileAdd === defaultAdditionalDescription;

        if (hrAddField?.checked) {
            profileForm += '<hr>';
        } else if (!profileAddNotFilled) {
            profileForm += '<br>';
        }

        if (!profileAddNotFilled) {
            profileForm += profileAdd;
        }

        copyContent +=
            `Форма профиля:\n` +
            `${String.fromCharCode(91)}code${String.fromCharCode(93)}` +
            `${profileForm}` +
            `${String.fromCharCode(91)}/code${String.fromCharCode(93)}\n\n`;
    }

    const stripeCustomField =
        document.getElementById('stripeCustomLabel');

    const stripeCustom = stripeCustomField
        ? stripeCustomField.value.trim()
        : '';

    let stripeForm = '';

    if (stripeCustom) {
        stripeForm = stripeCustom;
    } else {
        stripeForm = Array.from(
            document.getElementsByName('profileStripe')
        )
            .filter(function (element) {
                return element.checked;
            })
            .map(function (element) {
                return element.id;
            })
            .join('');
    }

    if (stripeForm) {
        copyContent +=
            `Плашка:\n` +
            `${String.fromCharCode(91)}img${String.fromCharCode(93)}` +
            `${stripeForm}` +
            `${String.fromCharCode(91)}/img${String.fromCharCode(93)}\n\n`;
    }

    const bgCustomField =
        document.getElementById('bgCustomLabel');

    const bgCustom = bgCustomField
        ? bgCustomField.value.trim()
        : '';

    let bgForm = '';

    if (bgCustom) {
        bgForm = bgCustom;
    } else {
        bgForm = Array.from(
            document.getElementsByName('profileBg')
        )
            .filter(function (element) {
                return element.checked;
            })
            .map(function (element) {
                return element.id;
            })
            .join('');
    }

    if (bgForm) {
        copyContent +=
            `Фон:\n` +
            `${String.fromCharCode(91)}img${String.fromCharCode(93)}` +
            `${bgForm}` +
            `${String.fromCharCode(91)}/img${String.fromCharCode(93)}\n\n`;
    }

    window.parent.postMessage({
        eventName: 'profileCopyInfoRequest',
        copyData: copyContent.trim()
    }, '*');
}

// --------- POST USER PROFILE UPDATE ------------

function updateProfilePreview() {
    if (!iframeDomReady) return;

    const cyrillicNameField =
        document.getElementById('cyrillicName');

    const applicationFormUrlField =
        document.getElementById('applicationFormUrl');

    const mainDescrField =
        document.getElementById('mainDescr');

    const addDescrField =
        document.getElementById('addDescr');

    const hrAddField =
        document.getElementById('hrAdd');

    if (
        !cyrillicNameField ||
        !applicationFormUrlField ||
        !mainDescrField ||
        !addDescrField ||
        !hrAddField
    ) {
        return;
    }

    const cyrillicName =
        cyrillicNameField.value.trim() ||
        userLatinName;

    const applicationFormUrl =
        applicationFormUrlField.value.trim() ||
        userApplicationFormUrl;

    const profileDescrName =
        mainDescrField.value;

    let profileForm =
        `<a href='${escapeAttr(applicationFormUrl)}'>${cyrillicName}</a>, ${profileDescrName}`;

    const profileAdd =
        addDescrField.value;

    const defaultAdditionalDescription =
        `любое описание на ваш вкус <a href='ссылка на анкету персонажа'>имя на кириллице</a>`;

    const profileAddNotFilled =
        profileAdd.trim() === '' ||
        profileAdd === defaultAdditionalDescription;

    if (hrAddField.checked) {
        profileForm += '<hr>';
    } else if (!profileAddNotFilled) {
        profileForm += '<br>';
    }

    if (!profileAddNotFilled) {
        profileForm += profileAdd;
    }

    const stripeCustomField =
        document.getElementById('stripeCustomLabel');

    const stripeCustom = stripeCustomField
        ? stripeCustomField.value.trim()
        : '';

    let stripeForm = '';

    if (stripeCustom) {
        stripeForm = stripeCustom;
    } else {
        stripeForm = Array.from(
            document.getElementsByName('profileStripe')
        )
            .filter(function (element) {
                return element.checked;
            })
            .map(function (element) {
                return element.id;
            })
            .join('');
    }

    const bgCustomField =
        document.getElementById('bgCustomLabel');

    const bgCustom = bgCustomField
        ? bgCustomField.value.trim()
        : '';

    let bgForm = '';

    if (bgCustom) {
        bgForm = bgCustom;
    } else {
        bgForm = Array.from(
            document.getElementsByName('profileBg')
        )
            .filter(function (element) {
                return element.checked;
            })
            .map(function (element) {
                return element.id;
            })
            .join('');
    }

    window.parent.postMessage({
        eventName: 'profileDemo',
        profileDescr: profileForm,
        stripe: stripeForm,
        background: bgForm
    }, '*');
}

// --------- STYLE AND FONT ------------

let initialStyleReceived = false;
let receivedTheme = 'pink';
let styleRequestInterval = null;
let styleRequestTimeout = null;

function applyIframeStyle(style, theme) {
    let appliedStyle = style;

    if (style === 'system') {
        appliedStyle = window
            .matchMedia('(prefers-color-scheme: dark)')
            .matches
            ? 'dark'
            : 'light';
    }

    if (appliedStyle !== 'dark') {
        appliedStyle = 'light';
    }

    if (typeof theme === 'string' && theme) {
        receivedTheme = theme;
    }

    document.body.classList.remove('light', 'dark');
    document.body.classList.add(appliedStyle);

    document.body.classList.remove('pink', 'green');
    document.body.classList.add(receivedTheme);
}

function applyIframeFont(data) {
    const fontSize = Number(data.fontsize) || 12;
    const fontFamily = data.fontfam || '0';
    const allFontSize = Number(data.allFontSize) || 12;

    document.documentElement.style.setProperty(
        '--iframe-post-font-size',
        fontSize + 'px'
    );

    document.documentElement.style.setProperty(
        '--iframe-all-font-size',
        allFontSize + 'px'
    );

    document
        .querySelectorAll(
            '.post-content p, ' +
            '.post-content div, ' +
            '.fillingForm, ' +
            '.instructionBlock'
        )
        .forEach(function (element) {
            element.style.fontSize = fontSize + 'px';
        });

    document
        .querySelectorAll('.post-content p, .fillingForm')
        .forEach(function (element) {
            if (fontFamily !== '0') {
                element.style.fontFamily = fontFamily;
            } else {
                element.style.removeProperty('font-family');
            }
        });
}

function requestParentStyle() {
    window.parent.postMessage({
        eventName: 'askStyle'
    }, '*');
}

function stopStyleRequesting() {
    if (styleRequestInterval) {
        clearInterval(styleRequestInterval);
        styleRequestInterval = null;
    }

    if (styleRequestTimeout) {
        clearTimeout(styleRequestTimeout);
        styleRequestTimeout = null;
    }
}

function startStyleRequesting() {
    stopStyleRequesting();

    requestParentStyle();

    styleRequestInterval = setInterval(function () {
        if (initialStyleReceived) {
            stopStyleRequesting();
            return;
        }

        requestParentStyle();
    }, 300);

    styleRequestTimeout = setTimeout(function () {
        stopStyleRequesting();
    }, 10000);
}

// --------- MESSAGES FROM PARENT ------------

window.addEventListener('message', function (event) {
    if (!isAllowedParentOrigin(event.origin)) return;
    if (!event.data || typeof event.data !== 'object') return;

    switch (event.data.eventName) {
        case 'profileFillingResponce':
            profileDataReceived = true;

            if (profileRequestInterval) {
                clearInterval(profileRequestInterval);
                profileRequestInterval = null;
            }

            userLatinName =
                event.data.userLatinName || '';

            userProfileUrl =
                event.data.userProfileUrl || '';

            userApplicationFormUrl =
                event.data.userApplicationFormUrl || '';

            receivedStripes =
                Array.isArray(event.data.stripes)
                    ? event.data.stripes
                    : [];

            receivedBackgrounds =
                Array.isArray(event.data.backgrounds)
                    ? event.data.backgrounds
                    : [];

            applyReceivedProfileData();
            break;

        case 'styleChange':
            initialStyleReceived = true;
            applyIframeStyle(event.data.style, event.data.theme);
            stopStyleRequesting();
            break;

        case 'fontChange':
            applyIframeFont(event.data);
            break;
    }
});

// --------- INITIALIZATION ------------

function initializeIframeForm() {
    const resultButton =
        document.getElementById('instructionResult');

    if (resultButton) {
        resultButton.addEventListener('click', copyResults);
    }

    if (profileDataReceived) {
        applyReceivedProfileData();
    } else {
        updateProfilePreview();
    }

    startProfileRequesting();
    startStyleRequesting();
}

// Если скрипт выполнился после готовности DOM

if (iframeDomReady) {
    initializeIframeForm();
}
</script>

<div class="fillingForm">
<label class="fillingCategoryRadio"><input type="radio" id="profileDescr" name="fillingCategoryRadio" checked /> <span>Описание в профиле</span></label>
<label class="fillingCategoryRadio"><input type="radio" id="profileStripe" name="fillingCategoryRadio" /> <span>Плашки</span></label>
<label class="fillingCategoryRadio"><input type="radio" id="profileBg" name="fillingCategoryRadio" /> <span>Фоны</span></label>

<div class="instructionBlock profileDescr">
<h2 class="instructionHeading">Описание в профиль</h2>
<label for="cyrillicName" class="labelDescr">Имя на кириллице:</label>
<input type="text" id="cyrillicName" name="cyrillicName" oninput="updateProfilePreview()">

<label for="applicationFormUrl" class="labelDescr">Ссылка на анкету:</label>
<input type="text" id="applicationFormUrl" name="applicationFormUrl" oninput="updateProfilePreview()">

<label for="mainDescr" class="labelDescr">Описание в профиль:</label>
<input type="text" id="mainDescr" name="mainDescr" value="возраст, раса, род деятельности" oninput="updateProfilePreview()">

<label for="hrAdd" class="hrAdd">
<input type="checkbox" id="hrAdd" name="hrAdd" onchange="updateProfilePreview()" />
<span>Добавить полосу между секциями</span>
</label>

<label for="addDescr" class="labelDescr">При желании можете добавить в профиль пару, красивую цитату, важного родственника, врага и тому подобное через это поле. Если не нужно, оставьте его пустым или не меняйте:</label>
<textarea id="addDescr" oninput="updateProfilePreview()" name="addDescr" rows="4">любое описание на ваш вкус <a href='ссылка на анкету персонажа'>имя на кириллице</a></textarea>
</div>

<div class="instructionBlock profileStripe">
<h2 class="instructionHeading">Плашки</h2>
<div id="stripeContainer"></div>
<div id="stripeCustom">
<label for="stripeCustomLabel" class="labelDescr">Своя плашка:</label>
<input type="text" id="stripeCustomLabel" name="stripeCustomLabel" oninput="handleStripeCustomInput()">
</div>
</div>

<div class="instructionBlock profileBg">
<h2 class="instructionHeading">Фоны</h2>
<div id="bgContainer"></div>
<div id="bgCustom">
<label for="bgCustomLabel" class="labelDescr">Свой фон:</label>
<input type="text" id="bgCustomLabel" name="bgCustomLabel" oninput="handleBgCustomInput()">
</div>
</div>

</div>

<div class="formButtons">
<input type="button" id="instructionResult" value="Скопировать код">
</div>

<style>
h2.instructionHeading {
    font-size: 16px;
    font-family: var(--font-accent);
    font-weight: bold;
    letter-spacing: 1px;
}

.labelDescr {
    display: block;
    margin: 9px 0px 1px 0px;
}

.instructionBlock {
    text-align: left;
    margin: 10px 0 !important;
    padding: 14px 14px 12px 14px !important;
    border: 1px solid var(--borders);
    background: var(--beg300);
    border-radius: 4px;
}

.instructionBlock input[type="text"] {
    width: calc(100% - 10px);
}

.instructionBlock textarea {
    width: calc(100% - 10px);
    resize: vertical;
}

label.hrAdd {
    margin: 10px 0 0 0;
    display: block;
}

input#hrAdd  {
    accent-color: var(--text2);
}

.profileStripeLabel, .profileBgLabel {
    margin: 5px 5px;
    display: inline-block;
    width: 180px;
    border-radius: 5px;
    padding: 5px;
    background: rgb(255 255 255 / 17%);
}

.profileStripeLabel img, .profileBgLabel img { border-radius: 3px; }

.profileBgLabel img {
    width: 180px;
    height: 40px;
    object-fit: cover;
    object-position: top;
}

.profileStripeLabel input, .profileBgLabel input { display: none; }

.profileStripeLabel:has(input:checked), .profileBgLabel:has(input:checked) {
    background: rgb(0 0 0 / 12%);
}

div#stripeContainer, div#bgContainer {
    align-items: baseline;
    display: flex;
    flex-direction: column;
    flex-wrap: wrap;
    align-content: flex-start;
    height: 193px;
    overflow-x: auto;
    overflow-y: hidden;
}

label.fillingCategoryRadio {
    border-radius: 16px;
    border: 1px solid var(--borders);
    background: var(--beg300);
    padding: 2px 6px;
    display: inline-block;
    margin: 0px 4px 5px 0px;
}

label.fillingCategoryRadio:has(input:checked) {
    background: var(--borders);
    color: var(--text1);
}

.fillingCategoryRadio input[type="radio"] {
    display: none;
}

label.fillingCategoryRadio {
    cursor: pointer;
}

.profileDescr, .profileStripe, .profileBg { display: none; }
.fillingCategoryRadio:has(#profileDescr:checked) ~ .profileDescr {
    display: block !important;
}
.fillingCategoryRadio:has(#profileStripe:checked) ~ .profileStripe {
    display: block !important;
}
.fillingCategoryRadio:has(#profileBg:checked) ~ .profileBg {
    display: block !important;
}

.fillingForm { text-align: center; }

.instructionBlock hr {
    border: solid 1px var(--borders);
    margin: 10px;
}

</style>
[/html]

+1

2

буду первой на кастомную плашку

плашка:

Код:
https://upforme.ru/uploads/001c/03/d9/200/575742.png

текст:

Код:
как мотылек на пламя

+4

3

Ragnell, готово с:

+1

4

Плашка:
https://upforme.ru/uploads/001c/03/d9/3/960700.jpg

вот эту, будьте добры)

Подпись автора

пусть мои иллюзии покоятся с миром

+2

5

Garreth of Riverbend, оп, готово

+1

6

Плашка:
https://upforme.ru/uploads/001c/03/d9/2/254438.jpg

можно мне эту, пожалуйста)

Подпись автора


гроши в глазницы, на шею жгут, -
вернешься ли невредим?

+2

7

буду красивый :3
Плашка:
https://upforme.ru/uploads/001c/03/d9/2/427469.jpg

+2

8

О, картиночки! А можно мне, пожалуйста, надпись от первой плашки - "знание - сила", но вот с этой картинкой:

Код:
https://upforme.ru/uploads/001c/03/d9/196/812869.jpg

+1

9

Neurin Tamariti, готово)

Подпись автора

One day, fate will find a way
Through the marches of death
And right back to the bearer of light

+1

10

Можно и мне плашку?)

Код:
https://upforme.ru/uploads/001c/03/d9/3/776823.jpg
Подпись автора


https://upforme.ru/uploads/001c/03/d9/148/827087.gif

- I'm a wizard, i practice duck magic.
- You mean dark magic?
- No.

+1

11

Niall, а подскажи подпись, пожалуйста?

0

12

Dolor, "Знание - сила"

Подпись автора


https://upforme.ru/uploads/001c/03/d9/148/827087.gif

- I'm a wizard, i practice duck magic.
- You mean dark magic?
- No.

0

13

Niall, поставил 🎉

0

14

знания - сила
https://upforme.ru/uploads/001c/03/d9/63/328201.png

Подпись автора

О, как же чудовищно
Медленно движется
Ком государственной смуты!

+1

15

Reynis Redwald, нужно только убрать тень, с ней плашка вылезает за 180 и вероятно смотрится не так как планируется

0

16

Dolor написал(а):

Reynis Redwald, нужно только убрать тень, с ней плашка вылезает за 180 и вероятно смотрится не так как планируется

оО откуда тень взялась
прошу прощения

знания - сила
https://upforme.ru/uploads/001c/03/d9/63/401144.png

Подпись автора

О, как же чудовищно
Медленно движется
Ком государственной смуты!

+1

17

Reynis Redwald, оп, стоит

+1

18

Плашка:
https://upforme.ru/uploads/001c/03/d9/2/879999.jpg

Можно с той же цитатой про драконов
С телефона только так могу :<

+1

19

Enid ni Tyanat, для готовых плашек и не нужно цитату)
Поставил ♥

0

20

Можно и меня приодеть, пожалуйста?)

Код:
https://upforme.ru/uploads/001c/03/d9/2/879999.jpg
Код:
от крови драконов

+1


Вы здесь » Shadows of Old » Организационный раздел » Оформление профиля