NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Recortar avatar (Fórum Atelier 801) // @namespace https://gist.github.com/emanuel15 // @version 0.5 // @description Complemento que permite recortar o avatar no momento do envio. // @author Laagaadoo // @require https://code.jquery.com/jquery-2.2.4.min.js // @require http://code.jquery.com/ui/1.12.1/jquery-ui.min.js // @require https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js // @grant GM.xmlHttpRequest // @match https://atelier801.com/profile?pr=* // @connect atelier801.com // @license MIT // @updateURL https://openuserjs.org/meta/c0rnerst0ne/Recortar_avatar_(Fórum_Atelier_801).meta.js // @downloadURL https://openuserjs.org/src/scripts/c0rnerst0ne/Recortar_avatar_(Fórum_Atelier_801).user.js // ==/UserScript== 'use strict'; var playerID; var originalAvatar = ""; // cópia da img var $imgCopy = $('<img id="image" />'); // preview var canvas = $('<canvas id="avtCanvas" />'); var ctx = canvas[0].getContext("2d"); // imagem que o usuário escolheu var $imageCanvas; var imageCanvas; var imgCanvasCtx; var URL_COMPLETE = window.location.href.replace(/#(.+)/ig, ''); $(document).ready(function() { playerID = $('input[name="pr"]').attr('value'); originalAvatar = $('.img100').attr('src'); var firstTime = true; // tema do jQuery UI $("head").prepend('<link rel="stylesheet" type="text/css" href="//code.jquery.com/ui/1.12.1/themes/black-tie/jquery-ui.css" />'); // borda preta no avatar $("head").prepend($('<style type="text/css">.avatar-profil:after { content: ""; position: absolute; top: 0; left: 0; right: 0; bottom: 0; -webkit-box-shadow: inset 0px 0px 0px 2px #000; -moz-box-shadow: inset 0px 0px 0px 2px #000; box-shadow: inset 0px 0px 0px 2px #000; }</style>')); $(".avatar-profil").css({ 'height': '100px', '-webkit-box-shadow': 'inset 0px 0px 0px 2px #ff0000', '-moz-box-shadow': 'inset 0px 0px 0px 2px #ff0000', 'box-shadow': 'inset 0px 0px 0px 2px #ff0000', 'position': 'relative', 'z-index': 1000, }); $(".img100").css({ 'position': 'relative', 'z-index': 0, 'width': '100px', 'height': '100px', 'max-width': '100px', 'max-height': '100px', 'min-width': '100px', 'min-height': '100px', }) .load(function() { $(".img100").width(100).height(100); }); $("#fichier").change(function(event) { if (event.target.files && event.target.files[0]) { var reader = new FileReader(); reader.onload = function(e) { if (firstTime) { createElements(); firstTime = false; } var image = new Image(); image.src = e.target.result; image.onload = function() { loadImage(e.target.result); } } reader.readAsDataURL(event.target.files[0]); } }); $('<div id="imageUrl" class="control-group">' + '<label class="control-label" for="avatarImg">Fonte (URL)</label>' + '<div class="controls">' + '<input type="url" id="imageSourceUrl" autocomplete="on"/>' + '<a id="loadUrlImageBtn" class="btn" style="margin-left: 5px;">Carregar</a>' + '</div>' + '</div>') .insertAfter('#cadre_changer_avatar_' + playerID + ' input[name="pr"]'); var $imageUrlInput = $('#imageSourceUrl'); $('#loadUrlImageBtn').click(function() { if (firstTime) { createElements(); firstTime = false; } GM.xmlHttpRequest({ method: "GET", url: $imageUrlInput.val(), onload: function(event) { var dataURI = 'data:image/png;base64,' + customBase64Encode(event.responseText); loadImage(dataURI); }, overrideMimeType: 'text/plain; charset=x-user-defined' }); }); }); function createElements() { $('<div id="cutAvatarParent" class="control-group"><label class="control-label" for="avatarImg">Recortar Avatar</label><div class="controls" id="avatarControls"><canvas id="imageCanvas" /><div id="cutArea" style="width: 100px; height: 100px;"></div></div></div>') .insertAfter('#cadre_changer_avatar_' + playerID + ' input[name="pr"]'); $("#avatarControls").css('position', 'relative'); $imageCanvas = $('#imageCanvas'); imageCanvas = $imageCanvas[0]; imgCanvasCtx = imageCanvas.getContext("2d"); $imageCanvas.css('position', 'relative'); $('#cutArea').css({ '-webkit-box-shadow': 'inset 0px 0px 0px 2px #000', '-moz-box-shadow': 'inset 0px 0px 0px 2px #000', 'box-shadow': 'inset 0px 0px 0px 2px #000' }); var $submit = $("#cadre_changer_avatar_" + playerID + " .btn-post") $submit.attr('onclick', ''); $submit.click(function(e) { //e.preventDefault(); $submit.attr('disabled', 'on'); var hiddenKey = $('#formulaire_deconnexion input[type="hidden"]').attr('name'); var hiddenValue = $('#formulaire_deconnexion input[type="hidden"]').attr('value'); var formData = new FormData(); formData.append('pr', playerID); formData.append("fichier", dataURItoBlob(canvas[0].toDataURL("image/jpeg"))); formData.append(hiddenKey, hiddenValue); GM.xmlHttpRequest({ method: "POST", url: "https://atelier801.com/update-profile-avatar", data: formData, headers: { "Referer": URL_COMPLETE }, onload: function(event) { if (event.status == 200 && (event.responseText != null || event.responseText != "")) { var r = JSON.parse(event.responseText); if (r.message != null) { if (r.resultat == "IMAGE_TROP_GROSSE") { $('body').prepend(creerPopupResultat(r.message, false)); } else { $('body').prepend(creerPopupResultat(r.message, true)); } jQuery.noConflict(); jQuery('#popup_resultat_requete').modal('show'); } if (r.redirection != null) { window.location.href = r.redirection; } $submit.attr('disabled', 'off'); } else { console.log("Response (" + event.status + "): " + event.responseText); } }, }); }); var $cancel = $("#cadre_changer_avatar_" + playerID + " button:eq(1)"); $cancel.click(function(event) { $(".img100").attr('src', originalAvatar); }); } // função do fórum function creerPopupResultat(texte, reloadSurOk) { $('#popup_resultat_requete').remove(); var popup = '<div class="modal hide fade ltr"'; if (reloadSurOk) { popup += ' data-backdrop="static" data-keyboard="false" data-show="true"'; } popup += ' id="popup_resultat_requete">' + '<form><div class="modal-header">'; if (!reloadSurOk) { popup += ' <a class="close" data-dismiss="modal">×</a>'; } popup += '<h3>Informação</h3>' + '</div>' + '<div class="modal-body">' + texte + '</div>' + '<div class="modal-footer">' + '<button type="submit" class="btn btn-info" data-dismiss="modal"'; if (reloadSurOk) { popup += ' onclick=\"window.location.reload();\"'; } popup += '>Ok</button>' + '</div>' + '</form>'; return popup; } function clearCanvas(cvs) { var ctx = cvs.getContext("2d"); ctx.beginPath(); ctx.clearRect(0, 0, cvs.width, cvs.height); } function selectArea(moveSelector, x, y, width, height) { if (moveSelector) { $('#cutArea').css({ 'position': 'absolute', 'top': ($imageCanvas.position().top + x) + 'px', 'left': ($imageCanvas.position().left + y) + 'px', 'width': width, 'height': height, 'z-index': 10, }); } var img = $imgCopy[0]; clearCanvas(imageCanvas); imgCanvasCtx.drawImage(img, 0, 0, img.width, img.height); imgCanvasCtx.stroke(); imgCanvasCtx.fillStyle = "rgba(0, 0, 0, 0.6)"; imgCanvasCtx.fillRect(0, 0, imageCanvas.width, imageCanvas.height); imgCanvasCtx.drawImage(img, x, y, width, height, x, y, width, height); imgCanvasCtx.stroke(); } function loadImage(url) { var img = $imgCopy[0]; $imgCopy.load(function(event) { clearCanvas(imageCanvas); imageCanvas.width = img.width; imageCanvas.height = img.height; imgCanvasCtx.drawImage(img, 0, 0, img.width, img.height); imgCanvasCtx.stroke(); imgCanvasCtx.fillStyle = "rgba(0, 0, 0, 0.6)"; imgCanvasCtx.fillRect(0, 0, imageCanvas.width, imageCanvas.height); selectArea(true, 0, 0, imageCanvas.width, imageCanvas.height); $('#cutArea').draggable({ addClasses: false, containment: "#imageCanvas", drag: function(event, ui) { selectArea(false, ui.position.left - $imageCanvas.position().left, ui.position.top - $imageCanvas.position().top, $("#cutArea").width(), $("#cutArea").height()); }, stop: function(event, ui) { displayPreview(); } }) .resizable({ handles: 'all', minWidth: 100, minHeight: 100, containment: '#imageCanvas', start: function(event, ui) { $("#cutArea").css('left', ($("#cutArea").css('left') + 2) + 'px'); $("#cutArea").css('top', ($("#cutArea").css('top') + 2) + 'px'); }, resize: function(event, ui) { selectArea(false, ui.position.left - $imageCanvas.position().left, ui.position.top - $imageCanvas.position().top, $("#cutArea").width(), $("#cutArea").height()); }, stop: function(event, ui) { displayPreview(); } }); $("#cutArea .ui-resizable-se").css('background-image', 'url("")'); displayPreview(); }) .error(function(event) { alert("Não foi possível carregar a imagem."); }); $imgCopy.attr('src', url); } function displayPreview() { var cx = $("#cutArea").offset().left - $imageCanvas.offset().left; var cy = $("#cutArea").offset().top - $imageCanvas.offset().top; var sw = $("#cutArea").width(); var sh = $("#cutArea").height(); clearCanvas(canvas[0]); canvas[0].width = sw; canvas[0].height = sh; ctx.drawImage($imgCopy[0], cx, cy, sw, sh, 0, 0, sw, sh); $(".img100").attr('src', canvas[0].toDataURL("image/jpeg")); } // função feita pelo Stovie do StackOverflow function dataURItoBlob(dataURI) { // convert base64/URLEncoded data component to raw binary data held in a string var byteString; if (dataURI.split(',')[0].indexOf('base64') >= 0) byteString = atob(dataURI.split(',')[1]); else byteString = unescape(dataURI.split(',')[1]); // separate out the mime component var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; // write the bytes of the string to a typed array var ia = new Uint8Array(byteString.length); for (var i = 0; i < byteString.length; i++) { ia[i] = byteString.charCodeAt(i); } return new Blob([ia], {type:mimeString}); } // StackOverflow function customBase64Encode (inputStr) { var bbLen = 3, enCharLen = 4, inpLen = inputStr.length, inx = 0, jnx, keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789+/=", output = "", paddingBytes = 0; var bytebuffer = new Array (bbLen), encodedCharIndexes = new Array (enCharLen); while (inx < inpLen) { for (jnx = 0; jnx < bbLen; ++jnx) { /*--- Throw away high-order byte, as documented at: https://developer.mozilla.org/En/Using_XMLHttpRequest#Handling_binary_data */ if (inx < inpLen) bytebuffer[jnx] = inputStr.charCodeAt (inx++) & 0xff; else bytebuffer[jnx] = 0; } /*--- Get each encoded character, 6 bits at a time. index 0: first 6 bits index 1: second 6 bits (2 least significant bits from inputStr byte 1 + 4 most significant bits from byte 2) index 2: third 6 bits (4 least significant bits from inputStr byte 2 + 2 most significant bits from byte 3) index 3: forth 6 bits (6 least significant bits from inputStr byte 3) */ encodedCharIndexes[0] = bytebuffer[0] >> 2; encodedCharIndexes[1] = ( (bytebuffer[0] & 0x3) << 4) | (bytebuffer[1] >> 4); encodedCharIndexes[2] = ( (bytebuffer[1] & 0x0f) << 2) | (bytebuffer[2] >> 6); encodedCharIndexes[3] = bytebuffer[2] & 0x3f; //--- Determine whether padding happened, and adjust accordingly. paddingBytes = inx - (inpLen - 1); switch (paddingBytes) { case 1: // Set last character to padding char encodedCharIndexes[3] = 64; break; case 2: // Set last 2 characters to padding char encodedCharIndexes[3] = 64; encodedCharIndexes[2] = 64; break; default: break; // No padding - proceed } /*--- Now grab each appropriate character out of our keystring, based on our index array and append it to the output string. */ for (jnx = 0; jnx < enCharLen; ++jnx) output += keyStr.charAt ( encodedCharIndexes[jnx] ); } return output; }