Skip to content

Instantly share code, notes, and snippets.

@kebien6020
Forked from oralekin/userscript.user.js
Last active April 3, 2022 05:14
Show Gist options
  • Save kebien6020/9eda7b69d0a147532bb99258538f9d4d to your computer and use it in GitHub Desktop.
Save kebien6020/9eda7b69d0a147532bb99258538f9d4d 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.4
// @description try to take over the canvas!
// @author oralekin, LittleEndu, ekgame
// @match https://hot-potato.reddit.com/embed*
// @match https://www.reddit.com/r/place*
// @icon https://www.google.com/s2/favicons?sz=64&domain=reddit.com
// @require https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js
// @grant GM_setValue
// @grant GM_getValue
// @grant unsafeWindow
// ==/UserScript==
if (window.top !== window.self) {
window.addEventListener('load', () => {
// Load the image
const image = document.createElement("img");
image.src = GM_getValue('template_url') || "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 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);
}
}, 100);
}, false);
}
// Config
if (window.top === window.self) {
unsafeWindow.require = require
unsafeWindow.requirejs = requirejs
unsafeWindow.define = define
require.config({
paths: {
'preact': 'https://unpkg.com/[email protected]/dist/preact.umd',
'preact-hooks': 'https://unpkg.com/[email protected]/hooks/dist/hooks.umd',
'htm': 'https://unpkg.com/[email protected]/dist/htm.umd',
},
})
require(['preact', 'preact-hooks', 'htm'], (
{ h, render, Fragment },
{ useState },
htm,
) => {
const html = htm.bind(h)
const styled = Comp => style =>
props => h(Comp, {...props, style: {...(props.style ?? {}), ...style}})
const ConfigMenu = () => {
const [show, setShow] = useState(false)
const toggle = () => setShow(prev => !prev)
const close = () => setShow(false)
const [url, setUrl] = useState(() => GM_getValue('template_url') ?? '')
const onSubmit = e => {
e.preventDefault()
GM_setValue('template_url', url)
location.reload()
}
const onCancel = e => {
e.preventDefault()
close()
}
return html`
<Fragment>
<${CircleBtn} onClick=${() => alert('test')} onClick=${toggle} />
<${Dialog} style=${{display: show ? 'block' : 'none'}}>
<form onSubmit=${onSubmit}>
<${FieldWrapper}>
<label>
Template URL:
<${HSpacer} />
<${Input}
name='template_url'
placeholder='(leave empty to use default)'
onChange=${e => setUrl(e.target.value)}
value=${url}
/>
</label>
<//>
<${FieldWrapper} style=${{justifyContent: 'end'}}>
<${CancelBtn} onClick=${onCancel}>Cancel<//>
<${HSpacer} />
<${SubmitBtn}>Save<//>
<//>
</form>
<//>
</Fragment>
`
}
const CircleBtn = styled(
props => h('div', {
...props,
className: `${props.className ?? ''} CircleBtn`,
children: html`
<${Fragment}>
${props.children}
<div className="txt">
Template settings
</div>
<style>
.CircleBtn {
width: 36px;
transition: width 250ms ease-in 250ms;
}
.CircleBtn:hover {
width: 144px;
transition: width 250ms ease-in;
}
.CircleBtn .txt {
opacity: 0;
transition: opacity 250ms ease-in;
position: absolute;
right: 8px;
width: 250px;
text-align: right;
}
.CircleBtn:hover .txt {
opacity: 1;
transition: opacity 250ms ease-in 250ms;
}
</style>
<//>
`
})
)({
position: 'fixed',
bottom: 0,
right: 0,
marginBottom: 16,
marginRight: 16,
height: 36,
borderRadius: 18,
backgroundColor: 'blue',
zIndex: 1000,
cursor: 'pointer',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
color: 'white',
})
const Paper = styled('div')({
backgroundColor: 'white',
padding: 16,
borderRadius: 4,
})
const Dialog = styled(Paper)({
position: 'fixed',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
zIndex: 1001,
})
const Input = styled('input')({
border: '1px solid rgba(0, 0, 0, 0.3)',
minWidth: 250,
})
const FieldWrapper = styled('div')({
padding: 2,
display: 'flex',
flexFlow: 'row',
})
const SubmitBtn = styled(props => h('button', {type: 'submit', ...props}))({
backgroundColor: 'darkgreen',
color: 'white',
borderRadius: 4,
padding: 8,
})
const CancelBtn = styled('button')({
backgroundColor: 'darkgrey',
color: 'white',
borderRadius: 4,
padding: 8,
})
const HSpacer = styled('div')({
display: 'inline-block',
width: 16,
})
const configRoot = document.createElement("div")
document.body.appendChild(configRoot)
render(html`<${ConfigMenu} />`, configRoot)
console.log(configRoot)
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment