前言
做过 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>
Tips: 因为标尺应用的 position: absolute,所以包裹标尺的容器肯定要设置 position 属性。
同时要使标尺固定不动,监听滚动的 element 不能是包裹标尺的 element
配置 (Config)
名称 | 含意 | 值 |
---|---|---|
mode? | 绘制模式 | ‘infinite’/’translate’/’auto’ |
mountRef? | 标尺挂载的 DOM(优先于 wrapperElement,会将 mountRef 的 parentElement 作为父容器) | HTMLElement |
wrapperElement? | 标尺的父容器 DOM (会主动生成标尺 DOM) | HTMLElement / CSSSelector |
scrollElement? | 监听滚动的 DOM | HTMLElement / CSSSelector |
width? | 标尺绘制宽度 | number |
height? | 标尺绘制高度 | number |
rulerId? | 标尺 id | string |
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();