ジャバボタン画像ジェネレータ
Original code is https://github.com/arigato-java/java_images
<div class="javabo"> | |
<a href="javascript:void" class="redjavabo"> | |
今すぐダウンロード | |
</a> | |
</div> | |
<p class="control"> | |
<label for="input">Your dream:</label> | |
<input id="input" value="" placeholder="is ...?"> | |
<br> | |
<a class="button" id="tweetlink" href="" target="_blink">Tweet</a> | |
<!-- TODO: Replace navigator.share button --> | |
<a class="button" id="permalink" href="" target="_top">🔗Link</a> | |
<a class="button" id="download-link" href="javascript:void" title="今すぐダウンロード" target="_top">💾</a> | |
</p> | |
<!-- | |
<a href="https://github.com/arigato-java/java_images/tree/master/src/com/java/images/css">Original code is here.</a> | |
--> |
// Constants and aliases | |
const baseURL = 'https://codepen.io/tobynet/full/LagBKm'; | |
const hashTag = '#JavaButtonMaker'; | |
const q = document.querySelector.bind(document); | |
// Update the caption of the button | |
// (string, boolean) -> void | |
const setCaption = (text, allowsEmptyText) => { | |
q('.redjavabo').textContent = text.trim(); | |
const caption = q('.redjavabo').textContent; | |
const inputValue = allowsEmptyText ? "" : caption; | |
const permalink = allowsEmptyText ? baseURL : makePermalink(caption).toString(); | |
q('#input').value = inputValue; | |
q('#permalink').href = permalink; | |
q('#tweetlink').href = makeTweetlink(caption, permalink, hashTag).toString(); | |
} | |
// Get a permalink | |
// string -> URL | |
const makePermalink = (text) => { | |
const url = new URL(baseURL); | |
url.searchParams.set('j', text); | |
return url; | |
} | |
// Get a tweetlink | |
// (string, string, string) -> URL | |
const makeTweetlink = (text, permalink, hashTag) => { | |
const tweet = text + ' ' + hashTag + ' ' + permalink; | |
const url = new URL('https://twitter.com/intent/tweet?text='); | |
url.searchParams.set('text', tweet); | |
return url; | |
} | |
// Get random chars | |
// (number, number) -> string | |
const randomChar = (from, to) => | |
String.fromCharCode( | |
from + Math.floor(Math.random()*(to - from))); | |
// Get random chars likea block | |
// () -> string | |
const randomCharOfBlock = () => randomChar(0x2580, 0x259F); | |
// Make random gabage text | |
// number -> string | |
const makeGlitchText = (length) => | |
Array(length).fill().map(randomCharOfBlock).join(''); | |
document.addEventListener('DOMContentLoaded', () => { | |
// Replace the caption of button by URL params like a `?j=🍣` | |
const params = new URLSearchParams(location.search); | |
const caption = params.get('j') | |
|| q('.redjavabo').textContent; | |
setCaption(caption, false); | |
// Replace the caption of button by URL | |
q('#input').addEventListener('input', (event) => { | |
const caption = event.target.value; | |
if (caption) { | |
setCaption(caption, false); | |
} else { | |
setCaption(makeGlitchText(10), true); | |
} | |
}); | |
}); |
'use strict'; | |
// Constants and aliases | |
const baseURL = 'https://codepen.io/tobynet/full/LagBKm'; | |
const hashTag = '#JavaButtonMaker'; | |
const q = document.querySelector.bind(document); | |
// Update the caption of the button | |
// (string, boolean) -> void | |
const setCaption = (text, allowsEmptyText) => { | |
q('.redjavabo').textContent = text.trim(); | |
const caption = q('.redjavabo').textContent; | |
const inputValue = allowsEmptyText ? "" : caption; | |
const permalink = allowsEmptyText ? baseURL : makePermalink(caption).toString(); | |
q('#input').value = inputValue; | |
q('#permalink').href = permalink; | |
q('#tweetlink').href = makeTweetlink(caption, permalink, hashTag).toString(); | |
}; | |
// Get a permalink | |
// string -> URL | |
const makePermalink = (text) => { | |
const url = new URL(baseURL); | |
url.searchParams.set('j', text); | |
return url; | |
}; | |
// Get a tweetlink | |
// (string, string, string) -> URL | |
const makeTweetlink = (text, permalink, hashTag) => { | |
const tweet = text + ' ' + hashTag + ' ' + permalink; | |
const url = new URL('https://twitter.com/intent/tweet?text='); | |
url.searchParams.set('text', tweet); | |
return url; | |
}; | |
// Get random chars | |
// (number, number) -> string | |
const randomChar = (from, to) => | |
String.fromCharCode( | |
from + Math.floor(Math.random()*(to - from))); | |
// Get random chars likea block | |
// () -> string | |
const randomCharOfBlock = () => randomChar(0x2580, 0x259F); | |
// Make random gabage text | |
// number -> string | |
const makeGlitchText = (length) => | |
Array(length).fill().map(randomCharOfBlock).join(''); | |
// Download node as image | |
// Element -> void | |
const downloadElementAsImage = (node) => { | |
domtoimage.toBlob(node) | |
.then(blob => { | |
window.saveAs(blob, 'javabutton.png') | |
}) | |
.catch(error => { | |
console.error('Error: dom to image', error); | |
// TODO: Show error dialog | |
q('.redjavabo').textContent = '[Error] ' + error; | |
}); | |
}; | |
document.addEventListener('DOMContentLoaded', () => { | |
// Replace the caption of button by URL params like a `?j=🍣` | |
const params = new URLSearchParams(location.search); | |
const caption = params.get('j') || q('.redjavabo').textContent; | |
setCaption(caption, false); | |
// Replace the caption of button by URL | |
q('#input').addEventListener('input', (event) => { | |
const caption = event.target.value; | |
if (caption) { | |
setCaption(caption, false); | |
} else { | |
setCaption(makeGlitchText(9), true); | |
} | |
}); | |
// Download link | |
q('#download-link').addEventListener('click', event => { | |
event.preventDefault(); // ignore a[href] | |
downloadElementAsImage(q('.redjavabo')); | |
}); | |
}); |
<script src="https://unpkg.com/dom-to-image-more@~2.7.5/src/dom-to-image-more.js"></script> | |
<script src="https://unpkg.com/file-saver@~2.0.0/dist/FileSaver.js"></script> |
/* ここからカット */ | |
/* Crimson Javabo */ | |
a.redjavabo { | |
font-size: 5em; | |
line-height: 1.4em; | |
display: inline-block; | |
text-decoration: none; | |
color: #fff; | |
font-family: 'MS Pゴシック', Osaka, "Noto Sans", "Noto Sans CJK JP", sans-serif; | |
font-weight: bold; | |
background-color: #f00; | |
border-radius: .4em; | |
padding-top: 0.15em; | |
padding-bottom: 0.2em; | |
padding-left: 1em; | |
padding-right: 1em; | |
min-width: 1em; | |
background-image: linear-gradient(to bottom, rgba(255,255,255,.17), rgba(255,255,255,.23) 40%, transparent 40%), linear-gradient(to bottom, #ff8791, #b50010); | |
background-size: auto, auto; | |
background-position: 0px 0px, 0px 0px; | |
text-align: center; | |
margin: 0; | |
word-wrap: break-word; | |
} | |
/* Royal Blue Javabo */ | |
a.bluejavabo{ | |
display: inline-block; | |
padding-top: .5em; | |
padding-bottom: .5em; | |
padding-left: 2em; | |
padding-right: 2em; | |
min-width: 11em; | |
text-decoration: none; | |
color: #fff; | |
font-family: 'MS Pゴシック', Osaka, "Noto Sans", "Noto Sans CJK JP", sans-serif; | |
font-weight: normal; | |
background-color: #007; | |
border-radius: .8em; | |
border: 2px solid #333; | |
background-color: #007; | |
background-image: linear-gradient(to bottom,rgb(125,227,255) 2px,rgb(39,181,247) 2px, rgb(7,123,242) 33%, rgb(0,32,115) 50%,rgb(0,34,70)); | |
text-align: center; | |
margin: .5em; | |
} | |
/* ここまでカット */ | |
/* pervasive */ | |
body { | |
font-family: sans-serif; | |
text-align: center; | |
} | |
div.javabo { | |
padding: 2em 2em; | |
} | |
input { | |
line-height: 1.6em; | |
font-size: 1.6em; | |
border: 1px solid #cecece; | |
border-radius: 9px; | |
padding: 0.2em 0.6em; | |
margin: 0.20em 0.25em; | |
width: 10em; | |
} | |
input:active, | |
input:focus { | |
outline: 0; | |
box-shadow: 0 0 0 0.11em rgba(120,0,10,0.10); | |
} | |
label { | |
font-size: 1.2em; | |
} | |
.button { | |
display: inline-block; | |
margin: 0.4em 0.4em; | |
padding: 0.4em 1.0em; | |
border: 1px solid gray; | |
border-radius: 9px; | |
text-decoration-line: none; | |
font-weight: bold; | |
} | |
#tweetlink { | |
color: white; | |
border-color: #1b95e0; | |
background-color: #1b95e0; | |
min-width: 4em; | |
} | |
/* For mobile */ | |
@media screen and (max-width: 500px) { | |
a.redjavabo { | |
font-size: 2.0em; | |
padding-top: 0.4em; | |
padding-bottom: 0.5em; | |
} | |
label[for="input"] { | |
display: block; | |
} | |
input { | |
font-size: 1.2em; | |
} | |
} |