Skip to content

Instantly share code, notes, and snippets.

@dbowring
Created May 4, 2015 13:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dbowring/91e423abfc8d67519da7 to your computer and use it in GitHub Desktop.
Save dbowring/91e423abfc8d67519da7 to your computer and use it in GitHub Desktop.
Jisho.org Kanji details page Stroke Order downloader
javascript:(function(){function%20r(d){return%20d&&0==d.lastIndexOf("http",0)&&-1==d.lastIndexOf(window.location.host)}function%20n(d,f){var%20c=d.querySelectorAll("image"),h=c.length;0==h&&f();for(var%20b=0;b<c.length;b++)(function(b){var%20a=b.getAttribute("xlink:href");if(a&&r(a.value))console.warn("Cannot%20render%20embedded%20images%20linking%20to%20external%20hosts:%20"+a.value);else{var%20e=document.createElement("canvas"),d=e.getContext("2d"),c=new%20Image,a=a||b.getAttribute("href");c.src=a;c.onload=function(){e.width=c.width;e.height=%20c.height;d.drawImage(c,0,0);b.setAttribute("xlink:href",e.toDataURL("image/png"));h--;0==h&&f()};c.onerror=function(){console.log("Could%20not%20load%20"+a);h--;0==h&&f()}}})(c[b])}var%20t=function(d,f,c){f=f||{};f.scale=f.scale||1;n(d,function(){var%20h=document.createElement("div"),b=d.cloneNode(!0),g,a;if("svg"==d.tagName)a=d.getBoundingClientRect(),g=a.width,a=a.height;else{a=d.getBBox();g=a.x+a.width;a=a.y+a.height;b.setAttribute("transform",b.getAttribute("transform").replace(/translate\(.*?\)/,""));%20var%20e=document.createElementNS("http://www.w3.org/2000/svg","svg");e.appendChild(b);b=e}b.setAttribute("version","1.1");b.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns","http://www.w3.org/2000/svg");b.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink");b.setAttribute("width",g*f.scale);b.setAttribute("height",a*f.scale);b.setAttribute("viewBox","0%200%20"+g+"%20"+a);h.appendChild(b);g=f.selectorRemap;a="";for(var%20e=document.styleSheets,l=0;l<e.length;l++)if(r(e[l].href))console.warn("Cannot%20include%20styles%20from%20other%20hosts:%20"+%20e[l].href);else{var%20p=e[l].cssRules;if(null!=p)for(var%20q=0;q<p.length;q++){var%20k=p[q];if("undefined"!=typeof%20k.style){var%20m=null;try{m=d.querySelector(k.selectorText)}catch(n){console.warn('Invalid%20CSS%20selector%20"'+k.selectorText+'"',n)}m?(m=g?g(k.selectorText):k.selectorText,a+=m+"%20{%20"+k.style.cssText+"%20}\n"):k.cssText.match(/^@font-face/)&&(a+=k.cssText+"\n")}}}g=document.createElement("style");g.setAttribute("type","text/css");g.innerHTML="<![CDATA[\n"+a+"\n]]\x3e";a=document.createElement("defs");%20a.appendChild(g);b.insertBefore(a,b.firstChild);e='<?xml%20version="1.0"%20standalone="no"?><!DOCTYPE%20svg%20PUBLIC%20"-//W3C//DTD%20SVG%201.1//EN"%20"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">'+h.innerHTML;h="data:image/svg+xml;base64,"+window.btoa(unescape(encodeURIComponent(e)));c&&c(h)})},u=$("h1.character").text()||"kanji";(function(d,f,c){c=c||{};t(d,c,function(c){var%20b=new%20Image;b.src=c;b.onload=function(){var%20c=document.createElement("canvas");c.width=b.width;c.height=b.height;c.getContext("2d").drawImage(b,%200,0);var%20a=document.createElement("a");a.download=f;a.href=c.toDataURL("image/png");document.body.appendChild(a);a.addEventListener("click",function(b){a.parentNode.removeChild(a)});a.click()}})})($(".stroke_order_diagram--outer_container%20>%20svg").get(0),u+".png")})();
// Made using saveSvgAsPNG: https://github.com/exupero/saveSvgAsPng
(function() {
var doctype = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">';
function isExternal(url) {
return url && url.lastIndexOf('http',0) == 0 && url.lastIndexOf(window.location.host) == -1;
}
function inlineImages(el, callback) {
var images = el.querySelectorAll('image');
var left = images.length;
if (left == 0) {
callback();
}
for (var i = 0; i < images.length; i++) {
(function(image) {
var href = image.getAttribute('xlink:href');
if (href) {
if (isExternal(href.value)) {
console.warn("Cannot render embedded images linking to external hosts: "+href.value);
return;
}
}
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
var img = new Image();
href = href || image.getAttribute('href');
img.src = href;
img.onload = function() {
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
image.setAttribute('xlink:href', canvas.toDataURL('image/png'));
left--;
if (left == 0) {
callback();
}
}
img.onerror = function() {
console.log("Could not load "+href);
left--;
if (left == 0) {
callback();
}
}
})(images[i]);
}
}
function styles(el, selectorRemap) {
var css = "";
var sheets = document.styleSheets;
for (var i = 0; i < sheets.length; i++) {
if (isExternal(sheets[i].href)) {
console.warn("Cannot include styles from other hosts: "+sheets[i].href);
continue;
}
var rules = sheets[i].cssRules;
if (rules != null) {
for (var j = 0; j < rules.length; j++) {
var rule = rules[j];
if (typeof(rule.style) != "undefined") {
var match = null;
try {
match = el.querySelector(rule.selectorText);
} catch(err) {
console.warn('Invalid CSS selector "' + rule.selectorText + '"', err);
}
if (match) {
var selector = selectorRemap ? selectorRemap(rule.selectorText) : rule.selectorText;
css += selector + " { " + rule.style.cssText + " }\n";
} else if(rule.cssText.match(/^@font-face/)) {
css += rule.cssText + '\n';
}
}
}
}
}
return css;
}
var svgAsDataUri = function(el, options, cb) {
options = options || {};
options.scale = options.scale || 1;
var xmlns = "http://www.w3.org/2000/xmlns/";
inlineImages(el, function() {
var outer = document.createElement("div");
var clone = el.cloneNode(true);
var width, height;
if(el.tagName == 'svg') {
var box = el.getBoundingClientRect();
width = box.width;
height = box.height;
} else {
var box = el.getBBox();
width = box.x + box.width;
height = box.y + box.height;
clone.setAttribute('transform', clone.getAttribute('transform').replace(/translate\(.*?\)/, ''));
var svg = document.createElementNS('http://www.w3.org/2000/svg','svg')
svg.appendChild(clone)
clone = svg;
}
clone.setAttribute("version", "1.1");
clone.setAttributeNS(xmlns, "xmlns", "http://www.w3.org/2000/svg");
clone.setAttributeNS(xmlns, "xmlns:xlink", "http://www.w3.org/1999/xlink");
clone.setAttribute("width", width * options.scale);
clone.setAttribute("height", height * options.scale);
clone.setAttribute("viewBox", "0 0 " + width + " " + height);
outer.appendChild(clone);
var css = styles(el, options.selectorRemap);
var s = document.createElement('style');
s.setAttribute('type', 'text/css');
s.innerHTML = "<![CDATA[\n" + css + "\n]]>";
var defs = document.createElement('defs');
defs.appendChild(s);
clone.insertBefore(defs, clone.firstChild);
var svg = doctype + outer.innerHTML;
var uri = 'data:image/svg+xml;base64,' + window.btoa(unescape(encodeURIComponent(svg)));
if (cb) {
cb(uri);
}
});
};
var saveSvgAsPng = function(el, name, options) {
options = options || {};
svgAsDataUri(el, options, function(uri) {
var image = new Image();
image.src = uri;
image.onload = function() {
var canvas = document.createElement('canvas');
canvas.width = image.width;
canvas.height = image.height;
var context = canvas.getContext('2d');
context.drawImage(image, 0, 0);
var a = document.createElement('a');
a.download = name;
a.href = canvas.toDataURL('image/png');
document.body.appendChild(a);
a.addEventListener("click", function(e) {
a.parentNode.removeChild(a);
});
a.click();
}
});
};
var kanji = $('h1.character').text() || 'kanji';
var svg = $('.stroke_order_diagram--outer_container > svg');
saveSvgAsPng(svg.get(0), kanji + '.png');
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment