イラストの頭をなでるといいねを押してくれます。
// ==UserScript==
// @name NADENADE gesture
// @namespace http://tampermonkey.net/
// @version 2023-12-30
// @description イラストの頭をなでるといいねを押してくれます。
// @author koragen
// @match https://twitter.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=twitter.com
// @grant none
// @license MIT
// ==/UserScript==
(()=>{
class ComboManager{
constructor(COMBO_ARRAY_,onSucceedsCombo_,TIME_DIFER_ = 2000,COOLDOWN_ = 600,debugMode=false){
this.DEBUGMODE = debugMode;
this.COMBO_ARRAY = COMBO_ARRAY_;
this.COMBO_LENGH = COMBO_ARRAY_.length;
this.TIME_DIFER = TIME_DIFER_;
this.COOLDOWN = COOLDOWN_;
this.comboProgress = 0;
this.comboStartedTime = -Infinity;
this.LastTriggerdTime = -Infinity;
this.onSucceedsCombo = onSucceedsCombo_;
this.timeOutId=0;
}
reset(){
let date=new Date();
let currentTime = date.getTime();
this.comboProgress = 0;
this.comboStartedTime = currentTime;
}
_continue(){
clearTimeout(this.timeOutId);
this.timeOutId = setTimeout(()=>{
this.reset()
},1000)
}
onEvent(ID,event){
this._continue();
let date=new Date();
let currentTime = date.getTime();
let status = false;
if(this.DEBUGMODE)console.log({"ID":ID,"prog":this.comboProgress})
if(this.COMBO_ARRAY[this.comboProgress] == ID){
this.comboProgress++;
let d = currentTime - this.comboStartedTime;
let d2 = currentTime - this.LastTriggerdTime;
if(this.comboProgress == this.COMBO_LENGH){
if((d<this.TIME_DIFER)&&(d2>this.COOLDOWN)){
status = true;
this.onSucceedsCombo(event);
}
this.LastTriggerdTime = currentTime;
this.reset();
}
}else{
this.reset();
}
return status;
}
}
class GestureManager{
constructor(){
this.BufferLen=100;
this.currentAcceraration ={x:0,y:0};
this.currentAcceraration_={x:0,y:0};
this.currentMousePos ={x:0,y:0};
this.currentMousePos_={x:0,y:0};
this.currentATheta = 0;
this.currentATheta_= 0;
this.currentF = 0;
this.currentF_= 0;
this.currentArrowID = -1;
this.currentArrowID_= -1;
this.comboManagers = [];
}
AddComboManager(comboManager){
this.comboManagers.push(comboManager);
}
onComboEvent(arrowID,event){
for(let cm of this.comboManagers){
let reult = cm.onEvent(arrowID,event);
}
}
// ベクトルの長さを計算する関数
vectorLength(vector) {
return Math.sqrt(vector.x * vector.x + vector.y * vector.y);
}
// 正規化されたベクトルを返す関数
normalizeVector(vector) {
var length = this.vectorLength(vector);
return {x: vector.x / length, y: vector.y / length};
}
isVaildForce(F){
return (1<F&&F<15);
}
convTheta2ArrowID(theta){
let N=4
theta += (Math.PI*2)/(N*2)
let f = Math.floor((theta/(Math.PI*2))*N)
return f%N
}
tick(mx,my,event){
this.currentAcceraration_ = this.currentAcceraration
this.currentAcceraration = {}
this.currentMousePos_ = this.currentMousePos;
this.currentMousePos = {};
this.currentMousePos.x=mx;
this.currentMousePos.y=my;
this.currentAcceraration.x = this.currentMousePos_.x-this.currentMousePos.x;
this.currentAcceraration.y = this.currentMousePos_.y-this.currentMousePos.y;
this.currentF_ = this.currentF*0.2;
this.currentF = this.vectorLength(this.currentAcceraration)*0.2;
this.currentATheta_ = this.currentATheta;
this.currentATheta = Math.atan2(this.currentAcceraration.x,this.currentAcceraration.y)+Math.PI;
this.currentArrowID = this.convTheta2ArrowID(this.currentATheta);
window.mf = Math.max(window.mf,this.currentF)
if(this.isVaildForce(this.currentF)&&this.currentArrowID_!=this.currentArrowID){
this.currentArrowID_ = this.currentArrowID;
this.onComboEvent(this.currentArrowID,event);
}
}
}
window.onload = function(){
function GetArticleFromTargetElm(elm){
if(elm.tagName=="ARTICLE")return elm;
if(elm.parentElement)return GetArticleFromTargetElm(elm.parentElement);
return null;
}
function GetMainFromTargetElm(elm){
if(elm.tagName=="MAIN")return elm;
if(elm.parentElement)return GetMainFromTargetElm(elm.parentElement);
return null;
}
function GetDialogFromTargetElm(elm){
if(elm.getAttribute("role")=="dialog")return elm;
if(elm.parentElement)return GetDialogFromTargetElm(elm.parentElement);
return null;
}
let gm = new GestureManager();
gm.AddComboManager(new ComboManager([3,1,3,1],onSucceedsCombo_= (event)=>{//NADENADE IINE
let likeElms = document.querySelectorAll('[data-testid="like"]');
if(likeElms.length==1){
likeElms[0].click();
return;
}
let article = GetArticleFromTargetElm(event.target);
if(article){
let t = article.querySelector('[data-testid="like"]');
if(t)t.click();
return;
}
let main = GetMainFromTargetElm(event.target);
if(main){
let t = main.querySelector('[data-testid="like"]');
if(t)t.click();
return;
}
let dialog = GetDialogFromTargetElm(event.target);
if(dialog){
let t = dialog.querySelectorAll('[data-testid="unlike"],[data-testid="like"]')[0];
if(!t)return;
if(t.getAttribute("data-testid")=="like")t.click();
return;
}
console.log(event.target)
},2000,0,false));
gm.AddComboManager(new ComboManager([2,0,2,0],(event)=>{//閉じる,戻る
let elm = document.querySelector('[aria-label="閉じる"],[aria-label="戻る"]');
if(elm)elm.click();
}));
gm.AddComboManager(new ComboManager([0,3],(event)=>{
let elm = document.querySelector('[aria-label="次のスライド"]');
if(elm)elm.click();
}));
gm.AddComboManager(new ComboManager([0,1],(event)=>{
let elm = document.querySelector('[aria-label="前のスライド"]');
if(elm)elm.click();
}));
let fc=0;
document.body.addEventListener("mousemove", function(e){
var mX = e.pageX; //X座標
var mY = e.pageY; //Y座標
(fc%8==0)?0:gm.tick(mX,mY,e);
fc++;
});
}
})()
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址