前言

做过web端编辑器的前端同仁们,或多或少都会接触标尺插件,类似于ps或PPT这些软件中的插件。

比较老的web插件比如jqury的,会产生很多dom,于是写了1个用纯TS和canvas绘制的标尺,不依赖任何第三方库。文档即使用方法如下,欢迎使用,贡献以及提issue!

PS:暂时还不支持辅助线功能,会尽快上线

该插件在一些思路上也参考了另一个大牛的标尺插件daybrush/ruler

light-ruler

DEMO / Github

主要特性(Features)

  • 使用 canvas 绘制,支持无限滚动,不会生成多个 DOM 和引起页面重绘
  • 支持自定义标尺背景色、文字色、刻度色以及单位
  • 支持 translate 模式,即首次 canvas 绘制标尺后,滚动通过 css transform 实现
  • 使用 Typescript 编写,不依赖任何第三方库,打包后文件仅有 26kb(包含样式)
  • 支持缩放刻度值
  • 目前提供 2 种标尺主题样式
  • 提供多实例控制器,可管理多个标尺实例

安装(Installation)


npm i light-ruler

使用(Useage)


  • 基本使用
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 使用
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 使用
<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>

配置(Config)


mode?绘制模式'infinite'/'translate'/'auto'
mountRef?标尺挂载的 DOM(优先于 wrapperElement,会将 mountRef 的 parentElement 作为父容器)HTMLElement
wrapperElement?标尺的父容器 DOM (会自动生成标尺 DOM)HTMLElement / CSSSelector
scrollElement?监听滚动的 DOMHTMLElement / CSSSelector
width?标尺绘制宽度number
height?标尺绘制高度number
rulerId?标尺 idstring
style?标尺样式Object
onScroll?滚动回调函数(x: number, y: number) => Function
  • style 属性
size?标尺尺寸(如 20, 则横向标尺 height 为 20px,纵向标尺 width 为 20px)number
backgroundColor?标尺背景颜色string
fontColor?标尺字体颜色string
fontSize?标尺字体大小(若不设置会自动计算合适大小,如设置了则为绝对值,不会自适应)number
fontWeight?标尺字体粗细'bold'/ number
tickColor?标尺刻度颜色string
unit?标尺单位样式Object
gap?标尺刻度间隔number
scale?标尺刻度值缩放系数number
show?标尺初始化后是否显示boolean
mode?标尺主题样式'center'/'right'
  • unit 属性
backgroundColor?单位背景颜色string
fontColor?单位字体颜色string
fontSize?单位字体大小number
text?单位显示内容string

API


scale

params

scaleNumber缩放系数number
ruler.scale(0.5);

resize

params

width?标尺绘制宽度number
height?标尺绘制高度number
size?标尺尺寸number
ruler.resize({
    width: 1920,
    height: 1080,
    size: 18,
});

update

params

style?标尺样式Object
ruler.update({
    fontColor: "#fff",
    unit: {
        text: "mm",
    },
});

changeScrollElement

params

scrollElement监听的滚动对象HTMLElement/CSSSelector
ruler.changeScrollElement("#wrap");

show

ruler.show();

hide

ruler.hide();

destroy

ruler.destroy();
03-05 15:03