0.0.9 • Published 5 months ago

element_marker v0.0.9

Weekly downloads
-
License
MIT
Repository
-
Last release
5 months ago

ElementMarker

Библиотека для выбора HTML элементов в области, указанной мышью

Для использования импортируем библиотеку:

import {ElementMarker } from 'element_marker'

создадим её инстанс:

const elementMarker = new ElementMarker()

а так же активируем:

elementMarker.switchActivity(true)

В DOM должна быть определена минимальная структура:

<div class='ElementMarkerWin'>
    <div class='Elem'>Element 1</div>
    <div class='Elem'>Element 2</div>
</div>

Слушаем события мыши:

document.addEventListener('mousedown', handlerMarking)
document.addEventListener('mouseup', handlerMarking)
document.addEventListener('mousemove', handlerMarking)
document.addEventListener('onElementMarker', e => handleAfterMarking(e))

Ищутся элементы с классом 'Elem' в родительском HTML элементе с классом 'ElementMarkerWin', при этом генерируется событие 'onElementMarker', в свойстве e.detail которого содержится массив с найденными HTML элементами.

Кастомизация: 'Elem' и 'ElementMarkerWin' являются классами по-умолчанию, но они могут быть переопределены:

elementMarker.settings = {winClassName: 'newParentClass', elemClassName: 'newElemClass'}

Дополнительно может быть задан цвет рамки и области выбора:

elementMarker.settings = {color: '#7fff00'}

Библиотека может быть легко использована с UI-библиотеками и фреймворками, например React:

app.tsx:

import {useEffect, useState} from "react"
import {ElementMarker } from 'element_marker'
import './style.scss'

const elementMarker = new ElementMarker()

const elemsSet = [
    {id: 0, name: '0'},
    {id: 1, name: '1'},
    {id: 2, name: '2'},
    {id: 3, name: '3'},
    {id: 4, name: '4'},
    {id: 5, name: '5'},
]

const App = () => {
    const [elems] = useState(elemsSet)
    const [markedElemIds, setMarkedElemIds] = useState<number[]>([])

    const handlerMarking = (e: MouseEvent) => elementMarker.drawRect(e)
    const handleAfterMarking = (e: CustomEvent<Element[]>) => {
        const newMarkedElemIds = e.detail.map(el => +el.getAttribute('data-elem-id')!)
        setMarkedElemIds(newMarkedElemIds)
    }

    useEffect(() => {
        document.addEventListener('mousedown', handlerMarking)
        document.addEventListener('mouseup', handlerMarking)
        document.addEventListener('mousemove', handlerMarking)
        document.addEventListener('onElementMarker', handleAfterMarking)

        return () => {
            document.removeEventListener('mousedown', handlerMarking)
            document.removeEventListener('mouseup', handlerMarking)
            document.removeEventListener('mousemove', handlerMarking)
            document.removeEventListener('onElementMarker', handleAfterMarking)
        }
    }, [])

    useEffect(() => {
        elementMarker.settings = {winClassName: 'ElementMarkerWin', elemClassName: 'Elem', color: '#7fff00'}
        elementMarker.switchActivity(true)
    }, [])

    return (
        <div className={'ElementMarkerWin'}>
            <div className={'interlayer'}>
                {elems.map(el => {
                    const markedCls = markedElemIds.includes(el.id) ? 'marked' : ''
                    return <div key={el.id} className={`Elem ${markedCls}`} data-elem-id={el.id}>{el.name}</div>
                })}
            </div>
        </div>
    )
}

export default App

style.scss:

.ElementMarkerWin {
  width: 98vw;
  height: 98vh !important;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
.Elem {
  background-color: #bae6fd;
  color: black;
  display: flex;
  justify-content: center;
  align-items: center;
  &.marked {
    background-color: rgb(115, 255, 0);
  }
}
.interlayer {
  width: 500px;
  height: 200px;

  display: grid;
  grid-template-columns: 200px 200px;
  gap: 10px;
  align-items: stretch;
}
0.0.9

5 months ago

0.0.8

5 months ago

0.0.7

5 months ago

0.0.6

5 months ago

0.0.5

5 months ago

0.0.4

5 months ago

0.0.3

5 months ago

0.0.2

5 months ago

0.0.1

5 months ago