您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
Pixel Place Tools
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greasyfork.icu/scripts/443807/1045808/PPT.js
// ==UserScript== // @name PPT // @description Pixel Place Tools // @version 2.0 // @author 0vC4 // @namespace http://greasyfork.icu/users/670183 // @match https://pixelplace.io/* // @icon https://www.google.com/s2/favicons?sz=64&domain=pixelplace.io // @license MIT // @grant none // @run-at document-start // ==/UserScript== const PPT = (() => { if (window.PPT) return window.PPT; const worker = function(func) { const worker = new Worker(URL.createObjectURL(new Blob(["onmessage=async({data})=>self.postMessage(await(" + func.toString() + ")(data))"], { type: "text/javascript" }))); const root = {}; const post = data => (worker.postMessage(data), root); const then = callback => (worker.onmessage=({data})=>callback(data), root); return Object.assign(root, {post, then}); }; const PPT = { zero: 0xCCCCCC, default: new Uint32Array([ 0xFFFFFF, 0xC4C4C4, 0x888888, 0x555555, 0x222222, 0x000000, 0x006600, 0x22B14C, 0x02BE01, 0x51E119, 0x94E044, 0xFBFF5B, 0xE5D900, 0xE6BE0C, 0xE59500, 0xA06A42, 0x99530D, 0x633C1F, 0x6B0000, 0x9F0000, 0xE50000, 0xFF3904, 0xBB4F00, 0xFF755F, 0xFFC49F, 0xFFDFCC, 0xFFA7D1, 0xCF6EE4, 0xEC08EC, 0x820080, 0x5100FF, 0x020763, 0x0000EA, 0x044BFF, 0x6583CF, 0x36BAFF, 0x0083C7, 0x00D3DD, 0x45FFC8 ]), exclude: new Uint32Array([ 0x51E119, 0xFF3904, 0x5100FF, 0x45FFC8 ]), get palette() { return this.default.map(color => this.exclude.includes(color) ? this.zero : color); }, _wheelID: 0, get wheel() { let pixel = this._wheelID+1; while (this.palette[pixel] == this.zero) if (this.palette[++pixel] == null) pixel = 0; this._wheelID = pixel; return this._wheelID; }, RGB2P(r, g, b) { const closest = [...this.palette] .filter(n => n != this.zero) .map(clr => [ ((r - ((clr>>16)&0xFF))*.299)**2 + ((g - ((clr>>8)&0xFF))*.587)**2 + ((b - (clr&0xFF))*.114)**2, clr ] ) .sort((a,b) => a[0]-b[0]) [0][1]; return this.palette.indexOf(closest); }, CLR2P(color) { return this.RGB2P((color>>16)&0xFF, (color>>8)&0xFF, color&0xFF); }, client: null, get order() { if (!this.client) throw new Error('assign client variable first'); const queue = this.client._pixelQueue; const [cx, cy] = queue.reduce(([x,y], [x2,y2]) => { if (!x) return [x2,y2]; return [x+x2>>1, y+y2>>1]; }, [0, 0]); const workQueue = (func, ...args) => { let fin = queue => 0; const then = finish => fin = finish; worker(func) .then(queue => fin(this.client._pixelQueue = queue)) .post([queue, ...args]); return {then} }; return { start(finish){ workQueue(([queue]) => { return [...queue].sort(([x,y,p,i], [x2,y2,p2,i2]) => i-i2); }).then(finish); }, end(finish){ workQueue(([queue]) => { return [...queue].sort(([x,y,p,i], [x2,y2,p2,i2]) => i2-i); }).then(finish); }, rand(finish){ workQueue(([queue]) => { return [...queue].sort(() => Math.random()-.5); }).then(finish); }, top(finish){ workQueue(([queue]) => { return [...queue].sort(([x,y], [x2,y2]) => y-y2); }).then(finish); }, left(finish){ workQueue(([queue]) => { return [...queue].sort(([x,y], [x2,y2]) => x-x2); }).then(finish); }, right(finish){ workQueue(([queue]) => { return [...queue].sort(([x,y], [x2,y2]) => x2-x); }).then(finish); }, bottom(finish){ workQueue(([queue]) => { return [...queue].sort(([x,y], [x2,y2]) => y2-y); }).then(finish); }, fromCenter(finish){ workQueue(([queue, cx, cy]) => { return [...queue].sort(([x,y], [x2,y2]) => ((x-cx)**2+(y-cy**2)) - ((x2-cx)**2+(y2-cy**2)) ); }, cx, cy).then(finish); }, toCenter(finish){ workQueue(([queue, cx, cy]) => { return [...queue].sort(([x,y], [x2,y2]) => ((x2-cx)**2+(y2-cy**2)) - ((x-cx)**2+(y-cy**2)) ); }, cx, cy).then(finish); }, }; }, timer: window, pixel: 0, size: 1, innerSize: 0, speed: 100, map: {pixels:[],width:0,height:0,get(x,y){return 255}}, square(x,y, callback, finish) { const {pixel, timer, speed, size, innerSize} = this; const half = size>>1; const innerHalf = innerSize>>1; let xi = -half; let yi = -half; let t = timer.setInterval(() => { let i = 0; for (; yi < half+1;) { for (; xi < half+1;) { if (pixel === 255 || xi > -innerHalf && xi < innerHalf && yi > -innerHalf && yi < innerHalf) { xi++; continue; } callback(x+xi, y+yi, pixel, t); xi++; i++; if (i > speed) return; continue; } yi++; xi = -half; } timer.clearInterval(t); finish(); }); return t; }, ring(x,y, callback, finish) { const {pixel, timer, speed, size, innerSize} = this; const half = size>>1; const innerHalf = innerSize>>1; let xi = -half; let yi = -half; let t = timer.setInterval(() => { let i = 0; for (; yi < half+1;) { for (; xi < half+1;) { if (pixel === 255 || xi**2 + yi**2 > half**2 || xi**2 + yi**2 < innerHalf**2) { xi++; continue; } callback(x+xi, y+yi, pixel, t); xi++; i++; if (i > speed) return; continue; } yi++; xi = -half; } timer.clearInterval(t); finish(); }); return t; }, shader(callback, finish) { const {timer, speed, map} = this; let pos = 0; let t = timer.setInterval(() => { let i = 0; for (; pos < map.pixels.length; ) { if (map.pixels[pos] === 255) { pos++; continue; } callback(pos%map.width, pos/map.width>>0, map.pixels[pos], t); pos++; i++; if (i > speed) return; continue; } timer.clearInterval(t); finish(); }); return t; }, image(pixels, x,y,w,h, callback, finish) { const {timer, speed} = this; let xi = 0; let yi = 0; let t = timer.setInterval(() => { let i = 0; for (; yi < h;) { for (; xi < w;) { const pixel = pixels[xi+yi*w]; if (pixel === 255) { xi++; continue; } callback(x+xi, y+yi, pixel, t); xi++; i++; if (i > speed) return; continue; } yi++; xi = 0; } timer.clearInterval(t); finish(); }); return t; } }; window.PPT = PPT; return PPT; })(); // 0vC4#7152