Giter Club home page Giter Club logo

refline.js's Introduction

refline.js

refline.js是完全不依赖设计器环境的参考线组件,方便各种设计器快速接入,支持参考线匹配及吸附功能。

refline.js

示例

Edit refline.js

安装

npm install refline.js

使用

import { RefLine } from 'refline.js'

const refLine = new RefLine({
  rects: [{
    key: 'a',
    left: 100,
    top: 100,
    width: 400,
    height: 800
  }],
  points: [{
    x: 300,
    y: 300
  }],
  current: {
    key: 'b',
    left: 100,
    top: 100,
    width: 100,
    height: 100
  }
})

// 匹配参考线
const lines = refLine.getAllRefLines()

// 拖拽下参考线吸附
// mousedown
const updater = refLine.adsorbCreator({
  pageX: 100,
  pageY: 100,
})
// mousemove
const {delta} = updater({
  pageX: 108,
  pageY: 110,
})

// TODO.

createRefLine(opts: RefLineOpts): RefLine

创建 RefLine 实例

RefLine

constructor(opts: RefLineOpts)

构造函数

interface RefLineOpts<T extends Rect> {
    // 所有矩形列表
    rects?: T[];
    // 设置单个吸附点
    points?: Point;
    // 当前检查的矩形,可通过setCurrent改变
    current?: T | string;
    // 参考线过滤,默认提供6条参考线(水平、垂直),可通过该参数过滤不需要的参考线
    lineFilter?: (line: RefLineMeta) => boolean;
    /**
     * 自定义处理矩形生成的吸附线,不包含自定义吸附线
     */
    lineProcess?: (line: RefLineMeta<T>) => void
    // 自定义垂直吸附线
    adsorbVLines?: Array<{key: string; offset: number}>;
    // 自定义水平吸附线
    adsorbHLines?: Array<{key: string; offset: number}>;
    /**
     * 吸附匹配流程中对吸附线的过滤,包含所有线段
     */
    adsorbLineFilter?: (line: LineGroup) => boolean;
}

setCurrent(current)

设置当前需要检查的矩形

const refLine = new RefLine({...});
refLine.setCurrent({
  key: 'b',
  left: 100,
  top: 100,
  width: 100,
  height: 100
})

// 获取匹配到的垂直辅助线
refLine.getVRefLines()

setLineFilter(filter)

更新lineFilter

getVRefLines(): MatchedLine[]

获取匹配到的垂直参考线,返回一个参考线列表,为匹配到时返回一个空数组

interface MatchedLine{
  // 匹配后辅助线的类型
  type: "horizontal" | "vertical";
  // 辅助线相对矩形所在容器的坐标 x
  left: number;
  // 辅助线相对矩形所在容器的坐标 y
  top: number;
  // 辅助线高度(相对水平辅助线就是宽度)
  size: number;
  // 匹配到的矩形列表元信息
  refLineMetaList: RefLineMeta[];
}

getHRefLines(): MatchedLine[]

获取匹配到的水平参考线,返回一个参考线列表,为匹配到时返回一个空数组

getAllRefLines(): MatchedLine[]

获取匹配到的水平参考线及垂直参考线

getAdsorbDelta()

给定当前的偏移量进行吸附偏移量计算,如果有吸附返回一个新的偏移量,如果无吸附则返回当前偏移量。

adsorbCreator(IOpts): Updater

根据给定坐标,创建吸附偏移量生成器,将新坐标传进生成器后可获得计算后的偏移量

interface IOpts{
  pageX: number;
  pageY: number;
  current?: Rect;
   /**
    * 优先级高于 current
    */
  point?: Point;
  distance?: number;
  // 禁用吸附计算
  disableAdsorb?: boolean;
  // 当前视图缩放比例,默认为:1
  scale?: number;
}

**:** `scale`的作用仅仅用于计算缩放后拖拽距离

type Updater = (data: {
    pageX?: number;
    pageY?: number;
    current?: Rect;
     /**
      * 优先级高于 current
      */
    point?: Point;
    distance?: number;
    // 禁用吸附计算
    disableAdsorb?: boolean;
    // 更新当前视图缩放比例,默认为:1
    scale?: number;
    // 设置距离起始坐标偏移量,设置后相应的pageX或pageY及scale会失效
    offsetX?: number;
    offsetY?: number;
}) => {
    // 拖动原始偏移量
    raw: {
      left: number;
      top: number;
    };
    // 拖动时吸附产生的偏移量,无吸附的情况下delta和raw是相等的
    delta: {
      left: number;
      top: number;
    };
    // 相对初始pageX/pageY的偏移量
    offset: {
      left: number;
      top: number;
    };
    rect: Rect;
}

使用示例:

const refLine = new RefLine({...})

const updater = refLine.adsorbCreator({
  current: rect,
  pageX: 100,
  pageY: 100,
  distance: 5,
  scale: 1
})

const ret = updater({
  pageX: 105,
  pageY: 200
})

rect.left += ret.delta.left
rect.top += ret.delta.top

Interfaces

export interface RefLineOpts<T extends Rect = Rect> {
    rects?: T[];
    points?: Point[];
    current?: T | string;
    /**
     * 过滤矩形生成的吸附线,不包含自定义吸附线
     */
    lineFilter?: (line: RefLineMeta<T>) => boolean;
    adsorbVLines?: Omit<AdsorbLine, "type">[];
    adsorbHLines?: Omit<AdsorbLine, "type">[];
    /**
     * 吸附匹配流程中对吸附线的过滤,包含所有线段
     */
    adsorbLineFilter?: (line: LineGroup<T>) => boolean;
}
export declare class RefLine<T extends Rect = Rect> {
    get rects(): T[];
    get vLines(): LineGroup<T>[];
    get hLines(): LineGroup<T>[];
    get vLineMap(): Map<string, RefLineMeta<T>[]>;
    get hLineMap(): Map<string, RefLineMeta<T>[]>;
    get adsorbVLines(): AdsorbVLine[];
    set adsorbVLines(lines: AdsorbVLine[]);
    get adsorbHLines(): AdsorbHLine[];
    set adsorbHLines(lines: AdsorbHLine[]);
    get adsorbLineFilter(): ((line: LineGroup<T>) => boolean) | undefined;
    constructor(opts?: RefLineOpts<T>);
    getRectByKey(key: string | number): T | null;
    getOffsetRefLineMetaList(type: LineType, offset: number): RefLineMeta<T>[];
    addPoint(point: Point): Rect;
    addRect(rect: T): T;
    removeRect(key: string | number): void;
    removePoint(key: string | number): void;
    setCurrent(current: T | string | null): void;
    getCurrent(): T | null;
    setLineFilter(filter: ((line: RefLineMeta) => boolean) | null): void;
    getLineFilter(): ((line: RefLineMeta<Rect>) => boolean) | null;
    setLineProcess(process: ((line: RefLineMeta) => void) | null): void
    getLineProcess(): ((line: RefLineMeta) => void) | null
    /**
     * 匹配参考线,主要用于显示
     * @param type
     * @param {boolean} [adsorbOnly=false] 是否仅获取自定义吸附线或排除自定义吸附线
     * @param rect
     * @returns
     */
    matchRefLines(type: LineType, adsorbOnly?: boolean): MatchedLine<T>[];
    /**
     * 给定offset(坐标x或y)的值,返回距离该offset的最近的两个offset(上下或左右)及距离
     * @param type
     * @param offset
     * @returns
     */
    getNearestOffsetFromOffset(type: LineType, offset: number): [[number, number] | null, [number, number] | null];
    /**
     * 指定当前矩形需要检查的参考线,判断是否存在匹配,包括自定义吸附线
     * @param position
     * @returns
     */
    hasMatchedRefLine(position: RefLinePosition): boolean;
    /**
     * alias getVRefLines
     * @returns
     */
    matchVRefLines(): MatchedLine<T>[];
    /**
     * 返回当前矩形匹配到的垂直参考线
     * 注:不包括自定义吸附参考线,既:adsorbVLines
     * @returns
     */
    getVRefLines(): MatchedLine<T>[];
    /**
     * alias getHRefLines
     * @returns
     */
    matchHRefLines(): MatchedLine<T>[];
    /**
     * 返回当前矩形匹配到的水平参考线
     * 注:不包括自定义吸附参考线,既:adsorbHLines
     * @returns
     */
    getHRefLines(): MatchedLine<T>[];
    /**
     * alias getAllRefLines
     * @returns
     */
    matchAllRefLines(): MatchedLine<T>[];
    /**
     * 返回当前矩形匹配到的 水平、垂直参考线
     * 注:不包括自定义吸附参考线,既:adsorbVLines、adsorbHLines
     * @returns
     */
    getAllRefLines(): MatchedLine<T>[];
    /**
     * 返回当前矩形匹配到的自定义水平参考线
     * @returns
     */
    getAdsorbHRefLines(): MatchedLine<T>[];
    /**
     * 返回当前矩形匹配到的自定义垂直参考线
     * @returns
     */
    getAdsorbVRefLines(): MatchedLine<T>[];
    /**
     * 返回当前矩形匹配到的自定义水平、垂直参考线
     * @returns
     */
    getAllAdsorbRefLines(): MatchedLine<T>[];
    /**
     * 适配偏移量,达到吸附效果
     * @param type
     * @param offset
     * @param delta
     * @param adsorbDistance
     * @returns
     */
    getOffsetAdsorbDelta(type: LineType, offset: number, delta: number, adsorbDistance?: number): number;
    /**
     * 适配偏移量,达到吸附效果
     * @param delta
     * @param adsorbDistance
     * @returns
     */
    getAdsorbDelta(delta: Delta, adsorbDistance: number, dir: {
        x: "left" | "right" | "none";
        y: "up" | "down" | "none";
    }): Delta;
    adsorbCreator({ pageX, pageY, current, point, distance, disableAdsorb, scale, }: {
        pageX: number;
        pageY: number;
        current?: T | null;
        /**
         * 优先级高于 current
         */
        point?: Point;
        distance?: number;
        disableAdsorb?: boolean;
        scale?: number;
    }): (data: {
        pageX?: number;
        pageY?: number;
        current?: T;
        point?: Point;
        distance?: number;
        disableAdsorb?: boolean;
        scale?: number;
        offsetX?: number;
        offsetY?: number;
    }) => {
        raw: {
            left: number;
            top: number;
        };
        delta: {
            left: number;
            top: number;
        };
        offset: {
            left: number;
            top: number;
        };
        rect: T;
    };
}
export declare function createRefLine<T extends Rect = Rect>(opts: RefLineOpts<T>): RefLine<T>;
export default RefLine;

export interface Rect {
  key: string | number;
  left: number;
  top: number;
  width: number;
  height: number;
  rotate?: number;
  [x: string]: any;
}

export interface BoundingRect {
  left: number;
  top: number;
  right: number;
  bottom: number;
  width: number;
  height: number;
}

export type LineType = "horizontal" | "vertical";

// horizontal/vertical  top/center/bottom left/center/right
export type VRefLinePosition = "vl" | "vc" | "vr";
export type HRefLinePosition = "ht" | "hc" | "hb";
export type RefLinePosition = VRefLinePosition | HRefLinePosition;
export interface AdsorbLine {
  key: string;
  type: LineType;
  offset: number;
}

export type AdsorbVLine = Omit<AdsorbLine, "type">;
export type AdsorbHLine = Omit<AdsorbLine, "type">;
export interface RefLineMeta<T extends Rect = Rect> {
  type: LineType;
  position: RefLinePosition;
  offset: number;
  start: number;
  end: number;
  rect: T;
  adsorbOnly?: boolean;
  /**
   * 当匹配到的是自定义吸附线
   */
  line?: AdsorbVLine | AdsorbVLine;
}

export interface MatchedLine<T extends Rect = Rect> {
  type: LineType;
  left: number;
  top: number;
  size: number;
  refLineMetaList: RefLineMeta<T>[];
}

export interface LineGroup<T extends Rect = Rect> {
  min: number;
  max: number;
  offset: number;
  refLineMetaList: RefLineMeta<T>[];
}

export interface Delta {
  left: number;
  top: number;
}

export enum MOVE_DIR {
  MOVE_TOP,
  MOVE_RIGHT,
  MOVE_BOTTOM,
  MOVE_LEFT,
  NONE,
}

export interface Point {
  key?: string | number;
  x: number;
  y: number;
}

refline.js's People

Contributors

bplok20010 avatar

Stargazers

 avatar EC avatar dufemeng avatar Jin Yao avatar Edward Xie avatar Vint avatar  avatar acvv_khalil avatar Zion avatar Evan avatar  avatar moxiufe avatar  avatar M.Winchester avatar  avatar Jlg1128 avatar Rhuzerv avatar XLor avatar tumars avatar 阿良仔 avatar Zhanghao avatar 嚴肅遊戲 avatar Alex Yang avatar Flrande avatar Pionxzh avatar Vincent Chan avatar Kha'Zix avatar ZCDC_Ren avatar Tenvi avatar Horus avatar Suyi avatar 尹挚 avatar czh avatar  avatar 王洪莹 avatar Vaan Kong avatar 米大熊 avatar 胡昊 avatar niphor avatar  avatar qinjiayang avatar  avatar  avatar TiyeeJiang avatar  avatar  avatar ᝰ 大辉 avatar zhhyang avatar  avatar Stephen Cui avatar ivoryoung avatar 蜡笔小新 avatar 周杨 avatar 小白不圆 avatar  avatar  avatar liu-mengwei avatar 伟伟权 avatar Superlin avatar Eternal_Jovi avatar lxp avatar Syan avatar Lee avatar  avatar xlitter avatar Max.Neo avatar Sanonz avatar  avatar Viweei avatar  avatar well avatar  avatar  avatar  avatar MO avatar Zenquan avatar  avatar  avatar  avatar Anyx avatar zhiqiang.T avatar ivany avatar  avatar Joe_Sky avatar yuhongda avatar  avatar Alfreton avatar  avatar ggymm avatar cary avatar  avatar  avatar 代码编写者C avatar Link-Kou avatar  avatar  avatar 杜鹏 avatar caixiaomao avatar  avatar  avatar

Watchers

Jeanvi, xue avatar  avatar  avatar

refline.js's Issues

垂直和水平参考线问题

在线示例:http://49.233.166.224/data-view-web/data-view-instance/create
代码:https://github.com/ggymm/data-view-web-preview

重现步骤:

  1. 添加纵向参考线
  2. 位移组件
    点击图表组件进行位移操作会调用src/store/modules/data-view/refline.js中的setRefline方法,会获取所有横向和纵向的参考线,然后初始化refline
  3. 移动时使用updater方法获取delta,但是没有触发吸附操作

我将吸附距离调大,并且添加横向参考线,出现了吸附现象(和吸附距离应该无关,只是调大会现象比较明显)。但是吸附位置不正确

麻烦帮忙看下是什么问题,多谢了

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.