弹幕词云/弹幕图

bilibili弹幕词云

目前为 2021-08-25 提交的版本。查看 最新版本

// ==UserScript==
// @name         弹幕词云/弹幕图
// @namespace    http://tampermonkey.net/
// @version      2.3.1
// @description  bilibili弹幕词云
// @author       You
// @match        https://www.bilibili.com/bangumi/play/*
// @match        https://www.bilibili.com/video/*
// @grant        none
// @require      https://cdn.bootcdn.net/ajax/libs/wordcloud2.js/1.1.2/wordcloud2.min.js
// @require      https://cdn.bootcdn.net/ajax/libs/d3/7.0.0/d3.min.js
// ==/UserScript==

(function() {
    'use strict';
function geo(){
    console.log("开始")
  //  setInterval(modi,1000);
  initBase();
   init();
}
//======变量=======
var canv;
var btnTextE;
var baocun;//保存按钮
var baocun2;//保存按钮
var holder;//包裹词云
var canvP;//词云div
var title;
var hasCi=false;//词云是否显示
let s=[]//弹幕
let dmlang=[]//所有弹幕
let wds=[]//所有
let sai=[]//词频
let stageSai=[];
let dmBar;
let pao;
let fail=false;
let walkPao=false;
let tez=[0,1]//[最大值,最小值,中位数]
let count=350//最大词数
let reqParm=[0,1]
let liFac=0.5;//
let weiFac=0.5;//字体权重
let colorTable=['#9794DB','#8240BF','#6344C1','#4840BF','#444EC1','#4461C1','#5E90C9','#4BABC3','#66C7CC','#66CCBD','#53C69F','#BDD071','#C9965E','#C15444','#BF4640','#D13D3D','#FF533E']
let peiIdx=0;
let sepei=[//背景色,高频色,低频色,遮罩
  ['#2775b6',[255,255,255],[73,92,105],'//i0.hdslb.com/bfs/article/874074999995e6981d7602a7d5a770043a10b932.png@256w_256h.webp','景泰蓝'],
  ['#AC1F18',[28,13,26],[54,41,47],'//i0.hdslb.com/bfs/article/874074999995e6981d7602a7d5a770043a10b932.png@256w_256h.webp','对联红'],
  ['#621d34',[226,225,228],[97,113,114],'//i0.hdslb.com/bfs/article/874074999995e6981d7602a7d5a770043a10b932.png@256w_256h.webp','鹞冠紫'],
  ['#ed9db2',[51,20,30],[181,152,162],'//i0.hdslb.com/bfs/article/874074999995e6981d7602a7d5a770043a10b932.png@256w_256h.webp','豇豆红'],
  ['#1ba784',[173, 213, 162],[65, 174, 60],'//i0.hdslb.com/bfs/article/874074999995e6981d7602a7d5a770043a10b932.png@256w_256h.webp','竹绿'],
  ['#fed71a',[140, 194, 105],[140, 194, 105],'//i0.hdslb.com/bfs/article/874074999995e6981d7602a7d5a770043a10b932.png@256w_256h.webp','佛手黄'],
  ['#f26b1f',[249, 233, 205],[240, 156, 90],'//i0.hdslb.com/bfs/article/874074999995e6981d7602a7d5a770043a10b932.png@256w_256h.webp','金黄'],
  ['#500A16',[226,225,228],[97,113,114],'//i0.hdslb.com/bfs/article/d2bba9afdcd82302d8d387696e076da26050fb37.jpg@1320w_1760h.webp','浪'],
]//背景+文字颜色2
let sepeiBtn=[];
let styleSheet=` .blura{
  animation: 1s animatea 1 linear;
}
.blura:hover{
  animation: 2s animateb 1 linear;
}
@keyframes animatea{
0%{ text-shadow: 0 0 0 white; }
50%{
  color: rgba(238, 235, 235, 0.8);
  text-shadow: 0 0 30px rgb(216, 227, 243);
}
100%{ text-shadow: 0 0 40px white; }
}
@keyframes animateb{
  0%{ text-shadow: 0 0 0px rgba(255,255,255,0); }
  50%{
    color: rgba(255, 255, 255, 0.925);
    text-shadow: 0 0 10px rgb(184, 245, 242);
  }
  100%{ text-shadow: 0 0 0 white; }
}
@keyframes ac{
  0%{ color: rgba(33, 33, 33, 0.9); }
  50%{color: rgba(238, 235, 235, 0.9);}
  100%{ color: rgba(33, 33, 33, 0.9); }
}
@keyframes ad{
  0%{ color: rgba(33, 33, 33, 0.9); }
  50%{color: rgba(238, 235, 235, 0.9);}
  100%{ color: rgba(33, 33, 33, 0.9); }
}
.btnBg{
  position:relative;top:-17px;background: linear-gradient(45deg , #e5c0ff, skyblue);border-radius: 4px;filter: blur(15px);width: 100%;height: 100%;
}
.blr-btn{
  user-select:none;overflow:hidden;position:fixed;top:56px;z-index:999;left:10px;width: 54px;height: 26px;border-radius: 3px;font-size: 18px;padding: 5px;cursor: pointer;
  width:fit-content;
  width:-webkit-fit-content;
  width:-moz-fit-content;
  animation: 0.5s ad 1 linear;
}
.blr-btn:hover{
  animation: 0.5s ac 1 linear;
}
.fEl{
  width: 100%;
  height: 25px;
  padding: 5px 0px;
  color: cornsilk;
}
.bar-indicator{
  height: 5px;
  background-color: rgb(76 173 104);
  width: 80%;
}
.fEl:hover{
  background-color: rgba(96, 160, 243, 0.363);
  transition:1s;
  cursor: pointer;
}
.frequency{
  width: 10%;
  float: right;
  font-size: 14px;
  padding: 9px 5px 0 0;
  text-align: right;
  text-shadow: -2px -1px 8px #bdfa9d;
}
.danmu-word{
  padding: 5px;
  font-size: 12px;
  line-height: 15px;
}
.hid{
  opacity: 0;
  transition: 0.5s;
}
:root{
  --rds: 0px;
}
*{
  border-radius: var(--rds) !important;
}
*:after{
  border-radius: var(--rds) !important;
}
`
//======基础======
var mbox;
function initBase(){
  mbox=document.createElement("div");
  var m=[window.innerHeight/2-100,window.innerWidth/2-200]
  mbox.style="width: 400px;height: 200px;background-color: rgba(33,33,33,0.7);position: fixed;top:"+m[0]+"px;left:"+m[1]+"px;border-radius: 5px;z-index:999999;"
  mbox.hidden=true;
  document.body.append(mbox)
}
function msg(t){
    mbox.hidden=false;
    mbox.innerHTML="";
    let txt=document.createElement('span');
    txt.style="font-size:20px;color: white;position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);"
    if(t.length>23) t=t.substr(0,23)+"..."
    else if(t.length<6) txt.style.fontSize='50px'
    txt.innerText=t;
    mbox.append(txt)
    mbox.className="";
    var outTime=t.length/7*1000
    setTimeout(()=>{mbox.className='hid'},outTime)
    setTimeout(()=>{mbox.hidden=true},outTime+500)
}
//======函数======

function drag(obj){
  obj.onmousedown = function(e){
      // 鼠标点击物体那一刻相对于物体左侧边框的距离=点击时的位置相对于浏览器
      // 最左边的距离-物体左边框相对于浏览器最左边的距离,纵向同理
      var divX = e.clientX - this.offsetLeft;
      var divY = e.clientY - this.offsetTop;

      document.onmousemove = function(e){
          var disX = e.clientX - divX;
          var disY = e.clientY - divY;

          // 移动时重新得到物体的距离,解决拖动时出现晃动现象
          obj.style.top = disY + "px";
          obj.style.left = disX + "px";
          document.onmouseup = function(){    // 鼠标抬起时不再移动
              // 预防鼠标弹起来后还会循环(即预防鼠标放上去的时候还会移动)
              document.onmousedown = document.onmousemove = null;
          }
      }
  }
}
var init=()=>{
  var sty=document.createElement("style");
  sty.innerHTML=styleSheet
  document.head.append(sty)
  //按钮
  let cibtn=newBtn(document.body,ciw,10,54,'词云');
  btnTextE=cibtn.tx;
  let saveBtn=newBtn(document.body,()=>{
    saveDiv(holder)
  },10,100,'保存')
  let saveBtn2=newBtn(document.body,()=>{
    saveDiv(canvP)
  },10,140,'仅文字保存')

  sepei.forEach((v,i)=>{
    let themBtn=newBtn(document.body,()=>{
      peiIdx=i;doWordCloud();
    },10,240+i*50,v[4])
    // themBtn.bt.style.background='linear-gradient(45deg , #e5c0ff, '+v[0]+')'
    themBtn.bt.style.background=v[0]
    themBtn.bt.style.display='none'
    themBtn.tx.style.color='rgb('+v[1][0]+','+v[1][1]+','+v[1][2]+')'
    sepeiBtn[i]=themBtn.bt;
  })


  let dmBarBtn=newBtn(document.body,()=>{
    if(sai.length==0) msg('请先生成词云(>_<)')
    if(dmBar.hidden) {
      dmBar.hidden=false
      $(dmBar).fadeIn( 300 , 'linear')
    }
    else{
      dmBar.hidden=true;
      dmBar.style.display='none'
    }
  },60,54,'列表')

  let paopaoBtn=newBtn(document.body,()=>{
    if(!pao.hidden) {pao.hidden=true;return}
    pao.hidden=false
    bubble.update(sai)
  },110,54,'泡泡')

  baocun=saveBtn.bt
  baocun.style.display='none'
  baocun2=saveBtn2.bt
  baocun2.style.display='none'
  //词云画布
  canv=document.createElement("div");
  canvP=document.createElement("div");//背景
  canvP.append(canv);
  canv.style="height: 100%;width: 100%;"

  //渐变
  // canvP.style="opacity:0.96;border: 5px solid rgb(237 237 237 / 74%);height: 700px;width: 1200px;position:fixed;top:50px;left:60px;z-index:999999;background:linear-gradient(311deg, rgb(234 229 229), rgb(233 241 227), rgb(218 231 230));";
  //单色background-image: url(https://i0.hdslb.com/bfs/album/d16f34b89e59174bd066a27101bf6b9c92d16615.jpg);
  canvP.style="background-image: url(//i0.hdslb.com/bfs/article/874074999995e6981d7602a7d5a770043a10b932.png@256w_256h.webp);opacity:0.96;border: 5px solid rgb(237 237 237 / 74%);height: 700px;width: 1200px;background-color: rgb(236, 43, 36);";
  holder=document.createElement('div')
  holder.style="position:fixed;top:40px;left:115px;z-index:999;"
  holder.setAttribute("hidden",true);
  title=document.createElement("span")
  title.style="font-size:10px;color:rgb(225,235,215);position:absolute;z-index:10;background-color:#888"
  holder.append(canvP)
  holder.append(title)
  document.body.append(holder)
  drag(holder)

  //弹幕列表
  dmBar=document.createElement('div')
  dmBar.style='background-color:rgb(128 204 150 / 96%);position: absolute;z-index: 998;width: 320px;border: 4px solid #c1f8db38;'
  dmBar.style.display='none'
  dmBar.hidden=true
  drag(dmBar)
  //泡泡图
  pao=document.createElement('div')
  pao.style='position: fixed;z-index: 999;width: 700px;top:80px;left:115px;'
  pao.append(bubble.svg.node().parentNode)
  document.body.append(pao)
  pao.style.cursor="pointer"
  pao.hidden=true
  drag(pao)
}

var modi=()=>{
  var dms=$(".b-danmaku");
  for(var i=0;i<dms.length;i++){
      if(dms[i].innerHTML.indexOf("div")==-1){
          var s=dms[i].style.fontSize.replace("px","")
          var l=dms[i].innerHTML.length*s+"px"
          dms[i].innerHTML=` <div style="overflow: hidden;height: `+dms[i].style.fontSize+`;width: `+l+`">
          <div style="position: relative;top: -32px;">`+dms[i].innerHTML+`</div>
          <div style="width: 100%;
          height:  100%;
          background: linear-gradient(45deg , #e5c0ff, skyblue);
          border-radius: 4px;
          filter: blur(20px);
          position: relative;
          top: -90px;"></div>
      </div>`
      }
  }
}
//产生词云
async function ciw(){
  if(hasCi) {
    holder.setAttribute("hidden",true);
    $(baocun,baocun2).fadeOut( 1000 , 'linear' , ()=>{
    })
    $(baocun2).fadeOut( 1000 , 'linear' )
    $(sepeiBtn).fadeOut( 1000 , 'linear' )
    btnTextE.innerText='词云'
    hasCi=false;
    return;
  };
  console.log('生成词云');
  let pid=reqParm[0]
  loadParam();
  if(sai.length==0||pid!=reqParm[0]) analysi();
  else afterTask.a();
}
let afterTask={
  a:function(){
    // peiIdx=peiIdx==sepei.length-1?0:peiIdx+1 改为按钮切换
    holder.removeAttribute("hidden");
    setTimeout(()=>{btnTextE.innerText='^_^'},100)
    doWordCloud()
    hasCi=true;
    btnTextE.innerText='关闭'
    $(baocun).fadeIn( 1000 , 'linear')
    $(baocun2).fadeIn( 1000 , 'linear')
    $(sepeiBtn).fadeIn( 1000 , 'linear')
    pao.hidden=true;
  },
  b:function(){
    wds.forEach(e=>{
      if(e[1]>=1) {
        sai.push(e)
      }
      })
    wds=null
    sai.sort((a,b)=>b[1]-a[1]);//降序
    //计算weiFac
    if(sai.length>count) sai.splice(count)
    let siz=0;
    sai.forEach(e=>siz+=e[0].length*e[1]*e[1])
    let bgSize=canvP.style.height.replace("px","")*canvP.style.width.replace("px","")
    weiFac=Math.sqrt(bgSize/siz)

    tez[0]=sai[0][1]
    tez[1]=sai.slice(-1)[0][1]
    tez[2]=sai[parseInt(sai.length/2)][1]

    console.log(dmlang)
    console.log("大小中",tez)
    console.log("筛选结果:",sai)
    dmLiebiao()//
  }
}
let doWordCloud=()=>{
  backgroundImag()
  WordCloud([canv],
    {
     list: sai,
     color: colorw, //'random-light'
     backgroundColor: '',
     gridSize: 18,
     weightFactor: weiFac,//200/tez[0],//被除数为最大字号
    fontFamily: '楷体',
    rotateRatio: 0.5,
    classes: "blura",
    rotationSteps: 2
  } );
}
//上色
let colorw=(wd,weight)=>{
  //tez[0]红色 #ff0000
  //1=>蓝色 #0000ff
  // console.log(wd,weight,tez[0])
  let i=sai.findIndex(e=>e[0]==wd);
  let v=i/sai.length;

  // let v=parseInt(colorTable.length*i/sai.length)
  // return colorTable[v];
  let s=sepei[peiIdx][1]
  let e=sepei[peiIdx][2]
  let colo='rgb('
  for(let x in s){
    colo+=(parseInt(s[x]+v*(e[x]-s[x])))+','
  }
  return colo.substr(0,colo.lastIndexOf(','))+')'
}
//获取弹幕并分析
let analysi=()=>{
  //清空
  s=[];
  sai=[];
  reCalcFac()
  console.log("等待弹幕获取完成")
  btnTextE.innerText='>_<';
  pao.hidden=false;
  getOneSeg(1)
}
function getOneSeg(seg){
  let regex=/:.(.*?)[�@]/
  $.ajax({
       url:'https://api.bilibili.com/x/v2/dm/web/seg.so?type=1&oid='+reqParm[0]+'&pid='+reqParm[1]+'&segment_index='+seg,
       data:{},
            async:false,
            cache:false,
            ifModified :true,
      type:'GET',
      success:function(re, textStatus, xhr){ //成功回调函数
              if(xhr.status!=200) {
                console.log("失败点:",seg)
                fail=true
                afterTask.b();
                afterTask.a();
                return;
              }
              let ss=re.split('\n');
              ss.forEach(e=>{
                let dm=regex.exec(e);
                if(dm&&dm[1]){
                  s.push(dm[1]);
                  dmlang.push([dm[1],1])
                }
              })
              console.log(s);
              //分析进行
              let t1=new Date().getTime();
              cia()
              //清空s
              s=[]
              wds.sort((a,b)=>b[1]-a[1]);//降序
              stageSai[stageSai.length]=wds.slice()
              if(wds.length>count) stageSai[stageSai.length-1].splice(count)
              let ps=bubble.update(stageSai[stageSai.length-1])
              Promise.all(ps).then(data=>{
                console.log("完成",data)
                let t2=500-(new Date().getTime()-t1)
                if(t2>0) sleep(t2)
                if(seg<10)
                getOneSeg(seg+1)
              });
       },
      error:function (err){ //失败回调函数
            fail=true;
            console.log("失败点:",seg)
       console.log(err);
      }
      });
}
//分析
 function cia(){
  console.log('分析弹幕...')
  // let wds=[]
  s.forEach(e => {
    //去特殊符号
    // e=e.replace(/[\ |\~|\`|\!|\@|\#|\$|\%|\^|\&|\*|\(|\)|\-|\_|\+|\=|\||\\|\[|\]|\{|\}|\;|\:|\"|\'|\,|\<|\.|\>|\/|\?]/g,"");
    // ctin(wds,e)
    ctin(wds,e)
    //展示泡泡
  });

}
function dmFenxi(dm){
  let join=true
  let dmf=[dm,1]
  for(let i in wds){
    if(wds[i][0]==dm) {
      join=false;
      wds[i][1]+=1
    }else{
      jiaQuan(wds[i],dmf)
    }
  }
  if(join==true){
    wds.push(dmf);
  }
}
function jiaQuan(a,b){
  if(a[0].indexOf(b[0])>-1) {
    a[1]+=b[0].length/a[0].length
    b[1]+=b[0].length/a[0].length
  }else if(b[0].indexOf(a[0])>-1){
    b[1]+=a[0].length/b[0].length
    a[1]+=a[0].length/b[0].length
  }
}

function ctin(a,b){
  var h=true;
  for(let i in a){
    if(ditIn(a[i],b)){
      a[i][1]+=1;
      h=false;
      break;
    }
  }
  if(h){
    a.push([b,0])
  }
}
let ditIn=(A,b)=>{
  if(liFac==1){
    if(A[0].indexOf(b)<0&&b.indexOf(A[0])<0) return false;
  }else if(!xiangsi(A[0],b)) return false;
  // if(A[0].length>b.length&&b.length>1) A[0]=b;//选择少的
  if(b.length==2||b.length==4) A[0]=b;//选择2字4字
  return true;
}
let xiangsi=(a,b)=>{
  if(xiangsi0(a,b)||xiangsi0(b,a)) return true;
  return false;
}
let xiangsi0=(a,b)=>{
  let m=a.split('')
  let c=0;
  m.forEach(e=>{
    if(b.indexOf(e)>-1) c++;
  })
  if(c/m.length>=liFac) return true;
  return false;
}

let loadParam=()=>{
  reqParm= [window.cid,window.aid]
  if(reqParm[0]==undefined){
    let xx=document.querySelector("#eplist_module > div.list-wrapper.longlist > ul > li.ep-item.cursor.visited")
    if(!xx){xx=document.querySelector("#eplist_module > div.list-wrapper > ul > li.ep-item.cursor.visited")}
    let x=xx.__vue__.$options._parentVnode.componentOptions.propsData.epInfo;
    reqParm=[x.cid,x.aid]
  }
  console.log('找到参数:',reqParm)
}
//设置词云宽高和筛选因子
let reCalcFac=()=>{
  let m= 0
  try {
    m=parseInt(document.querySelector('.bilibili-player-video-info-danmaku-number').innerText);
  } catch (error) {
    m=parseInt(document.querySelector('.bpx-player-video-info-dm-number').innerText);
  }
  let titleEl=document.querySelector('#media_module > div > a')
  if(!titleEl) titleEl=document.querySelector('#viewbox_report > h1 > span')
  title.innerText="视频标题:"+titleEl.innerText+"   "+new Date()
  if(m<1000) {
    liFac=0.5
  }else{
    liFac=0.5+(m-1000)/10000;//上限10000条
    if(liFac>1) liFac=1;
  }
  let w=window.innerWidth-160;
  let h=window.innerHeight-70;
  canvP.style.width=w+'px'
  canvP.style.height=h+'px'
  pao.style.width=w+'px'
  pao.style.height=h+'px'
  holder.style.width=(10+w)+'px'
  holder.style.height=(10+h+17.6)+'px'
}
let dmLiebiao=()=>{
  dmBar.innerHTML=''//
  if(null==dmBar.parent){
    let p=document.querySelector('#app > div.v-wrap > div.r-con');
    if(null==p) p=document.querySelector('#app > div.plp-r');
    p.prepend(dmBar)
  }
  let h=360*Math.random();
  let b=360-h;
  sai.forEach(e=>{
    let fe=document.createElement('div');
    fe.className='fEl';
    let dw=document.createElement('span');
    dw.className='danmu-word';
    dw.innerHTML=e[0]
    if(e[0].length>21){
      dw.innerText=e[0].substr(0,21)+"..."
    }
    let f=document.createElement('div');
    f.className="frequency";
    f.innerText=parseInt(e[1])
    let bi=document.createElement('div');
    bi.className='bar-indicator'
    bi.style='width:'+(Math.round(80*e[1]/tez[0]))+'%'
    bi.style.backgroundColor=colorTool.hsla(b,70,60,0.7);
    fe.append(dw)
    fe.append(f)
    fe.append(bi)
    fe.style.backgroundColor=colorTool.hsla(h,e[1]/sai[0][1]*100,60,0.75)
    dmBar.append(fe)
  })
}

let backgroundImag=()=>{
  console.log("主题更改:",sepei[peiIdx][4])
  // msg("更改主题:"+sepei[peiIdx][4])
  canvP.style.backgroundImage='url("'+sepei[peiIdx][3]+'")'
  canvP.style.backgroundColor=sepei[peiIdx][0]
  // $.ajax({
  //   url:'http://zhongguose.com/img/texture.png',
  //   type:'get',
  //   success:(data)=>{
  //     console.log(daata)
  //     var img=new Blob([data],{type:"png"})
  //     var url=URL.createObjectURL(img);
  //     canvP.style.backgroundImage='url("'+url+'")'
  //   }
  // })
}
let bubble={
  width:600,
  height:600,
  pack:data => d3.pack()
  .size([bubble.width - 2,bubble.height - 2])
  .padding(0)
  (d3.hierarchy({ children: data })
  .sum(d => d[1])),
  svg:d3.create("svg").attr("style","background-color: #f0f8ff85;")
  .attr("viewBox", [0, 0, 600, 600])
  .attr("text-anchor", "middle").append("g"),
  update:sj=>{
    let promises=[]
    let color= d3.scaleOrdinal(sj.map(d => d[0]), d3.schemeCategory10);
    let fontSize= d3.scaleLinear()
    .domain([d3.min(sj,d=>d[1]), d3.max(sj,d=>d[1])])
    .range([5, 40])
    let root =bubble.pack(sj);
    bubble.leaf = bubble.svg.selectAll("g")
            .data(root.leaves(),d=>d[0])
            .join(
                enter => {
                    let lf=enter.append("g")
                    lf.append("circle").attr("r",0)
                    lf.append("text")
                    return lf
                },
                update => update,
                exit => exit.remove()
            );
        promises[0]= bubble.leaf.selectAll("circle")
        .data(d=>d,d=>d)
        .attr("id",1)
        .transition()
        .attr("r", d => d.r)
        .attr("fill", d => color(d.data[0]))
        .attr("fill-opacity", 0)
        .transition()
        .attr("fill-opacity", 0.7).end()
        ;
        bubble.leaf.selectAll("text")
        .attr("clip-path", 1)
        .selectAll("tspan")
        .data(d => d,x=>x[0])
        .join("tspan")
        .attr("x", 0)
        .attr("y", (d, i, nodes) => `${i - nodes.length / 2 + 0.8}em`)
        .attr("font-size",d=>fontSize(d.data[1]))
        .attr("color","#5f5")
        .text(d => d.data[0].split(/(?=[A-Z][a-z])|\s+/g));
        bubble.leaf.attr("transform", d => `translate(${d.x + 1},${d.y + 1})`)
        let width=bubble.width,height=bubble.height;
        let currentTransform = [width / 2, height / 2, height];
        function transition() {
          if(!walkPao)  return
          const d = root.children[Math.floor(Math.random() *root.children.length)];
          const i = d3.interpolateZoom(currentTransform, [d.x,d.y+d.r, 4*d.r ]);

          bubble.svg.transition()
              .delay(1000)
              .duration(i.duration)
              .attrTween("transform", () => t => transform(currentTransform = i(t)))
              .on("end", transition);
        }

        function transform([x, y, r]) {
          return `
            translate(${width / 2}, ${height / 2})
            scale(${height / r})
            translate(${-x}, ${-y})
          `;
        }
        bubble.svg.call(transition)
        return promises;
    }
}
function cibubble(){
        // let width = 600
        // let height = 600
        // let pack = data => d3.pack()
        //     .size([width - 2, height - 2])
        //     .padding(0)
        //     (d3.hierarchy({ children: data })
        //         .sum(d => d.value))
        // let color = d3.scaleOrdinal(data.map(d => d.name), d3.schemeCategory10)
        // const svg = d3.create("svg")
        //     .attr("viewBox", [0, 0, width, height])
        //     .attr("font-size", 10)
        //     .attr("font-family", "sans-serif")
        //     .attr("text-anchor", "middle");
        // let leaf
}
//保存div内容为png
function saveDiv(div){
  //1.将div转成svg
  var divContent = div.innerHTML;
  let w=div.offsetWidth;
  let h=div.offsetHeight
  if(w==0||h==0){
    w=div.firstElementChild.offsetWidth
    h=div.firstElementChild.offsetHeight
  }
  var data = "data:image/svg+xml," +
  "<svg xmlns='http://www.w3.org/2000/svg' width='"+w+"' height='"+h+"'>" +
  "<foreignObject width='100%' height='100%'>" +
  "<div xmlns='http://www.w3.org/1999/xhtml' style='font-size:16px;font-family:Helvetica'>" +
  divContent +
  "</div>" +
  "</foreignObject>" +
  "</svg>";
  var img = new Image();
  img.src = data;
  // document.body.appendChild(img);
  //2.svg转成canvas
  var canvas = document.createElement('canvas');  //准备空画布

  img.onload=()=>{
    var dpr =window.devicePixelRatio;
    canvas.width = img.width;
    canvas.height =img.height;
    canvas.style.width =dpr*w + "px"
    canvas.style.height =dpr*h + "px"
    var context = canvas.getContext('2d');  //取得画布的2d绘图上下文
    context.drawImage(img, 0, 0);
    var a = document.createElement('a');
    a.href = canvas.toDataURL('image/png');  //将画布内的信息导出为png图片数据
    let titleEl=document.querySelector('#media_module > div > a')
    if(!titleEl) titleEl=document.querySelector('#viewbox_report > h1 > span')
    a.download =titleEl.innerText+(new Date()).getTime()+".png";  //设定下载名称
    a.click()
  }
}
let colorTool={
  hsla:function(h,s,l,a){
    return "hsla("+h+","+s+"%,"+l+"%,"+a+")";
  }
}
//生产按钮
function newBtn(p,f,left,top,word){
  var cibtn= document.createElement("div");
  var cibtnBg= document.createElement("div");
  cibtnBg.className='btnBg'
  let TextE=document.createElement('span')
  TextE.innerText=word
  cibtn.append(TextE)
  cibtn.className='blr-btn'
  cibtn.append(cibtnBg);
  cibtn.style.left=left+'px';
  cibtn.style.top=top+'px';
  // moveAble(cibtn,f)//setTimeOut还是卡
  cibtn.onclick=f;
  p.append(cibtn)
  return {bt:cibtn,bg:cibtnBg,tx:TextE}
}
function sleep(numberMillis) {
	var now = new Date();
	var exitTime = now.getTime() + numberMillis;
	while (true) {
		now = new Date();
		if (now.getTime() > exitTime)
		return;
	}
}

var ban,unattach = !0;function mcDrag(b,c,k){b.onmousedown=function(m){if(!k||m.target==b){var e=c.style.transition;c.style.transition="unset";var d=m.clientX-c.offsetLeft,a=m.clientY-c.offsetTop;document.onmousemove=function(f){var n=f.clientX-d;c.style.top=f.clientY-a+"px";c.style.left=n+"px";document.onmouseup=function(){document.onmousedown=document.onmousemove=null;c.style.transition=e}}}}}
function tuoyi(b,c,k,m,e,d){var a=(new Date).getTime();b.onmousedown=function(f){var n=f.clientX,q=f.clientY;a=(new Date).getTime();var r=m();e&&e();document.onmousemove=function(h){var p=h.clientX-n,t=h.clientY-q;200<(new Date).getTime()-a&&c(p,t,r);document.onmouseup=function(){document.onmousemove=null;200>(new Date).getTime()-a&&k(h);d&&d()}}}}function g(b){return document.createElement(b)}
function bujie(b){b.classList.add("mc-bujie");setTimeout(function(){b.classList.remove("mc-bujie")},1E3)}function shantishi(b,c,k){b.classList.add(c);setTimeout(function(){b.classList.remove(c)},k)}var LX={wuxian:1,prop:2,bl:3,wb:4};
function MiCan(b,c,k,m){unattach && attachStyle();ban=document.createElement("div");ban.classList.add("mc-b");ban.style.top="200px";ban.style.left="200px";document.body.append(ban);var e=g("div"),d=g("div");d.style.width="100%";ban.append(e);ban.append(d);ban.ti=d;e.classList.add("mc-tou");e.innerText=m;b.forEach(function(a){a[2]==LX.prop?sx(a[0],a[1],k,c,a[3],a[4],a[5]):a[2]==LX.wuxian?wxsx(a[0],a[1],k,c,a[3],a[4]):a[2]==LX.wb?wz(a[0],a[1],k,c):a[2]==LX.bl&&sf(a[0],a[1],k,c)});mcDrag(e,ban,1);return ban}
function sx(b,c,k,m,e,d,a){var f=g("div");f.classList.add("mc-sx");ban.ti.append(f);var n=g("div");n.classList.add("mc-title","mc-dh");n.innerText=b;f.append(n);b=g("div");b.style="float: left;width: 170px;height: 30px;";f.append(b);var q=g("div");q.classList.add("mc-sx-op");b.append(q);var r=g("div");r.classList.add("mc-sx-bar");q.append(r);var h=g("input");h.classList.add("mc-sx-input","mc-input","mc-dh");h.value=k(c);b.append(h);var p=g("div");p.classList.add("mc-slider","mc-dh");b.append(p);var t=
function(){var l=h.value;l>d?(l=d,bujie(n)):l<e&&(l=e,bujie(n));a&&(l=parseInt(l));h.value=l;r.style.width=q.clientWidth*(l-e)/(d-e)+"px";m(c,l)};tuoyi(p,function(l,v,u){h.value=e+(u+l)/q.clientWidth*(d-e);t()},function(){p.style.display="none";setTimeout(function(){h.focus()},1)},function(){return r.clientWidth},function(){p.classList.add("mc-faguang")},function(){p.classList.remove("mc-faguang")});t();h.onblur=function(){p.style.display="block";t()};return f}
function wxsx(b,c,k,m,e,d){function a(l){d&&(l=l.parseInt);h.value=l;m(c,l)}var f=g("div");f.classList.add("mc-sx");ban.ti.append(f);var n=g("div");n.classList.add("mc-title","mc-dh");n.innerText=b;f.append(n);b=g("div");b.style="float: left;width: 170px;height: 30px;";f.append(b);var q=g("div");q.classList.add("mc-sx-op");b.append(q);var r=g("div");r.classList.add("mc-jiantou","mc-z","mc-dh");r.innerText="<";q.append(r);var h=g("input");h.classList.add("mc-sx-input","mc-input","mc-dh");h.style.width=
"100px";h.style.top="0px";h.value=k(c);q.append(h);var p=g("div");p.classList.add("mc-jiantou","mc-y","mc-dh");p.innerText=">";q.append(p);var t=g("div");t.classList.add("mc-huakuai-zj","mc-dh");b.append(t);h.onblur=function(){t.style.display="block";a(h.value)};r.onclick=function(){a(h.value-e);shantishi(this,"mc-huodong",500)};p.onclick=function(){a(new Number(h.value)+e);shantishi(this,"mc-huodong",500)};tuoyi(t,function(l,v,u){a(u- -l*e);0>l?(r.classList.add("mc-huodong"),p.classList.remove("mc-huodong")):
(p.classList.add("mc-huodong"),r.classList.remove("mc-huodong"))},function(){t.style.display="none";setTimeout(function(){h.focus()},1)},function(){return h.value},function(){q.classList.add("mc-faguang")},function(){q.classList.remove("mc-faguang");r.classList.remove("mc-huodong");p.classList.remove("mc-huodong")})}
function wz(b,c,k,m){function e(n){m(c,n);f.value=n}var d=g("div");ban.ti.append(d);d.classList.add("mc-sx");var a=g("div");a.classList.add("mc-title","mc-dh");a.innerText=b;d.append(a);b=g("div");b.style.float="left";b.style.height="100%";d.append(b);d=g("div");d.innerText="\ud83d\udd8a";d.classList.add("mc-tubiao","mc-dh");b.append(d);var f=g("input");f.classList.add("mc-input","mc-dh","mc-bj-danhuang");f.style.width="260px";f.style.textAlign="left";f.value=k(c);b.append(f);f.onblur=function(){m(c,
f.value)};d.onclick=function(n){wbsr.hd=e;wbsr.main||initWbsr();xianshi(wbsr.main);wbsr.in.value=f.value}}
function sf(b,c,k,m){var e=g("div");e.classList.add("mc-sx");ban.ti.append(e);var d=g("div");d.classList.add("mc-title","mc-dh");d.innerText=b;e.append(d);var a=g("div");a.style="float: left";a.classList.add("mc-title","mc-dh","mc-blue");a.innerText="\u662f";k(c)||(a.innerText="\u5426",a.classList.add("mc-red"),a.classList.remove("mc-blue"));e.append(a);a.onclick=function(){k(c)?(a.classList.add("mc-red"),a.classList.remove("mc-blue"),a.innerText="\u5426",m(c,!1)):(a.classList.remove("mc-red"),a.classList.add("mc-blue"),
a.innerText="\u662f",m(c,!0))}}var wbsr={};function xiaoshi(b){b.classList.add("mc-touming");setTimeout(function(){b.classList.add("mc-yincang")},500)}function xianshi(b){b.classList.remove("mc-yincang");b.classList.remove("mc-touming")}
function initWbsr(){wbsr.main=g("div");wbsr.main.classList.add("mc-tanchu","mc-dh","mc-yincang","mc-touming");document.body.append(wbsr.main);wbsr.in=g("textarea");wbsr.in.classList.add("mc-wenben");wbsr.main.append(wbsr.in);wbsr.btp=g("div");wbsr.main.append(wbsr.btp);wbsr.quxiao=g("div");wbsr.quxiao.innerText="\u53d6\u6d88";wbsr.quxiao.classList.add("mc-aniu","mc-red");wbsr.quxiao.style.float="left";wbsr.btp.append(wbsr.quxiao);wbsr.queren=g("div");wbsr.queren.innerText="\u786e\u8ba4";wbsr.queren.classList.add("mc-aniu",
"mc-blue");wbsr.queren.style.float="right";wbsr.btp.append(wbsr.queren);wbsr.quxiao.onclick=function(){xiaoshi(wbsr.main)};wbsr.queren.onclick=function(){wbsr.hd(wbsr.in.value);xiaoshi(wbsr.main)};mcDrag(wbsr.main,wbsr.main,1)};
function attachStyle(){var a=g("style");document.head.append(a);a.innerText="\n    .mc-sx{margin:5px;height:30px;float:left}.mc-tou{width:100%;background-color:rgb(4 4 45);height:25px;text-align:center;line-height:25px;color:cornsilk;font-size:15px}.mc-input{height:24px;color:cornsilk;background-color:inherit;display:block;background:transparent;border:none;padding:3px 10px;text-align:center;font-size:16px}.mc-bj-danhuang{background-color:rgb(68 56 115)}.mc-sx-input{width:150px;float:left;position:relative;top:-30px}.mc-input:focus{border:0px;outline:none;background:rgba(42,165,104,0.425)}.mc-sx-bar{margin: unset;background-color:rgb(163,85,241);width:30px;height:100%}.mc-b{position:fixed;width:800px;background-color:#0a043adb;margin:0;box-shadow:0px 0px 9px 2px#3c35357a;transition:0.5s}.mc-title{background-color:rgb(58 55 110);float:left;line-height:30px;font-size:18px;padding:0px 10px;color:#857cc2}.mc-sx-op{background-color:rgb(86 71 146);height:30px;width:170px}.mc-slider{position:relative;top:-30px;width:170px;height:30px;user-select:none}.mc-huakuai-zj{position:relative;top:-30px;left:25px;width:120px;height:30px;user-select:none}.mc-huakuai-zj:hover{cursor:e-resize}.mc-dh{transition:0.5s linear}.mc-slider:hover{cursor:e-resize}.mc-faguang{box-shadow:0px 0px 8px 3px#ffffffd6}.mc-bujie{background-color:red}.mc-jiantou{background-color:rgb(128,83,173);width:25px;height:100%;font-size:30px;color:#d1c1e0;line-height:26px;cursor:pointer;user-select:none}.mc-z{float:left}.mc-y{float:right}.mc-huodong{background-color:rgb(219,165,245);color:cornsilk}.mc-wenben{border:0;background-color:rgba(233,233,233,0.98);width:355px;height:100px;padding:10px;resize:both;font-size:15px;color:rgb(66,66,64)}.mc-wenben:focus{border:none;outline:none}.mc-tubiao{float:left;height:100%;width:30px;background-color:rgb(89,82,147);color:cornsilk;font-size:18px;line-height:30px;text-align:center;transition:0.5s}.mc-tubiao:hover{cursor:pointer;background-color:rgb(156,127,238)}.mc-aniu{height:30px;line-height:30px;font-size:16px;transition:.4s linear;cursor:pointer;padding:3px 10px;margin:5px;color:cornsilk;user-select:none}.mc-red{cursor:pointer;background-color:rgb(224,68,128)}.mc-blue{cursor:pointer;background-color:rgb(35,245,193)}.mc-red:hover{background-color:rgb(255,0,98)}.mc-blue:hover{background-color:rgb(0,102,255)}.mc-tanchu{position:fixed;background-color:rgba(233,230,218,0.801);top:100px;left:200px;z-index:99}.mc-yincang{display:none}.mc-touming{opacity:0}\n    "};

geo();
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址