Skip to content

Instantly share code, notes, and snippets.

@tosaka2
Created August 18, 2017 14:28
Show Gist options
  • Save tosaka2/335b0f363cfedfe84ea404b4956d305b to your computer and use it in GitHub Desktop.
Save tosaka2/335b0f363cfedfe84ea404b4956d305b to your computer and use it in GitHub Desktop.
// return t.generate()の行にブレークポイント
var getObject = () => t;
var getState = () => getObject().state;
var getOption = () => getState().options;
var getNoise = () => getState().gan.noise;
var getNoiseOrigin = () => getState().gan.noiseOrigin;
var isRunning = () => getState().gan.isRunning;
// NoiseをFixedに
var fixNoise = () => getOption().noise = 1;
// NoiseをRandomに
var randomNoise = () => getOption().noise = 0;
// Noiseを出力
var printNoise = () => "[" + getNoise().join(',') + "]";
// Noiseを設定
var setNoise = a => {
if (isRunning()) return;
cn = getNoise();
for (let i = 0; i < a.length; i++) {
cn[i] = a[i];
}
};
var setNoiseOrigin = a => {
if (isRunning()) return;
cn = getNoiseOrigin();
for (let i = 0; i < a.length; i++) {
cn[i][0] = a[i][0];
cn[i][1] = a[i][1];
}
}
// 中断フラグ
var _isAborted = false;
var _selected = [[],[]];
// Generate
var generate = async () => {
if (isRunning()) return;
await getObject().generate();
};
// NoiseをRandomにしてGenerate
var generateByRandom = async () => { randomNoise(); await generate(); };
// 引数で指定したNoiseでGenerate
var generateBy = async a => { fixNoise(); setNoise(a); await generate() };
var cancel = () => { _isAborted = true; };
// ベクトルの操作
var add = (a, b) => a.map((x, i) => x + b[i]);
var sub = (a, b) => a.map((x, i) => x - b[i]);
var times = (a, t) => a.map((x, i) => x * t);
var interpolate = (a, b, p) => a.map((x, i) => x * (1-p) + b[i] * p);
// Current Noiseにした時にできるだけ絵が変わってしまわないようにする
var calculatebackToPixel = v => {
let calc = (b, g) => Math.sqrt( -2.0 * Math.log( b ) ) * Math.cos( 2.0 * Math.PI * g );
let f = (bg) => calc(1-bg[0]/256, 1-bg[1]/256);
let min_diff = 100000000;
let res_b = 0;
let res_g = 0;
// 乱択のほうが速そう
for (let b = 1; b < 256; b++) {
let u = Math.sqrt( -2.0 * Math.log( 1 - b/ 256) );
if (v / u < -1 || v / u > 1) continue;
let pg = (1 - (Math.acos(v / u) / (2 * Math.PI))) * 256;
let g = Math.floor(pg + 0.5); //四捨五入
if (g < 0 || g >= 256) continue;
var diff = (v - f([b, g])) ** 2;
if (diff < min_diff) {
if(min_diff < 100) console.log(min_diff - diff);
min_diff = diff;
res_b = b;
res_g = g;
break; //一度更新できたらそれにしちゃう
}
}
return [res_b, res_g];
// これだとピクセル値にした時の誤差が大きい?
//let res_b = Math.floor((1 - Math.exp((v ** 2) / -2)) * 256);
//let res_g = Math.floor((1 - (Math.acos(Math.sign(v)) / 2 * Math.PI)) * 256);
}
var noiseToPixels = a => a.map(calculatebackToPixel);
var pixelToNoiseOrigin = ps => ps.map(x => [1 - x[0]/256, 1 - x[1]/256]);
var noiseToNoiseOrigin = a => pixelToNoiseOrigin(noiseToPixels(a));
var downloadImage = (img = _selected[0][0], name = "mgm.png") => {
img = img || document.body.querySelector(".result-canvas").firstChild;
let a = document.createElement("a");
a.href = img.src;
a.target = "_blank";
a.download = name;
a.click();
}
// 生成済みの画像を下に表示
var addImg = (src, noise = null, noiseOrigin = null) => {
let results = document.body.querySelector(".imgs");
if (!results) {
results = document.createElement("div");
results.className = "row imgs";
document.body.querySelector(".App").appendChild(results);
}
let img = document.createElement("img");
noise = noise || getNoise();
noise = noise.map(x => x);
img.src = src;
img.onclick = () => {
console.log("[" + noise.join(',') + "]");
console.log(img);
if (_selected[1][1] && _selected[0][1] != _selected[1][1]) {
_selected[1][1].style.border = "none";
}
_selected = [[noise, img, noiseOrigin], _selected[0]];
if (_selected[1][1]){
_selected[1][1].style.border = "dashed";
_selected[1][1].style.opacity = 1.0;
}
_selected[0][1].style.border = "solid";
//img.style.opacity = 0.5;
if (_selected[1][1] && _selected[0][1] == _selected[1][1]) {
downloadImage(img);
}
}
results.insertBefore(img, results.firstChild);
return img;
}
// 下に表示してある画像をクリア
var clearImgs = () => {
let imgs = document.body.querySelector(".imgs");
for (let x of imgs.children) {
x.onclick = null;
x.src = "";
}
imgs.parentNode.removeChild(imgs);
}
// 下に表示してある画像を一枚消す
var deleteImg = img => {
img.onclick = null;
img.src = "";
img.parentNode.removeChild(img);
}
// aとbに指定したNoiseでn枚画像補間し,下に表示.wait_secはGenerateにかかる時間(実行環境により調整).
var generateInterpolations = async (n, a, b, im1 = null, im2 = null) => {
if (isRunning()) return;
let result = document.body.querySelector(".result-canvas").firstChild;
// すでに生成された画像かどうか
let ok = im1 && im2;
if (ok) addImg(im1.src, a);
for (let i = ok ? 1 : 0; i < (ok ? n - 1 : n); i++) {
if (_isAborted) {
_isAborted = false;
break;
}
let noise = interpolate(a, b, i / (n - 1));
await generateBy(noise);
addImg(result.src, noise);
}
if (ok) addImg(im2.src, b);
}
// RandomなNoiseでn枚画像生成し,下に表示.wait_secはGenerateにかかる時間(実行環境により調整).
var generateRandomImages = async n => {
if (isRunning()) return;
let result = document.body.querySelector(".result-canvas").firstChild;
for (let i = 0; i <= n - 1; i++) {
if (_isAborted) {
_isAborted = false;
break;
}
await generateByRandom();
addImg(result.src);
}
}
// 指定したオプションの値をfromからtoまで動かして生成。
// param: オプション, n: 枚数, a: ノイズ
var generateSomeParams = async (param, n, a, from, to) => {
if (isRunning()) return;
a = a || getNoise();
let result = document.body.querySelector(".result-canvas").firstChild;
let op = getOption();
let moto = op[param];
for(let i = 0; i < n; i++) {
if (_isAborted) {
_isAborted = false;
break;
}
op[param] = from + ((to - from) * i / (n - 1));
await generateBy(a);
addImg(result.src, a);
}
op[param] = moto;
}
// ボタン追加処理
var addButton = (text, func) => {
let buttons = document.body.querySelector(".exbtns");
if (!buttons) {
buttons = document.createElement("div");
buttons.className = "row exbtns";
document.body.querySelector(".options-container").lastChild.appendChild(buttons);
}
let b = document.body.querySelector(".btn-primary").cloneNode();
b.textContent = text;
b.onclick = func;
buttons.appendChild(b);
}
(() => {
let buttons = document.body.querySelector(".exbtns");
if (buttons) {
buttons.parentNode.removeChild(buttons);
}
addButton("生成10", () => generateRandomImages(10));
addButton("100", () => generateRandomImages(100));
addButton("1000", () => generateRandomImages(1000));
addButton("∞", () => generateRandomImages(100000000000000000));
addButton("補間", () => generateInterpolations(10, _selected[0][0], _selected[1][0], _selected[0][1], _selected[1][1]));
addButton("百合", () => generateInterpolations(3, _selected[0][0], _selected[1][0], _selected[0][1], _selected[1][1]));
addButton("中断", () => { cancel() });
// isRunning弾かないとgetNoise()でバグる
addButton("下へ", () => { if (isRunning()) return; addImg(document.body.querySelector(".result-canvas").firstChild.src, getNoise()); });
addButton("上へ", () => { generateBy(_selected[0][0]); });
// 選択したやつなのか、表示してる画像なのかわかりにくいけど許して
addButton("口パク", () => generateSomeParams("open_mouth", 10, _selected[0][0], 1, -1));
addButton("笑顔", () => generateSomeParams("smile", 10, _selected[0][0], 2, -1));
addButton("Blush x2", () => getOption().blush = 2);
addButton("Smile x2", () => getOption().smile = 2);
addButton("Open Mouth x2", () => getOption().open_mouth = 2);
addButton("Hat x2", () => getOption().hat = 2);
addButton("x3", () => getOption().hat = 3);
addButton("Ribbon x2", () => getOption().ribbon = 2);
addButton("Glasses x2", () => getOption().glasses = 2);
addButton("x3", () => getOption().glasses = 3);
addButton("クリア", () => clearImgs());
addButton("1枚削除", () => {
deleteImg(_selected[0][1]);
_selected[0] = _selected[1];
});
addButton("Current Noise更新", (event) => {
//event.srcElement.style.opacity = 0.5;
event.srcElement.disabled = true;
console.log("Updating Current Noise...");
setNoiseOrigin(noiseToNoiseOrigin(getNoise()));
console.log("Complete!");
event.srcElement.disabled = false;
getObject().setNoiseOrigin(getNoiseOrigin());
//event.srcElement.style.opacity = 1;
});
/*
// デフォルトオプション
op = getOption();
op.hair_color = 11;
op.hair_style = 1;
op.eye_color = 8;
op.blush = -1;
op.smile = 1;
op.open_mouth = 1;
op.hat = -1;
op.ribbon = 1;
op.glasses = -1;
*/
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment