Greasy Fork

Greasy Fork is available in English.

動畫瘋 - 截圖工具

在 動畫瘋 加入 截圖 的功能

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         動畫瘋 - 截圖工具
// @namespace    hbl917070
// @version      0.3
// @description  在 動畫瘋 加入 截圖 的功能
// @author       hbl917070(深海異音)
// @match        https://ani.gamer.com.tw/animeVideo.php?sn=*
// @grant        none
// ==/UserScript==



/**
 * 最後修改日期:
 * 2020/05/09
 *
 * 說明:
 * 在 動畫瘋 加入 截圖 的功能
 *
 * 作者小屋:
 * https://home.gamer.com.tw/homeindex.php?owner=hbl917070
 *
 */

/**
 *
 * 版本說明
 *
 * 2020/05/09:修復BUG
 * 2019/09/08:修復某些圖片附檔名錯誤的BUG
 *
 */

(function () {


	//要插入的html

	var s_html = `
  <div class="ct_div">

  <style>
      /*最外層的框*/
      .ct_div {
          background-color: #FFF;
          padding: 5px;
          padding-left: 11px;
      }

      /*「截圖」按鈕*/
      .but_ct {
          margin-top: 10px;
          padding: 3px 10px;
          border: 1px solid #00B4D8;
          color: #00B4D8;
          display: inline-block;
          text-align: center;
          line-height: 27px;
          font-size: 1.3em;
          margin-right: 10px;
      }

      .but_ct:hover {
          background-color: #00B4D8;
          border: 1px solid #00B4D8;
          color: #FFF;
          display: inline-block;

      }

      /*放每一個截圖的區域*/
      #ct_output {
          max-height: 500px;
          overflow: auto;
          margin-top: 10px;
      }

      /*每一個截圖項目*/
      .ct_item {
          margin-bottom: 10px;
          margin-right: 10px;
          border: 1px solid #d9d9d9;
          float: left;
          padding: 5px;
          white-space: nowrap;
      }

      .ct_img {
          max-width: 195px;
          max-height: 150px;
      }

      /*影片時間*/
      .ct_time {
          float: left;
          margin-top: 5px;
          font-size: 18px;
      }

      /*下載圖片*/
      .ct_download {
          float: right;
          display: block;
          width: 20px;
          height: 20px;
          background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pg0KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE2LjAuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPg0KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4PSIwcHgiIHk9IjBweCINCgkgd2lkdGg9IjQzMy41cHgiIGhlaWdodD0iNDMzLjVweCIgdmlld0JveD0iMCAwIDQzMy41IDQzMy41IiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA0MzMuNSA0MzMuNTsiIHhtbDpzcGFjZT0icHJlc2VydmUiDQoJPg0KPGc+DQoJPGcgaWQ9ImZpbGUtZG93bmxvYWQiPg0KCQk8cGF0aCBkPSJNMzk1LjI1LDE1M2gtMTAyVjBoLTE1M3YxNTNoLTEwMmwxNzguNSwxNzguNUwzOTUuMjUsMTUzeiBNMzguMjUsMzgyLjV2NTFoMzU3di01MUgzOC4yNXoiLz4NCgk8L2c+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8L3N2Zz4NCg==);
          background-size: 90% 90%;
          background-position: center center;
          background-repeat: no-repeat;
          opacity: 0.2;
          margin-top: 3px;
      }

      .ct_download:hover {
          opacity: 1;
      }

      /*刪除圖片*/
      .ct_delete {
          float: right;
          display: block;
          width: 20px;
          height: 20px;
          background-image: url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjQyN3B0IiB2aWV3Qm94PSItNDAgMCA0MjcgNDI3LjAwMTMxIiB3aWR0aD0iNDI3cHQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTIzMi4zOTg0MzggMTU0LjcwMzEyNWMtNS41MjM0MzggMC0xMCA0LjQ3NjU2My0xMCAxMHYxODljMCA1LjUxOTUzMSA0LjQ3NjU2MiAxMCAxMCAxMCA1LjUyMzQzNyAwIDEwLTQuNDgwNDY5IDEwLTEwdi0xODljMC01LjUyMzQzNy00LjQ3NjU2My0xMC0xMC0xMHptMCAwIi8+PHBhdGggZD0ibTExNC4zOTg0MzggMTU0LjcwMzEyNWMtNS41MjM0MzggMC0xMCA0LjQ3NjU2My0xMCAxMHYxODljMCA1LjUxOTUzMSA0LjQ3NjU2MiAxMCAxMCAxMCA1LjUyMzQzNyAwIDEwLTQuNDgwNDY5IDEwLTEwdi0xODljMC01LjUyMzQzNy00LjQ3NjU2My0xMC0xMC0xMHptMCAwIi8+PHBhdGggZD0ibTI4LjM5ODQzOCAxMjcuMTIxMDk0djI0Ni4zNzg5MDZjMCAxNC41NjI1IDUuMzM5ODQzIDI4LjIzODI4MSAxNC42Njc5NjggMzguMDUwNzgxIDkuMjg1MTU2IDkuODM5ODQ0IDIyLjIwNzAzMiAxNS40MjU3ODEgMzUuNzMwNDY5IDE1LjQ0OTIxOWgxODkuMjAzMTI1YzEzLjUyNzM0NC0uMDIzNDM4IDI2LjQ0OTIxOS01LjYwOTM3NSAzNS43MzA0NjktMTUuNDQ5MjE5IDkuMzI4MTI1LTkuODEyNSAxNC42Njc5NjktMjMuNDg4MjgxIDE0LjY2Nzk2OS0zOC4wNTA3ODF2LTI0Ni4zNzg5MDZjMTguNTQyOTY4LTQuOTIxODc1IDMwLjU1ODU5My0yMi44MzU5MzggMjguMDc4MTI0LTQxLjg2MzI4Mi0yLjQ4NDM3NC0xOS4wMjM0MzctMTguNjkxNDA2LTMzLjI1MzkwNi0zNy44Nzg5MDYtMzMuMjU3ODEyaC01MS4xOTkyMTh2LTEyLjVjLjA1ODU5My0xMC41MTE3MTktNC4wOTc2NTctMjAuNjA1NDY5LTExLjUzOTA2My0yOC4wMzEyNS03LjQ0MTQwNi03LjQyMTg3NS0xNy41NTA3ODEtMTEuNTU0Njg3NS0yOC4wNjI1LTExLjQ2ODc1aC04OC43OTY4NzVjLTEwLjUxMTcxOS0uMDg1OTM3NS0yMC42MjEwOTQgNC4wNDY4NzUtMjguMDYyNSAxMS40Njg3NS03LjQ0MTQwNiA3LjQyNTc4MS0xMS41OTc2NTYgMTcuNTE5NTMxLTExLjUzOTA2MiAyOC4wMzEyNXYxMi41aC01MS4xOTkyMTljLTE5LjE4NzUuMDAzOTA2LTM1LjM5NDUzMSAxNC4yMzQzNzUtMzcuODc4OTA3IDMzLjI1NzgxMi0yLjQ4MDQ2OCAxOS4wMjczNDQgOS41MzUxNTcgMzYuOTQxNDA3IDI4LjA3ODEyNiA0MS44NjMyODJ6bTIzOS42MDE1NjIgMjc5Ljg3ODkwNmgtMTg5LjIwMzEyNWMtMTcuMDk3NjU2IDAtMzAuMzk4NDM3LTE0LjY4NzUtMzAuMzk4NDM3LTMzLjV2LTI0NS41aDI1MHYyNDUuNWMwIDE4LjgxMjUtMTMuMzAwNzgyIDMzLjUtMzAuMzk4NDM4IDMzLjV6bS0xNTguNjAxNTYyLTM2Ny41Yy0uMDY2NDA3LTUuMjA3MDMxIDEuOTgwNDY4LTEwLjIxODc1IDUuNjc1NzgxLTEzLjg5NDUzMSAzLjY5MTQwNi0zLjY3NTc4MSA4LjcxNDg0My01LjY5NTMxMyAxMy45MjU3ODEtNS42MDU0NjloODguNzk2ODc1YzUuMjEwOTM3LS4wODk4NDQgMTAuMjM0Mzc1IDEuOTI5Njg4IDEzLjkyNTc4MSA1LjYwNTQ2OSAzLjY5NTMxMyAzLjY3MTg3NSA1Ljc0MjE4OCA4LjY4NzUgNS42NzU3ODIgMTMuODk0NTMxdjEyLjVoLTEyOHptLTcxLjE5OTIxOSAzMi41aDI3MC4zOTg0MzdjOS45NDE0MDYgMCAxOCA4LjA1ODU5NCAxOCAxOHMtOC4wNTg1OTQgMTgtMTggMThoLTI3MC4zOTg0MzdjLTkuOTQxNDA3IDAtMTgtOC4wNTg1OTQtMTgtMThzOC4wNTg1OTMtMTggMTgtMTh6bTAgMCIvPjxwYXRoIGQ9Im0xNzMuMzk4NDM4IDE1NC43MDMxMjVjLTUuNTIzNDM4IDAtMTAgNC40NzY1NjMtMTAgMTB2MTg5YzAgNS41MTk1MzEgNC40NzY1NjIgMTAgMTAgMTAgNS41MjM0MzcgMCAxMC00LjQ4MDQ2OSAxMC0xMHYtMTg5YzAtNS41MjM0MzctNC40NzY1NjMtMTAtMTAtMTB6bTAgMCIvPjwvc3ZnPg==);
          background-size: 90% 90%;
          background-position: center center;
          background-repeat: no-repeat;
          opacity: 0.2;
          margin-top: 3px;
          margin-right: 20px;
      }

      .ct_delete:hover {
          opacity: 1;
      }

      /*開啟圖片*/
      .ct_open {
          float: right;
          display: block;
          width: 20px;
          height: 20px;
          background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pg0KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE5LjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPg0KPHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJDYXBhXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgNDUxIDQ1MSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNDUxIDQ1MTsiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPGc+DQoJPHBhdGggZD0iTTQ0Ny4wNSw0MjhsLTEwOS42LTEwOS42YzI5LjQtMzMuOCw0Ny4yLTc3LjksNDcuMi0xMjYuMUMzODQuNjUsODYuMiwyOTguMzUsMCwxOTIuMzUsMEM4Ni4yNSwwLDAuMDUsODYuMywwLjA1LDE5Mi4zDQoJCXM4Ni4zLDE5Mi4zLDE5Mi4zLDE5Mi4zYzQ4LjIsMCw5Mi4zLTE3LjgsMTI2LjEtNDcuMkw0MjguMDUsNDQ3YzIuNiwyLjYsNi4xLDQsOS41LDRzNi45LTEuMyw5LjUtNA0KCQlDNDUyLjI1LDQ0MS44LDQ1Mi4yNSw0MzMuMiw0NDcuMDUsNDI4eiBNMjYuOTUsMTkyLjNjMC05MS4yLDc0LjItMTY1LjMsMTY1LjMtMTY1LjNjOTEuMiwwLDE2NS4zLDc0LjIsMTY1LjMsMTY1LjMNCgkJcy03NC4xLDE2NS40LTE2NS4zLDE2NS40QzEwMS4xNSwzNTcuNywyNi45NSwyODMuNSwyNi45NSwxOTIuM3oiLz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjwvc3ZnPg0K);
          background-size: 90% 90%;
          background-position: center center;
          background-repeat: no-repeat;
          opacity: 0.2;
          margin-top: 3px;
          margin-right: 20px;
      }

      .ct_open:hover {
          opacity: 1;
      }
  </style>


  <div class="but_ct" onclick="add_ct()">截圖</div>
  <span style="font-size:14px; color:rgb(100, 100, 100)">(截圖快速鍵 「F8」</span>


  <div id="ct_output"></div>

  <div id="temp_ct_item" style="display:none;">
      <div class="ct_item">

          <img class="ct_img" src="{{ct_img}}">
          <div>
              <div class="ct_time">{{ct_time}}</div>
              <a class="ct_download" download="{{ct_name}}" href="{{ct_img}}"></a>
              <a class="ct_open" href="{{ct_img}}" target="_blank"></a>
              <div class="ct_delete" onclick="ct_delete('{{nub}}')"></div>
          </div>

      </div>
  </div>
</div>


`;

	var dom_div = document.createElement('div');
	dom_div.innerHTML = s_html;

	//目前截圖的編號(用於刪除圖片)
	window.ct_nub = 1;

	//把截圖的按鈕,插入到標題上方
	var dom_player = document.getElementsByClassName('anime-title')[0];
	dom_player.parentNode.insertBefore(dom_div, dom_player);

	//繪製圖片用的 canvas
	var cc = document.createElement('canvas');
	document.body.append(cc);

	//截圖快速鍵
	document.body.addEventListener("keydown", function (e) {
		if (e.keyCode == 119) { //F8
			add_ct();
		}
	});


	/**
	 * 影片截圖
	 */
	function add_ct() {

		//取得影片目前的畫面
		var video = document.getElementById('ani_video_html5_api');
		cc.width = video.videoWidth;
		cc.height = video.videoHeight;
		cc.setAttribute('style', 'width:0px; height:0px;');
		cc.getContext('2d').drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
		let base64 = cc.toDataURL("image/jpeg", 0.95);

		let imgsrc = URL.createObjectURL(dataURItoBlob(base64));// Blob url
		let imgtime = document.querySelector('.vjs-current-time .vjs-current-time-display').innerHTML;//目前時間

		let s_tit = document.querySelector('.anime_name h1').innerHTML;
		s_tit = s_tit.replace(/[/]/g, ' ').replace(/[\\]/g, ' ').replace(/[:]/g, ':').replace(/[*]/g, ' ')
			.replace(/["]/g, ' ').replace(/[?]/g, ' ').replace(/[<]/g, ' ').replace(/[>]/g, ' ').replace(/[|]/g, ' ')
			.replace(/[\t]/g, ' ').replace(/[\n]/g, ' ').replace(/[\r]/g, ' ');//避免windows不支援的檔名
		let s_time = imgtime.replace(/[:]/g, ':');
		let imgname = s_tit + ' ' + s_time + '.jpg';//圖片檔名


		let dom_ct_item = document.createElement('div');
		dom_ct_item.setAttribute('class', 'ct_item ' + 'ct_nub_' + window.ct_nub);
		let shtml = `
                  <img class="ct_img" src="{{ct_img}}">
                  <div>
                      <div class="ct_time">{{ct_time}}</div>
                      <a class="ct_download" download="{{ct_name}}" href="{{ct_img}}"></a>
                      <a class="ct_open" href="{{ct_img}}" target="_blank"></a>
                      <div class="ct_delete" onclick="ct_delete('{{nub}}')"></div>
                  </div>
                  `;
		shtml = shtml.replace(/{{ct_img}}/g, imgsrc)
			.replace(/{{ct_time}}/g, imgtime)
			.replace(/{{ct_name}}/g, imgname)
			.replace(/{{nub}}/g, window.ct_nub);

		dom_ct_item.innerHTML = shtml;
		document.getElementById('ct_output').append(dom_ct_item);

		window.ct_nub += 1;
	}

	/**
	 * 刪除圖片
	 * @param nub
	 */
	function ct_delete(nub) {
		let child = document.querySelector('.ct_nub_' + nub);
		child.parentNode.removeChild(child);
	}


	/**
	 * Blob object 轉 Blob url
	 * @param dataURI
	 */
	function dataURItoBlob(dataURI) {
		// convert base64/URLEncoded data component to raw binary data held in a string
		var byteString;
		if (dataURI.split(',')[0].indexOf('base64') >= 0)
			byteString = atob(dataURI.split(',')[1]);
		else
			byteString = unescape(dataURI.split(',')[1]);

		// separate out the mime component
		var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

		// write the bytes of the string to a typed array
		var ia = new Uint8Array(byteString.length);
		for (var i = 0; i < byteString.length; i++) {
			ia[i] = byteString.charCodeAt(i);
		}

		return new Blob([ia], { type: mimeString });
	}

	window.add_ct = add_ct;
	window.ct_delete = ct_delete;
	window.dataURItoBlob = dataURItoBlob;




})();