「マーカー線」を実装

単線・2重線のアンダーラインに比べて、マーカー線は線幅があるので線幅のジャンプが問題になりません。 このため、マーカー線の実装はとても簡単です。

 

「マーカー線」の位置は「線幅」「開始位置」で指定し、これは「アンダーライン」と同じですが、「線幅」 の指定は「em」単位です。

 

 

「開始位置」の設定範囲は「0em」~「1.3em」の広い範囲が指定可能で、文字全体の背景やアンダーライン同様の描画など、色々なデザインに対応出来ます。

 

 

「透過度」のコントロール 

マーカー線は、線色に「透過度」の調整機能が使えます。 線色の指定は編集画面のカラー設定ダイアログを利用しますが、マーカー線で必要な「淡い色」の設定がし難いので、この機能を追加しました。

 

下はカラー設定ダイアログのパレットからブルーを設定した状態です。

 

 

この濃さでは文字が読み難くいので「透過度」の設定を調整します。 値は 0.1ずつのステップで「1 ~ 0.1」の範囲で濃さを調整できます。

 

 

線色の入力枠の末尾に透過度入力枠の100倍の2桁が追加されます。 この指定方法は、末尾の2桁の16進数の「00」~「FF」で透過度を指定する書式です。 ただ、16進入力枠を作ると複雑になるので簡略化していますが、実用的には充分です。

 

 

単位の表示 

「アンダーライン」の線幅の指定は「px単位」ですが、「マーカー線」は「em単位」で指定する仕様です。 この違いを明示して操作の混乱を防ぐ意味で、入力枠に単位表示を盛り込みました。

 

下は「アンダーライン」のコントロール表示で、数値入力枠に「px」と「em」の単位が表示されています。

 

 

「マーカー線」の「線幅」の入力枠は「em」単位の表示ですが、値を変更するためにマウスを乗せるとスピナーの表示に変わります。

 

 

 

「padding-bottom」の選択的な追加 

ver. 0.2では、装飾線のコードの記入時に、同時に「padding-bottom: 0.4em」を追加していました。 これは「MS Pゴシック」が下線を描画できる範囲が狭いのを改善するためです。 しかし他のフォントでは不要で、本当は省略したい指定でした。

 

そこで、padding追加を選択式に改めました。 右端の「MS」のボタンが選択ボタンで、クリックで「赤帯」が表示され、この状態の時のみ paddingが追加されます。 この機能は「アンダーライン」「マーカー線」の両方で有効になります。

 

 

 

 

 「Draw The Line」ver. 0.3

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

ただし、現在のバージョンは開発段階で、未だ一部の機能しか動作しません。

 

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

 

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

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

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

 

 

〔 Draw The Line 〕ver. 0.3

 

// ==UserScript==
// @name         Draw The Line ⭐
// @namespace  http://tampermonkey.net/
// @version      0.3
// @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=0; //「MS Pゴシック」のために padding-bottom追加フラグ

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


    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();
                    change_panel();
                    draw_line(); }
                else if(task==1){
                    task=2;
                    change_panel();
                    trance();
                    draw_line(); }
                else if(task==2){
                    task=3;
                    change_panel();
                    un_trance();
                    draw_line(); }
                else if(task==3){
                    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 l_width=document.querySelector('#l_width');
        let l_base=document.querySelector('#l_base');
        let l_width_m=document.querySelector('#l_width_m');
        let l_base_m=document.querySelector('#l_base_m');
        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;
            l_width.disabled=true;
            l_width.value=1; }
        single.onclick=function(){
            single.checked=true;
            l_width.disabled=false; }


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


        l_trance.addEventListener('input', function(event){
            event.preventDefault();
            let able=0;
            if(test_color(l_color.value)){ // 3桁 6桁の有効コード
                able=1; }
            if(l_color.value.length==9){ // 8桁で変更可能な場合
                if(test_color(l_color.value.slice(0, -2))){
                    able=1; }}
            if(able==1){
                trance();
                l_color.style.boxShadow='inset -20px 0 ' + l_color.value; }
            else{
                l_trance.value=1; }}); // 変換不能なコードは「1」を変更できない


        l_type.onclick=function(){
            range=selection.getRangeAt(0);
            get_param();
            insert_node=document.createElement('span');
            if(add_padd==1){
                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;
            let l_wm=l_width_m.value;
            let l_bm=l_base_m.value;

            if(task==1 && single.checked){
                style_text=
                    'linear-gradient(transparent '+ l_b +'em, '+
                    l_c +' 0, '+
                    l_c +' calc('+ l_b +'em + '+ l_w +'px), transparent 0)'; }

            if(task==1 && double.checked){
                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==2){
                style_text=
                    'linear-gradient(transparent '+ l_bm +'em, '+
                    l_c +' 0, '+
                    l_c +' calc('+ l_bm +'em + '+ l_wm +'em), transparent 0)'; }
        }
    } // draw_line()



    function change_panel(){
        let l_type=document.querySelector('#l_type');
        let type_1=document.querySelector('#type_1');
        let type_2=document.querySelector('#type_2');

        if(task==1){
            l_type.value="アンダーライン";
            type_1.style.display='inline-block';
            type_2.style.display='none'; }
        else if(task==2){
            l_type.value="マーカー線";
            type_1.style.display='none';
            type_2.style.display='inline-block'; }
        else if(task==3){
            l_type.value="取り消し線";
            type_1.style.display='inline-block';
            type_2.style.display='none'; }}



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

        panel.innerHTML=
            '<input id="l_type" type="submit" value="アンダーライン">'+
            '<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>'+
            '<span class="l_label label_w">線幅</span>'+
            '<div class="wpx"><input id="l_width" type="number" step="1" min="1" max="50" value="1">'+
            '</div>'+
            '<span class="l_label">開始位置</span>'+
            '<div class="wem"><input id="l_base" type="number" step="0.01" min="0.9" max="1.5" value="1.23">'+
            '</div>'+
            '</div>'+
            '<div id="type_2">'+
            '<span class="l_label label_w">線幅</span>'+
            '<div class="wem"><input id="l_width_m" type="number" step="0.1" min="0.1" value="0.6">'+
            '</div>'+
            '<span class="l_label">開始位置</span>'+
            '<div class="wem"><input id="l_base_m" type="number" step="0.1" min="0" max="1.3" value="0.7">'+
            '</div>'+
            '<span class="l_label">透過度</span>'+
            '<input id="l_trance" type="number" step="0.1" min="0.1" max="1" value="0.5">'+
            '</div>'+
            '<span class="l_label">線色</span>'+
            '<input id="l_color" type="text" value="#333" autocomplete="off">'+
            '<input id="ms" type="submit" value="MS">';

        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_1, #type_2 { 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, .wem { position: relative; display: inline-block; }'+
            '.wpx::after { content: "px"; position: absolute; right: 15px; top: 5px; background: #fff; }'+
            '.wem::after { content: "em"; position: absolute; right: 15px; top: 5px; background: #fff; }'+
            '#l_width { width: 38px; text-align: center; padding: 0 4px 0 0; }'+
            '#l_base { width: 54px; padding: 0 4px 0 3px; }'+
            '#l_width_m { width: 45px; padding: 0 4px 0 5px; }'+
            '#l_base_m { width: 45px; padding: 0 4px 0 5px; }'+
            '#l_trance { width: 40px; text-align: center; padding: 0 0 0 4px; }'+
            '#l_color { width: 90px; padding: 2px 24px 0 6px; border: thin solid #aaa; height: 23px; }'+
            '#ms { margin-left: 5px; }'+
            '#cke_42 { top: 60px !important; left: calc( 50% - 45px) !important; }';

        if(ua==1){
            css=css +
                '#l_width, #l_base, #l_width_m, #l_trance { height: 24px; border: thin solid #aaa; }'; }

        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 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_color(l_color.value)){
                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; }}});

        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(); } // アイコンカラー取得終了

        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 test_color(color){
        return color.match(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/) !== null; }



    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)){
                if(l_color.value.length==4){
                    let code_c=l_color.value.split("");
                    l_color_code='#'+code_c[1]+code_c[1]+code_c[2]+code_c[2]+code_c[3]+code_c[3]; }
                else{
                    l_color_code=l_color.value; }

                if(l_trance.value!=1){
                    l_color_code= l_color_code + (100*l_trance.value); }}
            else{
                l_color_code=l_color.value;
                if(l_trance.value==1 && l_color.value.length==9){
                    if(test_color(l_color.value.slice(0, -2))){
                        l_color_code=l_color.value.slice(0, -2); }}
                else if(l_trance.value!=1 && l_color.value.length==9){
                    if(test_color(l_color.value.slice(0, -2))){
                        l_color_code=l_color.value.slice(0, -2) + (100*l_trance.value); }}}
            l_color.value=l_color_code; }}


    function un_trance(){
        let l_color=document.querySelector('#l_color');
        let l_color_code;
        if(l_color.value.length==9){
            if(test_color(l_color.value.slice(0, -2))){
                l_color_code=l_color.value.slice(0, -2); }}
        l_color.value=l_color_code; }


}






 

 

 

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

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

 

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