モバイル環境のScrapboxにスワイプカーソルを導入する

更新履歴

日付をタップすると展開します。


Scrapboxに書きたいという欲求は状況を選んで現れてはくれません。
いつでもどこでもScrapboxに書き付けられるようにしておきたい。
 

以前紹介したiOS向けのスクリプトと今回紹介するスクリプトを併せて導入すると、モバイルでのページ編集がいい感じになります。

▼1本指スワイプでカーソル移動

▼長押しスライドで虫眼鏡も使えます

▼2本指スワイプでテキスト選択

Androidでは肝心のコピーメニューが出てきませんので、Scrapboxの拡張ポップアップに「コピー」を追加して最低限コピーだけはできるようにしました。

--

ネイティブアプリがなくとも、モバイルにおいてもScrapboxは現時点ですでに最強格のエディタと言っていいかもしれません。

動作確認済み

  • iPhone
    • Safari → 最も安定している
    • Chrome
    • Opera mini
  • Android
    • Chrome

コード

code:script.js
    (function(){
    // このスクリプトをオン・オフする
    const this_script = 'on';
    // 1本指スワイプ感度(数字が小さいほど感度が高い)
    const sensitivity1 = 14;
    // 2本指スワイプ感度
    const sensitivity2 = 8;
    // 1本指スワイプを有効にするデバイスのリスト(Dummy Deviceは消さないで下さい)
    const device_list1 = ['iPhone', 'Android', 'Dummy Device'];
    // 2本指スワイプを有効にするデバイスのリスト
    const device_list2 = ['iPhone', 'Android', 'Dummy Device'];
    // 拡張ポップアップに「コピー」を追加するデバイスのリスト
    const device_list3 = ['Android', 'Dummy Device'];
    
    function get_coordinate($touchevent, num) {
        return {
            x: $touchevent.originalEvent.touches[num].pageX,
            y: $touchevent.originalEvent.touches[num].pageY
        };
    }
    function disable_scrolling() {
        $(window).on('touchmove.no_scroll', e => e.preventDefault());
    }
    function enable_scrolling() {
        $(window).off('.no_scroll');
    }
    function main(trial_times) {
        try {
            const textarea_elem = document.getElementById('text-input');
            const $editor_obj = $('#editor');
            if (!textarea_elem || !$editor_obj) {
                throw new Error();
            }
            const keydown_event = {
                event: document.createEvent('Event'),
                init: function(type) {
                    this.event.initEvent(type, true, true);
                },
                dispatch: function(keycode, with_shift, elem) {
                    this.event.keyCode = keycode;
                    this.event.shiftKey = with_shift;
                    elem.dispatchEvent(this.event);
                }
            };
            keydown_event.init('keydown');
            const finger1_active = new RegExp(device_list1.join('|'), 'i').test(user_agent);
            const finger2_active = new RegExp(device_list2.join('|'), 'i').test(user_agent);
            let coord_start1, coord_start2;
            let yx_ratio_threshold1 = 0.2;
            let text_selected = false;
            
            $editor_obj.on('touchstart', e => {
                text_selected = false;
                switch (e.originalEvent.touches.length) {
                    case 1:
                        coord_start1 = get_coordinate(e, 0);
                        break;
                    case 2:
                        if (!finger2_active || textarea_elem !== document.activeElement) return;
                        disable_scrolling();
                        coord_start1 = get_coordinate(e, 0);
                        coord_start2 = get_coordinate(e, 1);
                        break;
                    default:
                        break;
                }
            });
            $editor_obj.on('touchmove', e => {
                const coord_current1 = get_coordinate(e, 0);
                const x_variation1 = coord_start1.x - coord_current1.x;
                const y_variation1 = coord_start1.y - coord_current1.y;
                switch (e.originalEvent.touches.length) {
                    case 1:
                        if (!finger1_active || textarea_elem !== document.activeElement || text_selected) return;
                        if ( Math.abs(y_variation1 / x_variation1) < yx_ratio_threshold1) {
                            if (x_variation1 > sensitivity1) {
                                keydown_event.dispatch(37, false, textarea_elem);
                            } else if (x_variation1 < - sensitivity1) {
                                keydown_event.dispatch(39, false, textarea_elem);
                            } else {
                                return;
                            }
                            disable_scrolling();
                            yx_ratio_threshold1 = 1;
                            coord_start1 = coord_current1;
                        }
                        break;
                    case 2:
                        if (!finger2_active || textarea_elem !== document.activeElement) return;
                        const coord_current2 = get_coordinate(e, 1);
                        const x_variation2 = coord_start2.x - coord_current2.x;
                        const x_variation_sum = x_variation1 + x_variation2;
                        if (x_variation_sum > sensitivity2) {
                            keydown_event.dispatch(37, true, textarea_elem);
                        } else if (x_variation_sum < - sensitivity2) {
                            keydown_event.dispatch(39, true, textarea_elem);
                        } else {
                            return;
                        }
                        text_selected = true;
                        coord_start1 = coord_current1;
                        coord_start2 = coord_current2;
                        break;
                    default:
                        break;
                }
            });
            $editor_obj.on('touchend', e => {
                enable_scrolling();
                yx_ratio_threshold1 = 0.2;
            });
        } catch(e) {
            trial_times++;
            if (trial_times > 10) return;
            setTimeout(() => {
                main(trial_times);
            }, 2000);
        }
    }
    
    const user_agent = navigator.userAgent;
    if (this_script === 'on') {
        if (new RegExp(device_list3.join('|'), 'i').test(user_agent)) {
            scrapbox.PopupMenu.addButton({
                title: 'コピー',
                onClick: () => document.execCommand('copy')
            });
        }
        if (new RegExp(device_list1.concat(device_list2).join('|'), 'i').test(user_agent)) {
            main(0);
        }
    }
    
    })();

スポンサーリンク

導入の手順

  1. ScrapboxのUserScriptの機能を有効にする
    Scrapboxの右上のMenu -> Edit Profile -> Extensionタブ
    と進み、User ScriptのEnabledにチェックを入れる

  2. コードを「自分のページ」に貼り付ける

「自分のページ」って何だ?という方はこちらを参照。
自分のページ - 橋本商会

設定できる項目

コードの先頭あたりにあります。

// このスクリプトをオン・オフする
const this_script = 'on';
// 1本指スワイプ感度(数字が小さいほど感度が高い)
const sensitivity1 = 14;
// 2本指スワイプ感度
const sensitivity2 = 8;
// 1本指スワイプを有効にするデバイスのリスト(Dummy Deviceは消さないで下さい)
const device_list1 = ['iPhone', 'Android', 'Dummy Device'];
// 2本指スワイプを有効にするデバイスのリスト
const device_list2 = ['iPhone', 'Android', 'Dummy Device'];
// 拡張ポップアップに「コピー」を追加するデバイスのリスト
const device_list3 = ['Android', 'Dummy Device'];

 

2本指スワイプについての補足説明

  1. 2本の指を両方動かすと素早くドラッグできます。
  2. 片方の指を固定して片方だけ動かすと半分の速さになります。
  3. iOSの場合は、選択後、画面を上か下へちょっとだけスクロールするとiOSのポップアップメニューが出てきます。

他にこんな記事を書きました。

スポンサーリンク
スポンサーリンク

1 個のコメント

  • コメントを残す

    メールアドレスが公開されることはありません。