adjustColor2

convert colors to eye-friendly - webページの配色を目に優しく変更します (Flash対応)

当前为 2015-06-12 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name adjustColor2
  3. // @namespace http://chiebukuro.yahoo.co.jp/my/gbjyn273
  4. // @author Syakku
  5. // @description convert colors to eye-friendly - webページの配色を目に優しく変更します (Flash対応)
  6. // @include *
  7. // @version 1.2
  8. // @run-at document-start
  9. // ==/UserScript==
  10.  
  11. // ================≪ OPTION ≫================
  12.  
  13. // ----------------< white" & "black" color >----------------
  14. var FILTER_COLOR_W = "rgb(234, 229, 227)";
  15. var FILTER_COLOR_B = "rgb(41, 34, 29)";
  16. var INNER_COLOR_W = "rgb(211, 203, 198)";
  17. var INNER_COLOR_B = "rgb(41, 34, 29)"; // gb is disabled
  18. // OPTION : apply to Flash object
  19. var FLASH = true;
  20. // OPTION : skip <a> tag (link anchor)
  21. // OPTION : <a> タグ、つまりリンク文字列を処理から除外します
  22. // ex: [] or ["google.co.jp", "youtube", "&link=important"] or [*]
  23. var _A_SKIP_URL = ["*"];
  24. // ================≪ 初期化 ≫================
  25. var _win = document.defaultView;
  26. var fCw = rgbSplit(FILTER_COLOR_W);
  27. var fCb = rgbSplit(FILTER_COLOR_B);
  28. var iCw = rgbSplit(INNER_COLOR_W);
  29. var iCb = rgbSplit(INNER_COLOR_B);
  30. // ----------------< インナーがフィルターを超えていたら修正 >----------------
  31. for (var i=0; i<3; i++){
  32. if (iCw[i] > fCw[i]){iCw[i] = fCw[i];}
  33. if (iCb[i] < fCb[i]){iCb[i] = fCb[i];}
  34. }
  35. // ----------------< フィルタ関連の初期化 >----------------
  36. var fColor = createFilter(fCw, fCb);
  37. var filterR = fColor[0], filterG = fColor[1], filterB = fColor[2], filterA = fColor[3], filterAa = 1-filterA;
  38. // 色変換で使うので先に計算
  39. var filterRA = filterR * filterA, filterGA = filterG * filterA, filterBA = filterB * filterA;
  40. var _pr = (iCw[0] - iCb[0]) / 255, _pg = (iCw[1] - iCb[1]) / 255, _pb = (iCw[2] - iCb[2]) / 255;
  41. var _pr2 = iCb[0], _pg2 = iCb[1], _pb2 = iCb[2];
  42. // ----------------< 色変換の結果保持配列 >----------------
  43. var list = [];
  44. var lFg = [];
  45. var lCount = 0;
  46.  
  47.  
  48. // ----------------< 背景画像処理 >----------------
  49. var bgFilter = createBgFilter();
  50. var bgfCount = bgFilter.substring(0, 30);
  51. var bgfcLength = bgfCount.length;
  52. function createBgFilter(){
  53. var tw=[], tb=[];
  54. tw[0] = Math.floor((iCw[0] - filterRA) / filterAa);
  55. tw[1] = Math.floor((iCw[1] - filterGA) / filterAa);
  56. tw[2] = Math.floor((iCw[2] - filterBA) / filterAa);
  57. tb[0] = Math.floor((iCb[0] - filterRA) / filterAa);
  58. var bfColor = createFilter(tw, tb);
  59. var _rgba = bfColor[4];
  60. return("linear-gradient(" + _rgba + ',' + _rgba + "),");
  61. }
  62.  
  63. // ----------------< URLフィルタ >----------------
  64. var _skip = false;
  65. for (var i=0; i<_A_SKIP_URL.length; i++){
  66. if (location.href.indexOf(_A_SKIP_URL[i]) !== -1 || _A_SKIP_URL[i] === "*"){_skip = true;}
  67. }
  68. // ################################################ //
  69. // ################### メイン処理部 ################### //
  70. // ################################################ //
  71.  
  72.  
  73. // ================≪ 起動処理 ≫================
  74. loadFilter();
  75.  
  76. _win.addEventListener("DOMContentLoaded", afterTouch, false);
  77. if (FLASH === true){_win.addEventListener("DOMContentLoaded", flashMode, false);}
  78.  
  79. // ================≪ フィルタの適用 ≫================
  80. function loadFilter(_fast){
  81. var _filter = document.createElement("ac_filter");
  82. _filter.id = "adjustColor";
  83. _filter.style.backgroundColor = fColor[4];
  84. _filter.style.pointerEvents = "none";
  85. _filter.style.height = "100%";
  86. _filter.style.width = "100%";
  87. _filter.style.position = "fixed";
  88. _filter.style.zIndex = 9999;
  89.  
  90. var _nodes = document.getElementsByTagName("html")[0].childNodes;
  91. for (var i=0; i<_nodes.length; i++){
  92. var _node = _nodes[i];
  93. if (_node.tagName === "BODY"){
  94. var _style = _node.style;
  95. _style.position = "absolute";
  96. // absolute にすると中央揃えでなくなってしまう
  97. _style.left = 0;
  98. _style.right = 0;
  99. _style.top = 0;
  100. _style.bottom = 0;
  101. // unset なのはブラウザ標準スタイルシートでマージンが存在するため
  102. _style.margin = "unset auto";
  103. break;
  104. } else if (_node.tagName === "FRAMESET"){
  105. document.getElementsByTagName("html")[0].insertBefore(_filter, _node);
  106. return;
  107. }
  108. }
  109. document.getElementsByTagName("html")[0].appendChild(_filter);
  110. }
  111.  
  112.  
  113. // ================≪ 追加処理 ≫================
  114. function afterTouch(){
  115. var elm = document.getElementsByTagName("*");
  116. var elm_length = elm.length;
  117.  
  118. for (var i = 0; i < elm_length; i++) {
  119.  
  120. var tElm = elm[i];
  121. // <A>タグ
  122. if (tElm.tagName === "A" && _skip === true) {continue;}
  123. var style = _win.getComputedStyle(tElm, null);
  124. var fgColor = style.getPropertyValue("color");
  125. // ----------------< 背景 >----------------
  126. fg:{
  127. // 処理する必要のないカラーは省く
  128. for (var n=0; n<lCount; n++){
  129. if (fgColor === list[n]){break fg;}
  130. }
  131. // 既存のカラーは省エネ
  132. for (var n=0; n<lCount; n++){
  133. if (fgColor === lFg[n]){
  134. tElm.style.color = list[n];
  135. break fg;
  136. }
  137. }
  138.  
  139. var _tColorF = convColor(fgColor);
  140. lFg[lCount] = fgColor;
  141. list[lCount] = _tColorF;
  142. lCount++;
  143. tElm.style.color = list[n];
  144. }
  145. }
  146. }
  147.  
  148.  
  149. // ================ <背景色レンジ縮小 ≫================
  150. function convColor(_bg) {
  151.  
  152. var _col = rgbSplit(_bg);
  153. var _colR = _col[0] * _pr + _pr2*1;
  154. var _colG = _col[1] * _pg + _pg2*1;
  155. var _colB = _col[2] * _pb + _pb2*1;
  156. _colR = Math.floor((_colR - filterRA) / filterAa);
  157. _colG = Math.floor((_colG - filterGA) / filterAa);
  158. _colB = Math.floor((_colB - filterBA) / filterAa);
  159.  
  160. if (typeof _col[3] === "undefined") {
  161. return ("rgb(" + _colR + ", " + _colG + ", " + _colB + ")");
  162. }
  163. return ("rgb(" + _colR + ", " + _colG + ", " + _colB + ", " + _col[3] + ")"); // rgba
  164. }
  165.  
  166.  
  167. // ================≪ RGB値の分割 ≫================
  168. function rgbSplit(_col){
  169. if (_col.substring(0, 4) === "rgb("){_col = _col.slice(4, -1)}
  170. else {_col = _col.slice(5, -1)}
  171. var _ret = _col.split(", ");
  172. return (_ret);
  173. }
  174.  
  175.  
  176. // ================≪ 白・黒の範囲を与えてフィルタを作成 ≫================
  177. function createFilter(_w, _b){
  178. var br = _b[0], wr = _w[0], wg = _w[1], wb = _w[2];
  179. var tr = wr - br;
  180. var r = tr / (255 - tr) * br + br*1;
  181. var a = br/ r; // 中心値 r が気をつけないと 0 や 255 になって 0 除算になる
  182. if (isNaN(a) === true){a = (wr-255) / (r-255);}
  183.  
  184. var g = r - (wr - wg) / a;
  185. var b = r - (wr - wb) / a;
  186. // r, g, b, a, rgba の値を配列で返す
  187. return ([r, g, b, a, "rgba(" + Math.floor(r) + ", " + Math.floor(g) + ", " + Math.floor(b) + ", " + a + ")"]);
  188. }
  189.  
  190. // ================≪ フラッシュにもフィルタを適用 ≫================
  191. function flashMode(){
  192. for (var objs = document.getElementsByTagName("object"), i = 0, obj; obj = objs[i]; i++){
  193. if (obj.type === "application/x-shockwave-flash"){
  194. var skip = false;
  195. obj.style.display = "none";
  196.  
  197. for (var params = obj.getElementsByTagName("param"), j = 0, param; param = params[j]; j++){
  198. if (param.getAttribute("name") == "wmode"){
  199. skip = true;
  200. param.setAttribute("value", "transparent");
  201. // バックグラウンドのフラッシュはこうすると適用される
  202. _win.setTimeout(function(o){
  203. o.parentNode.insertBefore(o,o.nextSibling);
  204. o.style.display = "block";
  205. }, 100, obj);
  206. break;
  207. }
  208. }
  209. if(skip != true) {
  210. // paramが存在しないとき用(動作未確認)
  211. var param = document.createElement("param");
  212. param.setAttribute("name", "wmode");
  213. param.setAttribute("value", "transparent");
  214. obj.appendChild(param);
  215. obj.parentNode.insertBefore(obj,obj.nextSibling);
  216. }
  217. // バックグラウンドのフラッシュはこうすると適用される
  218. _win.setTimeout(function(o){
  219. o.parentNode.insertBefore(o,o.nextSibling);
  220. o.style.display = "block";
  221. }, 100, obj);
  222. }
  223. }
  224. // ----------------< embedタグ >----------------
  225. for (var embs = document.getElementsByTagName("embed"), i = 0, emb; emb = embs[i]; i++){
  226. emb.style.display = "none";
  227. emb.setAttribute("wmode", "transparent");
  228. // バックグラウンドのフラッシュはこうすると適用される
  229. setTimeout(function(o){
  230. o.parentNode.insertBefore(o,o.nextSibling);
  231. o.style.display = "block";
  232. }, 100, emb);
  233. }
  234. }