Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ==UserScript==
- // @name Endchan Mascot
- // @namespace https://endchan.org/
- // @version 1.3
- // @description Add a configurable mascot to endchan
- // @author Anonymous (You)
- // @match http://endchan.org/*/res/*
- // @match https://endchan.org/*/res/*
- // @match http://endchan.net/*/res/*
- // @match https://endchan.net/*/res/*
- // @match http://magrathea.endchan.net/*/thread/*
- // @match https://magrathea.endchan.net/*/thread/*
- // @resource fontAwesomeCSS https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css
- // @grant none
- // @downloadURL https://pastebin.com/raw/yjwXhRv2
- // @updateURL https://pastebin.com/raw/yjwXhRv2
- // ==/UserScript==
- /*
- How this works is you get 2 new elements on the page - one is the mascot, the other is a settings overlay.
- The mascot can get toggled into the foreground/background (in front/behind posts).
- When it's in the foreground it can be positioned anywhere in the window. Toggling it back into the background will lock its position.
- Bottom right corner of the image has a hidden settings button that's revealed on mouseover.
- Click that to toggle the image into the foreground and show other settings. Click again to lock the mascot back into the background.
- The settings overlay travels with the image when it's repositioned.
- The other settings button is an image picker, use that to replace the default mascot.
- Settings are saved to localStorage (browser cache) so they should be more or less persistent.
- The things that are saved are mascot position (x, y) and the image src attribute. When selecting the image through the picker the src is the image encoded in base64.
- */
- /*
- 1.3 - added endchan.net to @match
- 1.2 - support for magrathea
- 1.1 - added update urls
- */
- // adjust this as you see fit, this is the max size the mascot is allowed to be
- let mascotWidth = 800;
- let mascotHeight = 600;
- // init global vars to default
- let drag = false;
- let offsetX = 0;
- let offsetY = 0;
- let mascotPosX = 100;
- let mascotPosY = 100;
- let defaultMoveCallback = undefined;
- let mascotSrc = "https://static.wixstatic.com/media/32a1d6_391792dd70889caab5064b911d234eb7.png/v1/fit/w_2500,h_1330,al_c/32a1d6_391792dd70889caab5064b911d234eb7.png"
- // override any vars that need overriding
- restoreSettings();
- // create the mascot image tag
- let mascotImg = document.createElement("img");
- mascotImg.src = mascotSrc;
- mascotImg.className = "draggableMascot"
- mascotImg.style.maxWidth = mascotWidth + "px";
- mascotImg.style.maxHeight = mascotHeight + "px";
- mascotImg.style.position = "fixed";
- mascotImg.style.bottom = mascotPosY + "px";
- mascotImg.style.right = mascotPosX + "px";
- mascotImg.style.zIndex = -1;
- mascotImg.draggable = true;
- // create the settings tag - this needs to stay in the foreground (uses opacity trickery to hide and still trigger mouseover events)
- let mascotSettings = document.createElement("div");
- mascotSettings.style.position = mascotImg.style.position;
- mascotSettings.style.bottom = mascotImg.style.bottom;
- mascotSettings.style.right = mascotImg.style.right;
- mascotSettings.style.zIndex = 2;
- mascotSettings.style.margin = "4px";
- // toggle settings button - moves mascot into foreground so it can be moved around and shows other settings
- let settingsBtn = document.createElement("button");
- settingsBtn.style.opacity = 0;
- settingsBtn.style.minWidth = "28px";
- settingsBtn.style.minHeight = "28px";
- let settingsBtnContent = document.createElement("i");
- settingsBtnContent.classList.add("fa", "fa-gear");
- settingsBtn.appendChild(settingsBtnContent);
- // image picker button - opens file picker dialog
- let imgPickerBtn = document.createElement("button");
- imgPickerBtn.style.opacity = 0;
- imgPickerBtn.style.minWidth = "28px";
- imgPickerBtn.style.minHeight = "28px";
- imgPickerBtn.style.marginRight = "4px";
- let imgPickerBtnContent = document.createElement("i");
- imgPickerBtnContent.classList.add("fa", "fa-image");
- imgPickerBtn.appendChild(imgPickerBtnContent);
- // add buttons to settings overlay
- mascotSettings.appendChild(imgPickerBtn);
- mascotSettings.appendChild(settingsBtn);
- // -- configure settings functionality
- settingsBtn.onmouseover = function() {
- setSettingsBtnVisibility(true);
- }
- settingsBtn.onmouseout = function() {
- setSettingsBtnVisibility(false);
- }
- settingsBtn.onclick = toggleEditing;
- imgPickerBtn.onclick = selectImage;
- function setSettingsBtnVisibility(isMouseOver) {
- if (isMouseOver) {
- settingsBtn.style.opacity = 1;
- } else if (mascotImg.style.zIndex == -1) {
- // hide on mouse out only if the mascot is locked (not in the foreground)
- settingsBtn.style.opacity = 0;
- }
- }
- function toggleEditing() {
- // if mascot is in the background bring it forward so it can be dragged, otherwise send it back
- // also set the visibility of other settings buttons
- if (mascotImg.style.zIndex == -1) {
- mascotImg.style.zIndex = 1;
- imgPickerBtn.style.opacity = 1;
- } else {
- mascotImg.style.zIndex = -1;
- imgPickerBtn.style.opacity = 0;
- }
- }
- function selectImage() {
- const fileInput = document.createElement("input");
- fileInput.type = "file";
- fileInput.addEventListener("change", () => {
- const file = fileInput.files[0];
- const reader = new FileReader();
- reader.addEventListener("load", () => {
- mascotImg.src = reader.result;
- saveSettings(true);
- });
- reader.readAsDataURL(file);
- });
- fileInput.click();
- }
- // -- mouse events
- function mouseDown(e) {
- // get the event target (mascot image)
- let evt = e ? e : window.event;
- // IE uses srcElement, others use target
- let mascot = evt.target ? evt.target : evt.srcElement;
- if (mascot.className != "draggableMascot") {
- return false;
- }
- // ensure mascot has a starting position
- if (!mascot.style.right) {
- mascot.style.right = "0px";
- }
- if (!mascot.style.bottom) {
- mascot.style.bottom = "0px";
- }
- // get the mouse current coords
- offsetX = evt.clientX;
- offsetY = evt.clientY;
- // get the mascot"s current coords
- mascotPosX = parseInt(mascot.style.right);
- mascotPosY = parseInt(mascot.style.bottom);
- drag = true;
- // move the mascot
- defaultMoveCallback = document.onmousemove;
- document.onmousemove = mouseMove;
- return true;
- }
- function mouseMove(e) {
- // ensure we are in fact dragging
- if (!drag) {
- return false;
- }
- // get the event target (mascot image)
- let evt = e ? e : window.event;
- // move the mascot
- mascotImg.style.right = (mascotPosX - evt.clientX + offsetX) + "px";
- mascotImg.style.bottom = (mascotPosY - evt.clientY + offsetY) + "px";
- mascotSettings.style.right = mascotImg.style.right;
- mascotSettings.style.bottom = mascotImg.style.bottom;
- return false;
- }
- function mouseUp() {
- // stop dragging and reset move callback
- drag = false;
- document.onmousemove = defaultMoveCallback;
- saveSettings();
- return false;
- }
- // -- settings persistency
- function saveSettings(includeImage = false) {
- localStorage.setItem("mascotPosX", mascotImg.style.right);
- localStorage.setItem("mascotPosY", mascotImg.style.bottom);
- if (includeImage) {
- localStorage.setItem("mascotSrc", mascotImg.src);
- }
- }
- function restoreSettings() {
- let x = localStorage.getItem("mascotPosX");
- if (x) {
- mascotPosX = parseInt(x);
- }
- let y = localStorage.getItem("mascotPosY");
- if (y) {
- mascotPosY = parseInt(y);
- }
- let src = localStorage.getItem("mascotSrc");
- if (src) {
- mascotSrc = src;
- }
- }
- // hook onto page's mouse events
- window.onload = function() {
- document.addEventListener("mousedown", mouseDown);
- document.addEventListener("mouseup", mouseUp);
- }
- // add the mascot to the page
- document.body.appendChild(mascotImg);
- document.body.appendChild(mascotSettings);
Add Comment
Please, Sign In to add comment