Flag Upload

当前为 2014-08-19 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name        Flag Upload
// @include     http://*.legacy-game.net/flag.php*
// @version     1.0
// @grant       none
/*global $,FileReader,pic,HTMLCanvasElement */
// ==/UserScript==

/*****************************************************
                    General Methods                    
/****************************************************/
//
function create(type,attr,text,parent){
    var ele = document.createElement(type);
    for(var x in attr){
        if(x.hasOwnProperty){
            ele.setAttribute(x,attr[x]);
        }
    }
    if(text){ele.innerHTML = text;}
    if(parent){parent.appendChild(ele);}
    return ele;
}

//Method to convert RGB values into hex for flag variables
function toHex(r, g, b) {
    var hex ="0123456789ABCDEF", ans;
    r = hex.charAt((r - (r % 16)) / 16) + hex.charAt(r % 16);
    g = hex.charAt((g - (g % 16)) / 16) + hex.charAt(g % 16);
    b = hex.charAt((b - (b % 16)) / 16) + hex.charAt(b % 16);
    ans = "#" + r + g + b;
    return ans;
}
/*****************************************************
                    CSS Injection                    
/****************************************************/
var custom = ""+
        "#uploadPanel{height:auto; width:auto; background: red none; border: 5px solid darkred; padding: 5px; position:absolute; top:20px; left:20px; max-height:90%; max-width:90%; padding-right:20px; overflow:auto;}\n"+
        "#flagOut{border:1px solid #c3c3c3; display:inline-block;}\n"+
        "#container{position:relative; display:block; height:30px; width:40px; padding:1px;}\n"+
        "#rawImage{position: absolute; display:block; z-index:1;}\n"+
        "#getArea{position:absolute; height:30px; width:40px; top:1px; left:1px; border:1px solid red;z-index:2;}\n"+
        "#imageUpload{display:block;}\n"+
        "#editPanel{display:none;}";

create('link',{rel:'stylesheet',href:'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css'},false,document.head);
create('style',{type:'text/css'},custom,document.head);

/*****************************************************
                    Interface Creation & Injection                    
/****************************************************/

var panel = create('div',{id:'uploadPanel'},false,document.body);
create('canvas',{id:'flagOut',width:'40',height:'30'},false,panel);
create('input',{id:'toFlag',type:'button',value:'Send to Flag'},false,panel);
create('span',{},'<br/>Resize Select Box:',panel);
create('input',{id:'resizeToggle',type:'checkbox'},false,panel);
create('span',{},'<br/>Keep Aspect Ratio:',panel);
create('input',{id:'Aratio',type:'checkbox',checked:'checked',disabled:'disabled'},false,panel);
create('span',{},'<br/>',panel);
create('input',{id:'reset',type:'button',value:'Reset to 40X30'},false,panel);
create('input',{id:'rawImgHide',type:'button',value:'Show/Hide Canvas'},false,panel);
create('span',{},'<br/>',panel);
create('span',{id:'edit'},'Editing Tools',panel);
var edit = create('div',{id:'editPanel'},false,panel);
create('input',{id:'greyscale',type:'button',value:'Greyscale'},false,edit);
create('input',{id:'invert',type:'button',value:'Invert'},false,edit);
var container = create('div',{id:'container'},false,panel);
create('canvas',{id:'rawImage',width:'40',height:'30'},false,container);
create('div',{id:'getArea'},false,container);
create('input',{id:'imageUpload',type:'file'},false,panel);

/*****************************************************
                    Canvas Methods                    
/****************************************************/

//Sends image data to 'large' canvas, from which we can select the desired area
function toRawCanvas(imgData){
    var img = new Image() ,
        rawcanvas = document.getElementById('rawImage'), 
        context = rawcanvas.getContext('2d'), 
        area;
    img.src = imgData;
    img.onload = function() {
        var container = document.getElementById('container');
        container.style.height=img.height+2+'px';
        container.style.width=img.width+2+'px';
        rawcanvas.height=img.height+2;
        rawcanvas.width=img.width+2;
        context.drawImage(img, 1, 1);
        area = document.getElementById('getArea');
        area.style.top='1px';
        area.style.left='1px';
    };
}

//Ctrl + V to paste an image to the canvas
//Currently only available with Chrome
function onPasteHandler(e){
    if(e.clipboardData) {
        var items = e.clipboardData.items,
            blob, 
            source;
        if(!items){
            alert("Image Not found");
        }
        for (var i = 0; i < items.length; ++i) {
            if (items[i].type.match('image.*')) {
                blob = items[i].getAsFile();
                source = window.webkitURL.createObjectURL(blob);
                toRawCanvas(source);
            }
        }
    }
}
//Use jQuery UI to allow the capture div inside the raw canvas to move freely when dragging
$(function(){
    $('#getArea').draggable({containment:'parent'});
    window.addEventListener("paste", onPasteHandler);
});
//Show/Hide the Raw Canvas from view 
//Mainly for when the image is larger than the window, or file upload is difficult to see
$('#rawImgHide').click(function(){
    $('#container').slideToggle('slow');
});
//Reset the capture div back to default size
$('#reset').click(function(){
    var area = document.getElementById('getArea');
    area.style.height="30px";
    area.style.width="40px";
});
//Allow the capture div to be resizable (jQuery UI)
//Aspect ratio can only be enabled/disabled when the capture div is resizable            
$('#resizeToggle').click(function(){
    if(this.checked){
        if ($('#Aratio').is(':checked')){
            $('#getArea').resizable({aspectRatio: true, containment:'parent'});
        }
        else{
            $('#getArea').resizable({containment:'parent'});
        }
        $('#Aratio').prop('disabled','');
    }
    else{
        $('#getArea').resizable('destroy');
        $('#Aratio').prop('disabled','disabled');
    }
});
//Enable/Disable aspect ratio on capture div
//Disabling may cause stretching/skewing of output flag
$('#Aratio').click(function(){
    if (this.checked){
        $('#getArea').resizable('destroy');
        $('#getArea').resizable({aspectRatio: true, containment:'parent'});
    }
    else{
        $('#getArea').resizable('destroy');
        $('#getArea').resizable({aspectRatio: false, containment:'parent'});
    }
}); 
//Image upload from local machine to raw canvas
$('#imageUpload').change(function(){
    if (document.getElementById("imageUpload").files.length === 0) {
        return;
    }
    var flag = document.getElementById("imageUpload").files[0],
        reader;
    if (!flag.type.match('image.*')) {
        alert("Not an image");
        return;
    }
    reader = new FileReader();
    reader.onload = (function() {
        return function(e) {
            toRawCanvas(e.target.result);
        };
    }(flag));
    reader.readAsDataURL(flag);
});
//After moving capture div to desired area, send containing image to secondry canvas to preview before sending to legacy page
//Resize to fit 40X30 pixels where needed using native methods
$('#getArea').mouseup(function(){
    var rawcanvas = document.getElementById('rawImage'),
        out = document.getElementById('flagOut'),
        area = document.getElementById('getArea'),
        outctx = out.getContext('2d'),
        x=parseInt(area.style.left,10),
        y=parseInt(area.style.top,10);
    outctx.clearRect (0,0,out.width,out.height);
    outctx.drawImage(rawcanvas, x, y,area.clientWidth,area.clientHeight,0,0,out.width,out.height);
});
//Sent image from preview canvas to legacy page, adjusting page variables and 'pixel' block backgrounds
$('#toFlag').click(function(){
    var canvas=document.getElementById('flagOut'),
        context = canvas.getContext('2d'),
        w = canvas.width,
        h = canvas.height,
        imgd = context.getImageData(0, 0, w, h),
        pix = imgd.data;

    for (var i = 0; i < h; i++) {
        for (var j = 0; j < w; j++) {
            document.getElementsByName("X"+j+"Y"+i)[0].bgColor = pic[j+i*w] = toHex(pix[(j+i*w)*4], pix[(j+i*w)*4 + 1], pix[(j+i*w)*4 + 2]);
        }
    }
});
/*****************************************************
                    Effect Addons                    
/****************************************************/
//Hide/Show effect options
$('#edit').click(function(){
    $('#editPanel').slideToggle();
});
//Perform greyscale effect on output flag
$('#greyscale').click(function(){
    document.getElementById('flagOut').greyscale();
});
//Invert output flag colours
$('#invert').click(function(){
    document.getElementById('flagOut').invert();
});

HTMLCanvasElement.prototype.greyscale = function(){
    var ctx = this.getContext('2d'),
        data = ctx.getImageData(0,0,this.width,this.height),
        d = data.data;
    for(var i=0;i<d.length;i+=4){
         d[i]= d[i+1] = d[i+2] = 0.2126*d[i] + 0.7152*d[i+1] + 0.0722*d[i+2];
    }
    ctx.putImageData(data,0,0);
};

HTMLCanvasElement.prototype.invert = function(){
    var ctx = this.getContext('2d'),
        data = ctx.getImageData(0,0,this.width,this.height),
        d = data.data;
    for(var i=0;i<d.length;i+=4){
        d[i]=255-d[i];
        d[i+1]=255-d[i+1];
        d[i+2]=255-d[i+2];
    }
    ctx.putImageData(data,0,0);
};