I open source a lightweight ruler plug-in for the web!

preface

Front end colleagues who have worked as web side editors will more or less contact ruler plug-ins, similar to plug-ins in ps or PPT software.

Older web plug-ins, such as jqury, produce a lot of dom, so they write a ruler drawn with pure TS and canvas, which does not rely on any third-party library. The usage of the document is as follows. Welcome to use, contribute and issue!

PS: the auxiliary line function is not supported yet. It will be launched as soon as possible

The plug-in also refers to another Daniel's ruler plug-in in some ideas daybrush/ruler

light-ruler

DEMO / Github

Main features

  • Drawing with canvas supports infinite scrolling and does not generate multiple DOM S and cause page redrawing
  • Support custom ruler background color, text color, scale color and unit
  • Support translate mode, that is, after drawing the ruler in canvas for the first time, the scrolling is realized through css transform
  • It is written in Typescript and does not rely on any third-party library. After packaging, the file is only 26KB (including styles)
  • Supports scaling scale values
  • There are currently 2 ruler theme styles available
  • Multi instance controller is provided to manage multiple ruler instances

Installation

npm i light-ruler

Use (Useage)

  • Basic use
import LightRuler from "light-ruler";

const ruler = new LightRuler({
    mode: "infinite",
    wrapperElement: document.getElementById("box"),
    scrollElement: document.getElementById("wrap"),
    rulerId: "my-ruler",
    width: 30000,
    height: 30000,
    style: {
        mode: "right",
    },
    onScroll: (x, y) => {
        console.log(x, y);
    },
});
  • React use
import React, { useRef, useEffect } from "react";
import LightRuler from "light-ruler";

export default function () {
    const rulerRef = useRef(null);

    useEffect(() => {
        const ruler = new LightRuler({
            mode: "infinite",
            mountRef: rulerRef.current,
            scrollElement: document.getElementById("wrap"),
            rulerId: "ruler",
            width: 30000,
            height: 30000,
            onScroll: (x, y) => {
                console.log(x, y);
            },
        });
    }, []);
    return (
        <div id="root">
            <div id="box">
                <div id="wrap">...</div>
                <div id="ruler" ref={rulerRef}></div>
            </div>
        </div>
    );
}
  • Vue3 use
<template>
    <div id="gomi-homePage">
        <div
            id="box"
            :style="{ position: 'relative', width: '800px', height: '600px', overflow: 'hidden', background: 'red' }"
        >
            <div id="s" :style="{ width: '100%', height: '100%', overflow: 'auto' }">
                <div id="wrap" :style="{ width: '30000px', height: '4600px' }"></div>
            </div>
            <div id="ruler" ref="ruler"></div>
        </div>
        <footer>
        </footer>
    </div>
</template>

<script lang="ts">
import LightRuler from 'light-ruler';
import { onMounted, ref, defineComponent } from "vue";

export default defineComponent({
    name: "Home",
    props: {},
    setup: () => {
        const ruler = ref(null);
        onMounted(() => {
            const myRuler = new LightRuler({
                mountRef: ruler.value,
                mode: "infinite",
                scrollElement: "#s",
                rulerId: "hh",
                width: 30000,
                height: 30000,
                style: {
                    mode: 'right'
                },
                onScroll: (x, y) => {
                    console.log(x, y);
                },
            })
        });

        return {  ruler };
    },
});
</script>

<style scoped lang="scss">
</style>

Tips: because the ruler uses position: absolute, the container wrapping the ruler must set the position attribute.
At the same time, the ruler shall be fixed. The element monitoring the rolling shall not be the element wrapping the ruler

Configuration (Config)

namemeaningvalue
mode?Draw mode'infinite'/'translate'/'auto'
mountRef?DOM attached to the ruler (takes precedence over wrapperElement, and takes the parentElement of mountRef as the parent container)HTMLElement
wrapperElement?The dom of the ruler's parent container (the ruler DOM is automatically generated)HTMLElement / CSSSelector
scrollElement?Listening for scrolling DOMHTMLElement / CSSSelector
width?Ruler draw widthnumber
height?Ruler drawing heightnumber
rulerId?Ruler idstring
style?Ruler styleObject
onScroll?Scroll callback function(x: number, y: number) => Function
  • style attribute
namemeaningvalue
size?Scale size (if 20, the horizontal scale height is 20px and the longitudinal scale width is 20px)number
backgroundColor?Ruler background colorstring
fontColor?Ruler font colorstring
fontSize?Ruler font size (if it is not set, the appropriate size will be calculated automatically. If it is set, it will be an absolute value and will not be adaptive)number
fontWeight?Ruler font thickness'bold'/ number
tickColor?Ruler scale colorstring
unit?Ruler unit styleObject
gap?Scale intervalnumber
scale?Scale value scaling factornumber
show?Whether to display after ruler initializationboolean
mode?Ruler theme style'center'/'right'
  • unit attribute
namemeaningvalue
backgroundColor?Unit background colorstring
fontColor?Unit font colorstring
fontSize?Unit font sizenumber
text?Unit display contentstring

API

scale

Set the scale scaling factor, and the scale value will change according to the scaling factor

params

namemeaningvalue
scaleNumberScaling factornumber
ruler.scale(0.5);

resize

Reset ruler width, height or size

params

namemeaningvalue
width?Ruler draw widthnumber
height?Ruler drawing heightnumber
size?Scale sizenumber
ruler.resize({
    width: 1920,
    height: 1080,
    size: 18,
});

update

Update ruler style

params

namemeaningvalue
style?Ruler styleObject
ruler.update({
    fontColor: "#fff",
    unit: {
        text: "mm",
    },
});

changeScrollElement

Change the scrolling object that the ruler listens to

params

namemeaningvalue
scrollElementListening scroll objectHTMLElement/CSSSelector
ruler.changeScrollElement("#wrap");

show

Display ruler

ruler.show();

hide

Hide Rulers

ruler.hide();

destroy

Clear ruler

ruler.destroy();

Keywords: Front-end React TypeScript Vue.js

Added by gio2k on Sun, 05 Dec 2021 16:30:55 +0200