您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds a modernized, light-themed UI with upload image input to the avatar builder.
// ==UserScript== // @name Drawaria Avatar Builder ++ // @namespace YoutubeDrawariaAvatarBuilder++ // @version 2.0 // @description Adds a modernized, light-themed UI with upload image input to the avatar builder. // @author YouTubeDrawaria // @match https://*.drawaria.online/avatar/builder/ // @match https://drawaria.online/ // @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js // @icon https://img.itch.zone/aW1nLzE3Mjk3OTY0LnBuZw==/original/nVVAE%2F.png // @grant none // @license MIT // ==/UserScript== (($, undefined) => { $(() => { const CHUNK_SIZE = 500 * 1024; // 500 KB const avatar = () => { const $header = $('header'); // Add the image in the left corner of the header const $imageLeft = $('<div class="imageLeft"></div>').css({ position: 'absolute', top: '-64px', // Adjust top spacing left: '0px', // Adjust left spacing zIndex: '10', }); const $image = $('<img>') .attr('src', 'https://i.ibb.co/BT59zrr/builder.png') .css({ width: '180px', // Adjust the size as necessary height: '180px', objectFit: 'contain', }); $imageLeft.append($image); $header.css('position', 'relative').append($imageLeft); const $labelButton = $('<label class="Button" for="imageInput">Upload Image++</label>'); const $imageInput = $('<input style="display:none" id="imageInput" type="file" accept="image/*">'); $header.append($labelButton, $imageInput); $imageInput.on('change', (event) => { const file = event.target.files[0]; if (!file) return; const reader = new FileReader(); reader.onload = () => { const uploadedImage = reader.result; updateButtonState('Uploading...', true); uploadInChunks(file, 0); }; reader.readAsDataURL(file); }); const updateButtonState = (text, disable) => { $labelButton.text(text).css('pointer-events', disable ? 'none' : 'auto'); }; const updateProgressBar = (percentComplete) => { $labelButton.css( 'background', `linear-gradient(90deg, #00f2ff ${percentComplete.toFixed(0)}%, #ccc 0%)` ); }; const fetchAvatarImage = (data) => { fetch(`${location.origin}/avatar/cache/${data}.jpg`, { method: 'GET', mode: 'cors', cache: 'reload' }) .then(() => { updateButtonState('Save OK!', true); window.location.href = new URL(window.location.href).origin; }) .catch((error) => { handleError(error); }); }; const handleError = (error) => { updateButtonState('Upload Image', false); $imageInput.val(''); alert(`Error: ${error}`); }; const uploadInChunks = (file, start) => { const end = Math.min(start + CHUNK_SIZE, file.size); const chunk = file.slice(start, end); const reader = new FileReader(); reader.onload = (event) => { const chunkData = event.target.result.split(',')[1]; $.ajax({ url: window.LOGGEDIN ? '/saveavatar' : '/uploadavatarimage', type: 'POST', data: { 'avatarsave_builder': JSON.stringify(window.ACCOUNT_AVATARSAVE), 'imagedata': chunkData, 'fromeditor': true, 'chunk': start / CHUNK_SIZE, 'totalChunks': Math.ceil(file.size / CHUNK_SIZE), }, xhr: () => { const xhr = new window.XMLHttpRequest(); xhr.upload.addEventListener( 'progress', (evt) => { if (evt.lengthComputable) { const percentComplete = ((start + evt.loaded) / file.size) * 100; updateProgressBar(percentComplete); } }, false ); return xhr; }, }) .done((data) => { if (end < file.size) { uploadInChunks(file, end); } else { updateButtonState('Saving...', true); fetchAvatarImage(data); } }) .fail((_jqXHR, _textStatus, errorThrown) => { handleError(errorThrown); }); }; reader.readAsDataURL(chunk); }; }; const mainObserver = new MutationObserver(() => { if ($('main').length) { avatar(); mainObserver.disconnect(); } }); mainObserver.observe(document, { childList: true, subtree: true }); // Styles for the button and animation const style = ` /* General Styles */ body, html { font-family: 'Figtree', sans-serif; margin: 0; padding: 0; background: linear-gradient(to right, #f0f9ff, #cbebff); color: #333; overflow-x: hidden; } header { display: flex; align-items: center; justify-content: flex-end; padding: 10px 20px; background: linear-gradient(90deg, #00d4ff, #007cff); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); position: relative; } .App>header .Button { background: #517aa3; } .imageLeft { top: 5px; left: 15px; } .Button { padding: 10px 15px; font-size: 14px; font-weight: bold; color: white; background: linear-gradient(90deg, #6fffe9, #00b8ff); border: none; border-radius: 5px; cursor: pointer; transition: all 0.3s ease; margin: 0 5px; text-shadow: 0px 0px 5px rgba(255, 255, 255, 0.7); } .Button:hover { transform: translateY(-2px); box-shadow: 0 4px 10px rgba(0, 200, 255, 0.5); background: linear-gradient(90deg, #00b8ff, #6fffe9); } .Button:active { transform: translateY(0); box-shadow: 0 2px 5px rgba(0, 200, 255, 0.3); } .Panel { background: white; border-radius: 10px; padding: 15px; margin: 10px; box-shadow: 0 6px 10px rgba(0, 0, 0, 0.1); } .List ul { list-style: none; padding: 0; } .List li { margin: 5px 0; padding: 10px; background: #f5faff; border-radius: 5px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); transition: transform 0.2s, background 0.3s; } .List li:hover { transform: scale(1.02); background: #e3f7ff; } canvas.main { border-radius: 10px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); } /* Animations */ @keyframes fadeIn { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: translateY(0); } } .Panel, .List li { animation: fadeIn 0.5s ease-in-out; } `; // Add styles to the document const styleSheet = document.createElement('style'); styleSheet.type = 'text/css'; styleSheet.innerText = style; document.head.appendChild(styleSheet); }); })(window.jQuery.noConflict(true));