各種の描画設定を自動保存

「Draw The Line ⭐」は、「アンダーライン」「マーカー線」「取り消し線」を自在に書き込めるツールです。 各種の装飾線の指定は HTMLに直接書き込まれるので、スマホでも表示されます。

 

(注)スマホで正確な描画位置を期待するには、インラインでフォント種を指定する事が最善の策と思われます。 以下の記事を参照ください。

 

    「Auto Style Attach ⭐」ver. 0.5 

 

 

このツールは実際は5種のモードで書き込みを行います。 各モードに「線幅」「開始位置」「線色」等の共通の設定があります。 しかし、アンダーラインとマーカー線の「線幅」は全く異なり、線描画の「開始位置」は単線・2重線で異なる場合が多く、ブログスキンのフォント種の違いで、適切な描画位置が異なります。 このため、モードごとに、全く独立した値の設定が必要です。

 

これまで「メイリオ 16px」を標準とした設定値を初期設定とした仕様でしたが、他のフォント種の場合や、独自設定を使う場合などは、ツールを起動する度に設定する必要があり、これは実用的とは言えない状態でした。

 

この使い勝手を改善するため、各種の設定をローカルストレージに自動登録する様にしました。 登録は以下の設定で、モードごとに独立した値が記録されます。

 

アンダーライン            
 task1  単線   線幅px  開始位置    線色  MS
 task2  2重線  線幅px  開始位置    線色  MS
マーカー線            
 task3  単線  線幅em  開始位置  (透過度)   線色  MS
取り消し線            
 task4  単線  線幅px  開始位置    線色  
 task5  2重線  線幅px  開始位置    線色  

 

「task」は書込みモードです。「透過度」は登録せず「線色」のアルファ値として登録されます。

 

これらの登録は、設定の変更時にリアルタイムで保存されます。 ツールのOFFや、ブラウザを閉じても、ツールを起動すると前回の設定が再現します。 登録データの初期値は「メイリオ 16px」を標準とした値にしていますが、一旦ユーザーが設定を変更すると、初期設定は更新され、ユーザーが設定したものに置換えられます。

 

 

 

カラー値の判定コードを更新 

前ページのカラー値判定コードを導入しました。 表面上は判り難いのですが、線色の「カラー設定枠」と「透過度」の動作が柔軟になっています。 また実装に際して、「不適正」なカラー値は登録されない様にしました。

 

 

 

 「Draw The Line」ver. 0.5

このツールは、Chrome / 新Edge / Firefox の「Tampermonkey」上で動作します。

現在のバージョンは実使用が可能です。 今後は、ファイル保存などの補足機能を追加して行きます。

 

各ブラウザの「Tampermonkey」の「新規スクリプト」の編集画面で、最初から登録されているテンプレートを削除して完全に空白にした上で、以下のコードをコピー&ペーストして「保存」してください。

 

〔コピー方法〕 軽量シンプルなツール「PreBox Button   」を使うと

  コード枠内を「Ctrl+左Click」➔「Copy code 」を「左Click」

  の操作で、掲載コードのコピーが可能になります。

 

 

〔 Draw The Line 〕ver. 0.5

 

// ==UserScript==
// @name         Draw The Line ⭐
// @namespace  http://tampermonkey.net/
// @version      0.5
// @description  各種の装飾線を記入するツール
// @author       Ameba Blog User
// @match        https://blog.ameba.jp/ucs/entry/srventry*
// @exclude      https://blog.ameba.jp/ucs/entry/srventrylist.do*
// @grant         none
// ==/UserScript==


let retry=0;
let interval=setInterval(wait_target, 100);
function wait_target(){
    retry++;
    if(retry>10){ // リトライ制限 10回 1sec
        clearInterval(interval); }
    let target=document.getElementById('cke_1_contents'); // 監視 target
    if(target){
        clearInterval(interval);
        main(); }}


function main(){
    let editor_iframe;
    let iframe_doc;
    let selection;
    let range;
    let task=0; // アンダーライン・マーカー線・消し線・終了
    let add_padd; //「MS Pゴシック」のために padding-bottom追加フラグ

    let read_json;
    let setting; // 入力枠の設定とユーザー設定値登録

    let ua=0; // Chromeの場合のフラグ
    let agent=window.navigator.userAgent.toLowerCase();
    if(agent.indexOf('firefox') > -1){ ua=1; } // Firefoxの場合のフラグ


    read_json=localStorage.getItem('Draw_Line'); // ローカルストレージ 保存名
    setting=JSON.parse(read_json);
    if(setting==null){
        setting=[['DrawTheLine','0','0','0'],['1','1.23','#333','0'],['1','1.23','#333','0'],
                 ['0.6','0.7','#ccc','0'],['1','0.66','#333','0'],['1','0.54','#333','0']]; }
    let write_json=JSON.stringify(setting);
    localStorage.setItem('Draw_Line', write_json); // ローカルストレージ 保存


    let target=document.getElementById('cke_1_contents'); // 監視 target
    let monitor=new MutationObserver(catch_key);
    monitor.observe(target, {childList: true}); // ショートカット待受け開始

    catch_key();



    function catch_key(){
        if(document.querySelector('.cke_wysiwyg_frame') !=null){ //「通常表示」から実行開始
            editor_iframe=document.querySelector('.cke_wysiwyg_frame');
            iframe_doc=editor_iframe.contentWindow.document;
            selection=iframe_doc.getSelection();

            iframe_doc.addEventListener('keydown', check_key);
            document.addEventListener('keydown', check_key);

            function check_key(event){
                let gate=-1;
                if(event.ctrlKey==true){
                    if(event.keyCode==114){
                        event.preventDefault(); gate=1; }
                    if(gate==1){
                        event.stopImmediatePropagation();
                        do_task(); }}}

            function do_task(){
                if(task==0){
                    task=1;
                    panel_disp();
                    set_panel();
                    draw_line(); }
                else if(task==1 || task==2){
                    task=3;
                    set_panel();
                    draw_line(); }
                else if(task==3){
                    task=4;
                    set_panel();
                    draw_line(); }
                else if(task==4 || task==5){
                    task=0;
                    panel_remove(); }}
        }} // catch_key()



    function draw_line(){
        let insert_node;
        let style_text;

        show_color();
        pick_color();

        let l_type=document.querySelector('#l_type');
        let single=document.querySelector('#single');
        let double=document.querySelector('#double');
        let pxem=document.querySelector('#pxem');
        let l_width=document.querySelector('#l_width');
        let l_base=document.querySelector('#l_base');
        let l_trance=document.querySelector('#l_trance');
        let l_color=document.querySelector('#l_color');
        let ms=document.querySelector('#ms');

        single.checked=true;


        double.onclick=function(){
            double.checked=true;
            if(task==1){
                task=2;
                l_width.disabled=true;
                l_width.value=1; // 固定値
                pxem.classList.remove('wpx');
                pxem.classList.add('wpxd');
                l_base.value=setting[2][1];
                l_color.value=setting[2][2];
                add_padd=setting[2][3];
                if(add_padd==1){
                    ms.style.boxShadow='inset 0 -5px 0 0 red'; }
                else{
                    ms.style.boxShadow='none'; }}
            if(task==4){
                task=5;
                l_width.disabled=false;
                l_width.value=setting[5][0];
                l_base.value=setting[5][1];
                l_color.value=setting[5][2]; }
            show_color(); }


        single.onclick=function(){
            single.checked=true;
            if(task==2){
                task=1;
                l_width.disabled=false;
                pxem.classList.remove('wpxd');
                pxem.classList.add('wpx');
                l_width.value=setting[1][0];
                l_base.value=setting[1][1];
                l_color.value=setting[1][2];
                add_padd=setting[1][3];
                if(add_padd==1){
                    ms.style.boxShadow='inset 0 -5px 0 0 red'; }
                else{
                    ms.style.boxShadow='none'; }}
            if(task==5){
                task=4;
                l_width.disabled=false;
                l_width.value=setting[4][0];
                l_base.value=setting[4][1];
                l_color.value=setting[4][2]; }
            show_color();}


        l_width.addEventListener('input', function(event){
            event.preventDefault();
            setting[task][0]=l_width.value;
            let write_json=JSON.stringify(setting);
            localStorage.setItem('Draw_Line', write_json); }); // ローカルストレージ 保存


        l_base.addEventListener('input', function(event){
            event.preventDefault();
            setting[task][1]=l_base.value;
            let write_json=JSON.stringify(setting);
            localStorage.setItem('Draw_Line', write_json); }); // ローカルストレージ 保存


        l_trance.addEventListener('input', function(event){
            event.preventDefault();
            if(!test_color(l_color.value) && l_color.value.length==9){ // 不適合な #付き9桁コードの場合
                if(test_color(l_color.value.slice(0, -2))){ // アルファ―値のみ不適合なら修正
                    l_color.value=l_color.value.slice(0, -2); }}
            if(!test_color(l_color.value) && l_color.value.length==8){ // 不適合な #付き8桁コードの場合
                if(test_color(l_color.value.slice(0, -1))){ // アルファ―値のみ不適合なら修正
                    l_color.value=l_color.value.slice(0, -1); }}

            if((test_color(l_color.value))){
                trance();
                l_color.style.boxShadow='inset -20px 0 ' + l_color.value; }
            else{
                l_trance.value=1; } // 変換不能なコード, カラー名などは「1」を変更できない

            setting[task][2]=l_color.value;
            let write_json=JSON.stringify(setting);
            localStorage.setItem('Draw_Line', write_json); }); // ローカルストレージ 保存


        if(add_padd==1){
            ms.style.boxShadow='inset 0 -5px 0 0 red'; }
        else{
            ms.style.boxShadow='none'; }

        ms.onclick=function(){
            if(add_padd==0){
                add_padd=1;
                ms.style.boxShadow='inset 0 -5px 0 0 red'; }
            else{
                add_padd=0;
                ms.style.boxShadow='none'; }

            setting[task][3]=add_padd;
            let write_json=JSON.stringify(setting);
            localStorage.setItem('Draw_Line', write_json); } // ローカルストレージ 保存


        l_type.onclick=function(){
            range=selection.getRangeAt(0);
            get_param();
            insert_node=document.createElement('span');
            if(add_padd==1 && task!=4 && task!=5 ){
                insert_node.style.paddingBottom='.4em'; }
            insert_node.style.background=style_text;

            try{
                range.surroundContents(insert_node); }
            catch(e){;}
            range.collapse(); }


        function get_param(){
            let l_w=l_width.value;
            let l_b= l_base.value;
            let l_c=l_color.value;

            if(task==1){
                style_text=
                    'linear-gradient(transparent '+ l_b +'em, '+
                    l_c +' 0, '+
                    l_c +' calc('+ l_b +'em + '+ l_w +'px), transparent 0)'; }
            if(task==2){
                style_text=
                    'linear-gradient('+
                    'transparent '+ l_b +'em, '+
                    l_c +' 0, '+ l_c +' calc('+ l_b +'em + 1px), '+
                    'transparent 0, transparent calc('+ l_b +'em + 2px), '+
                    l_c +' 0, '+ l_c +' calc('+ l_b +'em + 3px), '+
                    'transparent 0)'; }
            if(task==3){
                style_text=
                    'linear-gradient(transparent '+ l_b +'em, '+
                    l_c +' 0, '+
                    l_c +' calc('+ l_b +'em + '+ l_w +'em), transparent 0)'; }
            if(task==4){
                style_text=
                    'linear-gradient(transparent '+ l_b +'em, '+
                    l_c +' 0, '+
                    l_c +' calc('+ l_b +'em + '+ l_w +'px), transparent 0)'; }
            if(task==5){
                style_text=
                    'linear-gradient('+
                    'transparent '+ l_b +'em, '+
                    l_c +' 0, '+ l_c +' calc('+ l_b +'em + '+ l_w +'px), '+
                    'transparent 0, transparent calc('+ l_b +'em + '+ l_w +'px + 3px), '+
                    l_c +' 0, '+ l_c +' calc('+ l_b +'em + '+ 2*l_w +'px + 3px), '+
                    'transparent 0)'; }}
    } // draw_line()



    function set_panel(){
        let l_type=document.querySelector('#l_type');
        let type_1=document.querySelector('#type_1');
        let type_2=document.querySelector('#type_2');
        let single=document.querySelector('#single');
        let double=document.querySelector('#double');
        let pxem=document.querySelector('#pxem');
        let l_width=document.querySelector('#l_width');
        let l_base=document.querySelector('#l_base');
        let l_trance=document.querySelector('#l_trance');
        let l_color=document.querySelector('#l_color');
        let ms=document.querySelector('#ms');

        if(task==1){
            l_type.value="アンダーライン";
            type_1.style.display='inline-block';
            type_2.style.display='none';

            l_width.disabled=false;
            l_width.value=setting[1][0];
            l_base.value=setting[1][1];
            l_color.value=setting[1][2];
            add_padd=setting[1][3];

            l_width.setAttribute('min', '1');
            l_width.setAttribute('max', '50');
            l_width.setAttribute('step', '1');
            l_base.setAttribute('min', '0.9');
            l_base.setAttribute('max', '1.5');
            l_base.setAttribute('step', '0.01'); }

        else if(task==3){
            l_type.value="マーカー線";
            type_1.style.display='none';
            type_2.style.display='inline-block';
            l_width.classList.add('m');
            pxem.classList.remove('wpx');
            pxem.classList.add('wem');

            l_width.disabled=false;
            l_width.value=setting[3][0];
            l_base.value=setting[3][1];
            l_color.value=setting[3][2];
            add_padd=setting[3][3];
            l_trance.value='1'; // 初期値

            l_width.setAttribute('min', '0.1');
            l_width.setAttribute('max', '1.5');
            l_width.setAttribute('step', '0.1');
            l_base.setAttribute('min', '0');
            l_base.setAttribute('max', '1.3');
            l_base.setAttribute('step', '0.1');
            l_trance.setAttribute('min', '0.1');
            l_trance.setAttribute('max', '1');
            l_trance.setAttribute('step', '0.1'); }

        else if(task==4){
            l_type.value="取り消し線";
            type_1.style.display='inline-block';
            type_2.style.display='none';
            l_width.classList.remove('m');
            pxem.classList.remove('wem');
            pxem.classList.add('wpx');

            l_width.disabled=false;
            l_width.value=setting[4][0];
            l_base.value=setting[4][1];
            l_color.value=setting[4][2];

            l_width.setAttribute('min', '1');
            l_width.setAttribute('max', '20');
            l_width.setAttribute('step', '1');
            l_base.setAttribute('min', '0');
            l_base.setAttribute('max', '1');
            l_base.setAttribute('step', '0.01');
            add_padd=0; // 固定値
            ms.style.display='none'; }} // set_panel()



    function panel_disp(){
        let panel=document.createElement('div');
        panel.setAttribute('id', 'l_panel');

        panel.innerHTML=
            '<input id="l_type" type="submit">'+
            '<div id="type_wrap">'+
            '<div id="type_1">'+
            '<input id="single" type="radio" name="s_d"><span class="l_label">単線</span>'+
            '<input id="double" type="radio" name="s_d"><span class="l_label">2重線</span>'+
            '</div>'+
            '<span class="l_label label_w">線幅</span>'+
            '<div id="pxem" class="wpx"><input id="l_width" type="number"></div>'+
            '<span class="l_label">開始位置</span>'+
            '<div class="wem"><input id="l_base" type="number"></div>'+
            '<div id="type_2">'+
            '<span class="l_label">透過度</span>'+
            '<div class="wtr"><input id="l_trance" type="number"></div>'+
            '</div>'+
            '</div>'+
            '<span class="l_label">線色</span>'+
            '<input id="l_color" type="text" autocomplete="off">'+
            '<input id="ms" type="submit" value="MS">'+
            '<div id="test"></div>';

        let css=
            '#l_panel { position: fixed; top: 15px; left: calc(50% - 490px); width: 784px; '+
            'padding: 6px 0 6px 15px; font-size: 14px; border: 1px solid #ccc; '+
            'border-radius: 4px; background: #eff5f6; z-index: 10; }'+
            '#type_wrap { display: inline-block; text-align: right; width: 355px; }'+
            '#type_1 { display: inline-block; } #type_2 { display: none; }'+
            '#l_panel input { position: relative; margin-right: 10px; padding-top: 2px; }'+
            '#l_panel input:hover { z-index: 1; }'+
            '#l_panel input[type="radio"] { margin: 0 2px 0 8px; vertical-align: -2px; box-shadow: none; }'+
            '.l_label { margin: 0 4px 0 0; } .label_w { margin: 0 4px 0 10px; }'+
            '#l_type { width: 110px; margin-right: 4px !important; }'+
            '.wpx, .wpxd, .wem, .wtr { position: relative; display: inline-block; }'+
            '.wpx::after { content: "px"; position: absolute; right: 15px; top: 5px; background: #fff; }'+
            '.wpxd::after { content: "px"; position: absolute; right: 15px; top: 5px; }'+
            '.wem::after { content: "em"; position: absolute; right: 15px; top: 5px; background: #fff; }'+
            '#l_width { width: 38px; text-align: center; padding: 2px 4px 0 0; }'+
            '#l_width[disabled]:hover { z-index: 0; }'+
            '#l_width.m { width: 45px; text-align: left; padding: 2px 4px 0 5px; }'+
            '#l_base { width: 54px; padding: 2px 4px 0 3px; }'+
            '#l_base.m { width: 45px; padding: 2px 4px 0 5px; }'+
            '#l_trance { width: 40px; text-align: center; padding: 2px 0 0 4px; }'+
            '#l_color { width: 90px; padding: 2px 24px 0 6px; border: thin solid #aaa; height: 23px; }'+
            '#ms { margin-left: 5px; }'+
            '#test { display: inline-block; }'+
            '#cke_42 { top: 60px !important; left: calc( 50% - 45px) !important; }';

        if(ua==1){
            css=css +
                '#l_width, #l_base, #l_trance, #l_color { height: 24px; border: thin solid #aaa; }'+
                '.wtr::after { content: " "; position: absolute; right: 11px; top: 5px; '+
                'background: #fff; width: 1.2em; }'+
                '.wpxd::after { background: #e3e3e3; }'+
                '#ms { border: thin solid #aaa; height: 28px; }'; }

        let style=document.createElement('style');
        style.innerHTML=css;
        panel.appendChild(style);

        let l_panel=document.querySelector('#l_panel');
        if(!l_panel){
            document.querySelector('.l-body').appendChild(panel); }} // panel_disp()



    function panel_remove(){
        let l_panel=document.querySelector('#l_panel');
        l_panel.remove(); }



    function test_color(color){
        return color.match(
            /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8}|[A-Fa-f0-9]{3}|[A-Fa-f0-9]{4})$/)!==null; }



    function test_colorE(color){ // test_colorE ⏹
        let test=document.querySelector('#test');
        test.style.color='#000001';
        if(color!=''){
            test.style.color=color; } // 引数の入力がない場合

        let colorR=window.getComputedStyle(test).color;
        if(colorR){
            if(colorR!='rgb(0, 0, 1)'){
                return true; }
            else{
                if(color=='rgb(0, 0, 1)' || color=='#000001' || color=='#000001ff'){
                    return true; }
                else{
                    return false; }}}
        else{
            return false; }}



    function show_color(){
        let l_color=document.querySelector('#l_color');
        l_color.style.boxShadow='inset -20px 0 ' + l_color.value; }



    function pick_color(){
        let set_color;
        let color_input_selector;
        let color_label;
        let icon_button;

        editor_iframe=document.querySelector('.cke_wysiwyg_frame');
        iframe_doc=editor_iframe.contentWindow.document;
        selection=iframe_doc.getSelection();

        if(ua==0){
            color_label=document.querySelector('#cke_16_label');
            icon_button=document.querySelector('#cke_17'); }
        else if(ua==1){
            color_label=document.querySelector('#cke_15_label');
            icon_button=document.querySelector('#cke_16'); }

        let target_p=color_label; // 監視 アイコンのカラーラベル
        let monitor_p=new MutationObserver( get_copy );

        let l_color=document.querySelector('#l_color');


        l_color.onclick=function(event){
            if(event.ctrlKey==true){
                event.preventDefault();
                icon_button.click();
                selection.removeAllRanges(); // 反転選択がある場合に背景指定を防止する
                monitor_p.observe(target_p, {attributes: true}); }} // アイコンカラー取得開始

        l_color.addEventListener('input', function(event){
            event.preventDefault();
            let l_trance=document.querySelector('#l_trance');
            if(l_trance){
                l_trance.value=1; } // 透過度をリセットする

            if(test_colorE(l_color.value)){ // test_colorEを実行 ⏹
                l_color.style.boxShadow='inset -20px 0 ' + l_color.value; }
            else{
                if(l_color.value==''){
                    l_color.style.boxShadow='inset 0 0 0 1px black'; }
                else{
                    l_color.style.boxShadow='inset 0 0 0 1px black'; // 担保コード
                    l_color.style.boxShadow=
                        'inset 0 0 0 1px black, inset -20px 0 ' + l_color.value; }}

            if(test_colorE(l_color.value)){ // test_colorEを実行 ⏹ 不適正な入力は登録されない
                setting[task][2]=l_color.value;
                let write_json=JSON.stringify(setting);
                localStorage.setItem('Draw_Line', write_json); }}); // ローカルストレージ 保存


        document.addEventListener('mousedown', function(){
            monitor_p.disconnect(); }); // アイコンカラー取得終了

        if(document.querySelector('.cke_wysiwyg_frame') !=null){
            let editor_iframe=document.querySelector('.cke_wysiwyg_frame');
            let iframe_doc=editor_iframe.contentWindow.document;
            iframe_doc.addEventListener('mousedown', function(){
                monitor_p.disconnect(); }); } // アイコンカラー取得終了


        function get_copy(){
            let l_trance=document.querySelector('#l_trance');
            if(l_trance){
                l_trance.value=1; } // 透過度をリセットする
            set_color=color_label.getAttribute('data-color');
            l_color.value='#'+ set_color;
            l_color.style.boxShadow=
                'inset -20px 0 ' + l_color.value;
            monitor_p.disconnect(); // アイコンカラー取得終了

            setting[task][2]=l_color.value;
            let write_json=JSON.stringify(setting);
            localStorage.setItem('Draw_Line', write_json); } // ローカルストレージ 保存


        let target_body=document.querySelector('.l-body'); // 監視 target
        let monitor_generator=new MutationObserver(stealth);
        monitor_generator.observe(target_body, {childList: true, subtree: true});

        function stealth(){
            let color_generator=document.querySelector('.ck-l-colorGenerator');
            if(color_generator){
                color_generator.addEventListener('mousedown', function(event){
                    event.stopImmediatePropagation(); }); }}
    } // pick_color()



    function trance(){
        let l_color_code;
        let l_color=document.querySelector('#l_color');
        let l_trance=document.querySelector('#l_trance');

        if(l_trance.value){
            if(test_color(l_color.value)){ // #カラーコードは全て#+16進8桁に変更
                if(l_color.value.length==4){
                    let ch=l_color.value.split("");
                    l_color_code='#'+ch[1]+ch[1]+ch[2]+ch[2]+ch[3]+ch[3]+'90'; }
                if(l_color.value.length==5){
                    let ch=l_color.value.split("");
                    l_color_code='#'+ch[1]+ch[1]+ch[2]+ch[2]+ch[3]+ch[3]+ch[4]+ch[4]; }
                if(l_color.value.length==7){
                    l_color_code=l_color.value+'90'; }
                if(l_color.value.length==9){
                    l_color_code=l_color.value; }

                if(l_trance.value!=1){
                    let ch=l_color_code.split('');
                    if(ch[7].match(/[A-Fa-f]/)){ // アルファ値の初桁が「9」を超える場合は「9」に
                        ch[7]='9'; }
                    if(Number(ch[7])<10*l_trance.value-1){ // 初桁とl_tranceの差が「2」以上は手入力
                        l_trance.value=Number(ch[7])/10; } // この場合はl_trance値を入力値に合わせる
                    else{
                        ch[7]=10*l_trance.value.toString(); } // l_tranceの入力に合わせて増減操作
                    ch[8]='0';
                    l_color.value=ch.join(''); }

                else if(l_trance.value==1){
                    l_color.value=l_color_code.slice(0, -2); }
            }}}

} // main()




 

 

 

「Draw The Line」最新版について 

旧いバージョンの JavaScriptツールは、アメーバのページ構成の変更で動作しない場合があり、導入する場合は最新バージョンをお勧めします。

 

●「Draw The Line」の最新バージョンへのリンクは、以下のページのリンクリストから探せます。