Skip to content

Instantly share code, notes, and snippets.

@oralekin
Last active June 19, 2022 15:53
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save oralekin/240d536d13d0a87ecf2474658115621b to your computer and use it in GitHub Desktop.
Save oralekin/240d536d13d0a87ecf2474658115621b to your computer and use it in GitHub Desktop.
osu! Logo Template for 2022 /r/place
// ==UserScript==
// @name osu! Logo template
// @namespace http://tampermonkey.net/
// @version 0.6
// @description try to take over the canvas!
// @author oralekin, LittleEndu, ekgame, Wieku, DeadRote
// @match https://hot-potato.reddit.com/embed*
// @icon https://www.google.com/s2/favicons?sz=64&domain=reddit.com
// @grant none
// ==/UserScript==
if (window.top !== window.self) {
window.addEventListener('load', () => {
// Load the image
const image = document.createElement("img");
const undotted = "https://cdn.discordapp.com/attachments/939592132556124230/960307248633094184/dotted-place-template.1-1.png";
image.src = "https://cdn.mirai.gg/tmp/dotted-place-template.png";
image.onload = () => {
image.style = `position: absolute; left: 0; top: 0; width: ${image.width/3}px; height: ${image.height/3}px; image-rendering: pixelated; z-index: 1`;
};
// Add the image as overlay
const camera = document.querySelector("mona-lisa-embed").shadowRoot.querySelector("mona-lisa-camera");
const layout = document.querySelector("mona-lisa-embed").shadowRoot;
const canvas = camera.querySelector("mona-lisa-canvas");
canvas.shadowRoot.querySelector('.container').appendChild(image);
// Add a style to put a hole in the pixel preview (to see the current or desired color)
const waitForPreview = setInterval(() => {
const preview = camera.querySelector("mona-lisa-pixel-preview");
if (preview) {
clearInterval(waitForPreview);
const style = document.createElement('style')
style.innerHTML = '.pixel { clip-path: polygon(-20% -20%, -20% 120%, 37% 120%, 37% 37%, 62% 37%, 62% 62%, 37% 62%, 37% 120%, 120% 120%, 120% -20%); }'
preview.shadowRoot.appendChild(style);
loadRegions()
setTimeout(()=>{
loadRegions();
if(typeof regionInterval == "undefined") {
const regionInterval = setInterval(()=>{
loadRegions()
},5000)
}
},1000)
}
}, 100);
//Insert element after another element
function insertAfter(newNode, referenceNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
//Slider initialization
function initSlider(){
let visSlider = document.createElement("div");
visSlider.style = `
position: fixed;
left: calc(var(--sail) + 16px);
right: calc(var(--sair) + 16px);
display: flex;
flex-flow: row nowrap;
align-items: center;
justify-content: center;
height: 40px;
top: calc(var(--sait) + 48px);
text-shadow: black 1px 0 10px;
text-align:center;
`;
//Text
let visText = document.createElement("div");
visText.innerText = "Highlight zones";
visSlider.appendChild(visText);
let lineSeparator = document.createElement("br");
visSlider.appendChild(lineSeparator);
//Range slider input
let visInput = document.createElement("input");
visInput.setAttribute("type","range");
visInput.setAttribute("id","visRange");
visInput.setAttribute("name","range");
visInput.setAttribute("min","0");
visInput.setAttribute("max","100");
visInput.setAttribute("step","1");
visInput.value = 0;
//Range slider label (name)
let visLabel = document.createElement("label");
visLabel.innerText = '0'
visSlider.appendChild(visInput);
visSlider.appendChild(visLabel);
var inputEvtHasNeverFired = true;
var rangeValue = {current: undefined, mostRecent: undefined};
visInput.addEventListener("input", function(evt) {
inputEvtHasNeverFired = false;
rangeValue.current = evt.target.value;
if (rangeValue.current !== rangeValue.mostRecent) {
visInput.value = rangeValue.current;
visLabel.innerText = rangeValue.current+'';
placeGlobal.visLevel = rangeValue.current/100;
placeGlobal.svgMask.style.opacity = placeGlobal.visLevel+'';
}
rangeValue.mostRecent = rangeValue.current;
});
let topControls = document.querySelector("mona-lisa-embed").shadowRoot.querySelector(".layout .top-controls");
insertAfter(visSlider,topControls);
placeGlobal.slider = visSlider;
}
//Generate SVG function
function generateSVG(){
let svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.setAttribute("width","2000px");
svg.setAttribute("height","2000px");
svg.style = `
position: absolute;
left: 0;
top: 0;
z-index: 1;
opacity: `+placeGlobal.visLevel+`;`;
let svgDefs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
svg.appendChild(svgDefs);
let mask = document.createElementNS('http://www.w3.org/2000/svg', 'mask');
mask.setAttribute("id","osuplaceMask");
svgDefs.appendChild(mask);
let mainMask = document.createElementNS("http://www.w3.org/2000/svg", 'rect');
mainMask.setAttribute('x', "0");
mainMask.setAttribute("y","0");
mainMask.setAttribute('height', "100%");
mainMask.setAttribute('width', "100%");
mainMask.setAttribute('fill', 'white');
mask.appendChild(mainMask);
let imageMask = document.createElementNS("http://www.w3.org/2000/svg", 'image');
imageMask.setAttribute('href',undotted)
imageMask.setAttribute('x', "0");
imageMask.setAttribute("y","0");
imageMask.setAttribute('height', "100%");
imageMask.setAttribute('width', "100%");
mask.appendChild(imageMask);
let svgBody = document.createElementNS('http://www.w3.org/2000/svg', 'g');
svgBody.setAttribute("width","2000px");
svgBody.setAttribute("height","2000px");
svgBody.setAttribute("x","0");
svgBody.setAttribute("y","0");
svg.appendChild(svgBody);
let bodyRect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
bodyRect.setAttribute("width","2000px");
bodyRect.setAttribute("height","2000px");
bodyRect.setAttribute("x","0");
bodyRect.setAttribute("y","0");
bodyRect.setAttribute("fill","rgba(0,0,0,0.6)");
bodyRect.setAttribute("mask","url(#osuplaceMask)")
svgBody.appendChild(bodyRect);
return svg
}
//Global variables
var placeGlobal = {
visLevel: 0,
slider: null,
svgMask: null
}
//Load mask
function loadRegions(){
if(placeGlobal.svgMask != null){
placeGlobal.svgMask.remove();
}
let svgClipBody = generateSVG();
placeGlobal.svgMask = svgClipBody;
//Generate slider UI
//if(placeGlobal.slider == null ){
let sliderState = layout.contains(layout.querySelector('#visRange'));
if(!sliderState){
initSlider();
}
//}
canvas.shadowRoot.querySelector('.container').appendChild(svgClipBody);
}
}, false);
}
@helpimnotdrowning
Copy link

helpimnotdrowning commented Apr 2, 2022

would you consider replacing image-rendering: pixelated with image-rendering: crisp-edges? the template pixels looked like they were on auto with Waterfox G4.0.6, but look correct with crisp-edges.

@Jumprocks1
Copy link

Couldn't we just set i.style.width = i.width / 3 so that it will work no matter what size of template we use?

Here's my proposed change:

i.onload = () => {
    i.style = `position:absolute; left:0; top:0; image-rendering:pixelated; width:${i.width/3}px; height:${i.height/3}px;`
};

This way if they expand the canvas more, we don't have to update anything but the image.

@ekgame
Copy link

ekgame commented Apr 2, 2022

I simplified the code and implemented some changes so the preview color doesn't obscure the overlayed image: https://gist.github.com/ekgame/38980058209aaad95cf469736fb9956f

@oralekin
Copy link
Author

oralekin commented Apr 2, 2022

I simplified the code and implemented some changes so the preview color doesn't obscure the overlayed image: ekgame/38980058209aaad95cf469736fb9956f

accepted changes, thanks!

@btmxh
Copy link

btmxh commented Apr 3, 2022

i added a hotkey (ctrl+i) to reload the overlay without having to reload the page, may be helpful when reddit servers are dying: https://gist.github.com/ngoduyanh/0026c9e54060d56e21dd20904a6d79fb

@Igneom
Copy link

Igneom commented Apr 3, 2022

i added a hotkey (ctrl+i) to reload the overlay without having to reload the page, may be helpful when reddit servers are dying: https://gist.github.com/ngoduyanh/0026c9e54060d56e21dd20904a6d79fb

With this, I'm quite sure you guys will run into the same issue that happened with me, on subsequent loads of the image, it keeps getting smaller and smaller.

Image.width and image.height, should be changed to image.naturalWidth and image.naturalHeight. So that it uses the intrinsic size of the image, and not the size of the element.

@kebien6020
Copy link

kebien6020 commented Apr 3, 2022

I added a settings menu with the option to customize the url: https://gist.github.com/kebien6020/9eda7b69d0a147532bb99258538f9d4d

image

It opens from a blue dot at the bottom right

@Igneom
Copy link

Igneom commented Apr 3, 2022

I added a settings menu with the option to customize the url: https://gist.github.com/kebien6020/9eda7b69d0a147532bb99258538f9d4d

image

It opens from a blue dot at the bottom right

Did the same as well throughout the day

https://gist.github.com/Igneom/1a63744cbaba5980fee2bdcf8f6ac55e

@ipatrol
Copy link

ipatrol commented Apr 3, 2022

It's giving me "To protect your security, hot-potato.reddit.com will not allow Firefox to display the page if another site has embedded it. To see this page, you need to open it in a new window.", which then doesn't load either

@Wetbikeboy2500
Copy link

I added a refresh button that doesn't require reload. I attached random numbers to the url for cache busting. It uses the image code to rebuild which could be nicer. Doesn't require any special permissions. https://gist.github.com/Wetbikeboy2500/e4e41f5799669ac05bbfab2cba3c2ea8

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment