// ==UserScript==
// @name 百度贴吧图片点击放大
// @version 1.5.9.20170312
// @description 直接在当前页面查看图片(支持签名档)原图,可缩放,可多开,可拖拽
// @include *://tieba.baidu.com/p/*
// @include *://tieba.baidu.com/f?*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_addStyle
// @grant GM_registerMenuCommand
// @author lliwhx
// @copyright Copyright 2016-2017 lliwhx
// @license MIT License
// @namespace https://github.com/lliwhx/Userscripts
// ==/UserScript==
//CSS
GM_addStyle(".BDE_Image,.j_user_sign{cursor:url('https://imgsrc.baidu.com/forum/pic/item/ff6278f0f736afc3a6ee1fefba19ebc4b6451203.png'),alias;}#Tie_enlargeImage_parentDIV{position:fixed;z-index:1005;top:0;left:0;}.Tie_enlargeImage{position:absolute;box-shadow:1px 1px 10px #000;cursor:url('https://imgsrc.baidu.com/forum/pic/item/ff6278f0f736afc3a6ee1fefba19ebc4b6451203.png'),move;}.Tie_enlargeImage:hover{z-index:1006;}#Tie_setValue_DIV{position:fixed;top:0;left:0;width:100%;height:100%;z-index:9999;background:rgba(0,0,0,0.5);}.Tie_definedDIV{position:absolute;z-index:10000;background:#fff;top:50%;left:50%;transform:translate(-50%,-50%);}.Tie_definedDIV_title{border-bottom:1px solid #f2f2f5;line-height:40px;font-size:15px;font-weight:700;padding:0 0 0 15px;}.Tie_definedDIV_point{padding:20px 40px;}.Tie_groupSubtitle{font-weight:bold;}.Tie_configItem{line-height:30px;margin:0 20px}.Tie_configItem select{margin:0.5em}.Tie_configItem br+label{margin-left:3em}.Tie_configItem input{vertical-align:middle;margin-right:0.5em}#Tie_debugConfig{margin:0.5em}.Tie_debugConfig_icon{position:relative;display:inline-block;top:4px;width:16px;height:16px;background-position:-350px -100px;background-image:url('https://img.t.sinajs.cn/t6/style/images/common/icon.png');background-repeat:no-repeat;}.Tie_definedDIV_SaveBtn{background-color:#f2f2f5;text-align:center;padding:10px 0;}.Tie_SaveBtn_a{background:#ff8140;color:#fff;font-size:15px;display:inline-block;padding:0 15px;line-height:35px;border-radius:3px;}.Tie_SaveBtn_a:hover{background:#f7671d}");
//数据缓存
var target,imageTarget,imageMouse,imageCount,imageButton,leftX,rightY,docResize,scriptDebug,
mouseWheel = /Firefox/.test(navigator.userAgent)?"DOMMouseScroll":"mousewheel",
protocol = location.protocol,
doc = document,
docHeight = doc.documentElement.clientHeight-6,
docWidth = doc.documentElement.clientWidth-6,
parentElement = doc.getElementById("j_p_postlist"),
definedEvent = GM_getValue("definedEvent","click,click,1,0,1").split(","),
repairDefinedEvent = GM_getValue("repairDefinedEvent",false);
var imageEvent = {
init:function(event){ //主事件
log("图片创建:开始");
var e=event,eTarget=e.target;
if(e.button===0&&(eTarget.className==="BDE_Image"||eTarget.className==="j_user_sign")){
var imageSrc = eTarget.src.match(/([a-z0-9]+\.[a-zA-Z]{3,4})(?:\?v=tbs)?$/);
log("图片地址获取",function(){if(imageSrc)return "成功";else return "失败";},eTarget.src);
if(!imageSrc) return false;
var image = doc.createElement("img");
image.classList.add("Tie_enlargeImage");
image.src = protocol + "//imgsrc.baidu.com/forum/pic/item/" + imageSrc[1];
image.onload = function(){
log("图片创建:进行中");
target = this;
this.onload = null;
imageTarget = [this.width,this.height];
var ifHeight = imageTarget[1]>docHeight,ifX = 6,ifY = 6;
if(ifHeight&&imageTarget[0]<docWidth){
ifX = (docWidth-imageTarget[0])/2;
}
if(!ifHeight){
ifX = (docWidth-imageTarget[0])/2;ifY = (docHeight-imageTarget[1])/2;
}
imageTarget.push(ifX,ifY);
this.style.transform = "translate("+ifX+"px,"+ifY+"px)";
parentDIV.appendChild(this);
log("图片创建",function(){if(!doc.getElementById("Tid_enlargeImage_Debug"))target.id = "Tid_enlargeImage_Debug";if(doc.getElementById("Tid_enlargeImage_Debug"))return "成功";else return "失败";},imageTarget);
};
image = null;
}
},
StopPropagation:function(event){
if(event.button===0&&event.target.className==="BDE_Image"){
event.stopPropagation(); //阻止冒泡,阻止图片原事件
log("贴吧图片原事件阻止:已执行");
}
},
Down:function(event){ //image鼠标down事件
log("鼠标down事件:开始");
var e=event,eTarget=e.target;
if (e.button!==0)return false;
e.preventDefault();
e.stopPropagation();
if(target!==eTarget){ //记录当前图片数据,缓存
target = eTarget;
var reg = eTarget.style.transform.match(/[-0-9.]+/g);
imageTarget = [eTarget.width,eTarget.height,parseFloat(reg[0]),parseFloat(reg[1])]; //图片的宽高,当前位置的XY
}
imageMouse = [e.clientX,e.clientY]; //鼠标按下时的XY
imageCount = [imageTarget[2]-imageMouse[0],imageTarget[3]-imageMouse[1],6-imageTarget[0],6-imageTarget[1]]; //图片宽高的偏移量,图片左右边界预留量
imageButton = true;
doc.addEventListener("mousemove",imageEvent.Move);
doc.addEventListener("mouseup",imageEvent.Up);
log("鼠标down事件:结束");
},
Move:function(event){
log("鼠标move事件:开始");
var e=event;
imageButton = false;
leftX = e.clientX+imageCount[0];
rightY = e.clientY+imageCount[1];
log("鼠标move事件:进行中","",[leftX,rightY]);
if(leftX<imageCount[2]){ //左边界
target.style.transform = "translate("+imageCount[2]+"px,"+rightY+"px)";
return false;
}
if(leftX>docWidth){ //右边界
target.style.transform = "translate("+docWidth+"px,"+rightY+"px)";
return false;
}
if(rightY<imageCount[3]){ //上边界
target.style.transform = "translate("+leftX+"px,"+imageCount[3]+"px)";
return false;
}
if(rightY>docHeight){ //下边界
target.style.transform = "translate("+leftX+"px,"+docHeight+"px)";
return false;
}
target.style.transform = "translate("+leftX+"px,"+rightY+"px)";
log("鼠标move事件:结束","",target.style.transform);
},
Up:function(event){
log("鼠标up事件:开始",function(){if(!imageButton&&event.clientX-imageMouse[0]===0&&event.clientY-imageMouse[1]===0)return "关闭图片功能可能以损坏";else return "";});
if(repairDefinedEvent&&event.clientX-imageMouse[0]===0&&event.clientY-imageMouse[1]===0){ //尝试修复关闭图片功能
log("尝试修复关闭图片功能");
imageButton = true;
}
if(!imageButton){
imageTarget[2] = leftX;
imageTarget[3] = rightY;
leftX = null;
rightY = null;
}
imageMouse = null; //释放鼠标数据空间
imageCount = null;
doc.removeEventListener("mousemove",imageEvent.Move);
doc.removeEventListener("mouseup",imageEvent.Up);
log("鼠标up事件:结束","",imageButton);
},
Close:function(){
log("鼠标click事件:开始");
if(imageButton){
parentDIV.removeChild(target);
log("鼠标click事件:",function(){if(!doc.getElementById("Tid_enlargeImage_Debug"))return "成功";else return "失败";});
target = null;
imageTarget = null;
imageButton = null;
}
},
Wheel:function(event){
log("鼠标wheel事件:开始");
var e=event,eTarget=e.target;
e.preventDefault();
e.stopPropagation();
if(target!==eTarget){
target = eTarget;
var reg = eTarget.style.transform.match(/[-0-9.]+/g);
imageTarget = [eTarget.width,eTarget.height,parseFloat(reg[0]),parseFloat(reg[1])];
}
var wheelKey = definedEvent[3];
if(wheelKey!=="0"){
log("鼠标wheel缩放事件:开始","",wheelKey);
if((e.ctrlKey&&wheelKey==="1")||(e.altKey&&wheelKey==="2")||(e.shiftKey&&wheelKey==="3")){ //判断图片缩放的组合键
var eX = e.clientX,eY = e.clientY,
eTargetWidth = imageTarget[0],eTargetHeight = imageTarget[1],
ratioX = (eX-imageTarget[2])/eTargetWidth,ratioY = (eY-imageTarget[3])/eTargetHeight,
wheelRatio = eTargetWidth+(e.wheelDelta||-e.detail*40)*definedEvent[4];
imageTarget[0] = wheelRatio<150?150:wheelRatio;
imageTarget[1] = imageTarget[0]*eTargetHeight/eTargetWidth;
imageTarget[2] = eX-(imageTarget[0]*ratioX);
imageTarget[3] = eY-(imageTarget[1]*ratioY);
log("鼠标wheel缩放事件:进行中","",imageTarget);
eTarget.width = imageTarget[0];
eTarget.style.transform = "translate("+imageTarget[2]+"px,"+imageTarget[3]+"px)"; //基于鼠标位置的缩放
log("鼠标wheel缩放事件:结束","",eTarget.style.transform);
return false;
}
}
if(imageTarget[1]<docHeight){
log("鼠标wheel滚动事件:图片高度小于窗口高度");
return false;
}
var wheelY = imageTarget[3]+(-e.wheelDelta||e.detail*40)*definedEvent[2];
if(wheelY>0||wheelY<docHeight-imageTarget[1]){
wheelY = wheelY>0?6:docHeight-imageTarget[1];
}
imageTarget[3] = wheelY;
log("鼠标wheel滚动事件:进行中","",wheelY);
eTarget.style.transform = "translate("+imageTarget[2]+"px,"+wheelY+"px)";
log("鼠标wheel滚动事件:结束","",eTarget.style.transform);
}
};
//创建DIV父框架
var parentDIV = doc.createElement("div");
parentDIV.id = "Tie_enlargeImage_parentDIV";
doc.body.appendChild(parentDIV);
parentDIV = doc.getElementById("Tie_enlargeImage_parentDIV");
//事件委托
parentElement.addEventListener("click",imageEvent.StopPropagation,true);
parentElement.addEventListener(definedEvent[0],imageEvent.init,true);
parentDIV.addEventListener("mousedown",imageEvent.Down);
parentDIV.addEventListener(definedEvent[1],imageEvent.Close);
parentDIV.addEventListener(mouseWheel,imageEvent.Wheel);
//释放缓存
parentElement=null;
//自定义设置
var userEvent = {
init:function(){
this.create();
this.Event();
},
create:function(){
var definedDIV = doc.createElement("div"); //创建自定义DIV框架
definedDIV.id = "Tie_setValue_DIV";
definedDIV.innerHTML = "<div class='Tie_definedDIV'><div class='Tie_definedDIV_title'>自定义设置</div><div><div class='Tie_definedDIV_point'><div class='Tie_groupSubtitle'>请保证鼠标在图片上进行操作</div><div class='Tie_configItem'>默认支持鼠标左键拖拽图片</div><div class='Tie_configItem'>查看图片<select name='Tie_setValue'><option value='click'>单击</option><option value='dblclick'>双击</option></select></div><div class='Tie_configItem'>关闭图片<select name='Tie_setValue'><option value='click'>单击</option><option value='dblclick'>双击</option></select><br><label><input id='Tie_repairValue' type='checkbox'>尝试修复关闭图片功能</label></div><div class='Tie_configItem'>上移图片<select name='Tie_setValue'><option value='1'>滚轮向上</option><option value='-1'>滚轮向下</option></select></div><div class='Tie_configItem'>缩放图片<select name='Tie_setValue'><option value='0'>关闭</option><option value='1'>Ctrl</option><option value='2'>Alt</option><option value='3'>Shift</option></select>+<select name='Tie_setValue'><option value='1'>滚轮向上放大</option><option value='-1'>滚轮向下放大</option></select></div><div class='Tie_configItem'>调试脚本<label><input id='Tie_debugConfig' type='checkbox'><i class='Tie_debugConfig_icon'></i></label></div></div></div><div class='Tie_definedDIV_SaveBtn'><a id='Tie_setValue_a' class='Tie_SaveBtn_a' href='javascript:void(0);'><span>确定</span></a></div></div>";
doc.body.appendChild(definedDIV);
definedDIV = null;
},
Event:function(){
var definedDIV = doc.getElementById("Tie_setValue_DIV"),
repairValue = doc.getElementById("Tie_repairValue"),
debugConfig = doc.getElementById("Tie_debugConfig"),
parentElement = doc.getElementById("j_p_postlist"),
setValue = doc.getElementsByName("Tie_setValue"),
oldDefinedEvent = definedEvent.concat(); //备份旧设置
for(var i=0;i<5;i++){
setValue[i].value = oldDefinedEvent[i];
}
repairValue.checked = repairDefinedEvent;
debugConfig.checked = scriptDebug;
if(setValue[3].value==="0")setValue[4].style.visibility = "hidden";
setValue[3].onchange = function(){
setValue[4].style.visibility = this.value==="0"?"hidden":"visible";
};
doc.getElementById("Tie_setValue_a").onclick = function(){
for(var i=0;i<5;i++){
definedEvent[i] = setValue[i].value;
}
repairDefinedEvent = repairValue.checked;
scriptDebug = debugConfig.checked;
if(oldDefinedEvent[0]!==definedEvent[0]){
parentElement.removeEventListener(oldDefinedEvent[0],imageEvent.init,true);
parentElement.addEventListener(definedEvent[0],imageEvent.init,true);
}
if(oldDefinedEvent[1]!==definedEvent[1]){
parentDIV.removeEventListener(oldDefinedEvent[1],imageEvent.Close);
parentDIV.addEventListener(definedEvent[1],imageEvent.Close);
}
this.onclick = null;
setValue[3].onchange = null;
doc.body.removeChild(definedDIV);
GM_setValue("definedEvent",definedEvent.toString());
GM_setValue("repairDefinedEvent",repairDefinedEvent);
definedDIV = null;repairValue = null;debugConfig = null;parentElement = null;setValue = null;oldDefinedEvent = null;
};
}
};
if(!GM_getValue("definedEvent")){
userEvent.init();
}
GM_registerMenuCommand("自定义设置", function(){
if(!doc.getElementById("Tie_setValue_DIV"))
userEvent.init();
});
window.addEventListener("resize", function(){
if(typeof docResize!==undefined){
clearTimeout(docResize);
}
docResize = setTimeout(function(){
docHeight = doc.documentElement.clientHeight-6;
docWidth = doc.documentElement.clientWidth-6;
},334);
});
//脚本调试,日志
var log = function(text,types,data){
if(!scriptDebug)return false;
if(typeof types==="function"){
types = types();
}
if(data===undefined){
if(types===undefined){
console.log(text);
return false;
}
console.log(text,types);
return false;
}else{
console.log(text,types,"参数:"+data);
return false;
}
};