npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

canvas-highlighter

v1.0.6

Published

A lib for text highlighting by using Canvas.

Downloads

193

Readme

canvas-highlighter

基于 canvas 实现的文本划词高亮,与文本展示的结构完全解耦,不改变文本内容的 DOM 结构。

Installation

npm install canvas-highlighter

Usage

最简单的实现文本划词直接高亮

import CanvasHighlighter from 'canvas-highlighter'

// container 为页面需要划词高亮区域的 DOM 对象
const container = document.getElementById('container')
const highlighter = new CanvasHighlighter(container)
container.addEventListener('mouseup', () => {
  const range = highlighter.getSelectionRange()
  if (range) highlighter.addRange(range)
})

自定义高亮区域样式

高亮区域采用 konva 库进行渲染,会在划词区域渲染一个 Rect 和底部渲染一个 Line,可通过修改传入 range 对象上的 config 属性进行自定义

const range = highlighter.getSelectionRange()
const { rect, line } = range.config

// 修改矩形填充颜色
rect.fill = 'red'
// 隐藏线段
line.visible = false

highlighter.addRange(range)

监听高亮区域点击

document.addEventListener('click', (event) => {
  // 通过传入点击位置获取 range id
  const id = highlighter.getRangeIdByPointer(event.pageX, event.pageY)
})

添加自定义图形

默认只会在划词区域渲染一个 Rect 和底部渲染一个 Line,如果需要在划词区域添加其他图形,可以传入 shapeConstructors 参数,shapeConstructors 是一个 ShapeConstructor 类型的数组,ShapeConstructor 是一个函数,接收 4 个参数:

  • position:划词区域位置信息
  • id: 划词区域的 id
  • domRects:划词区域的 DOMRect 数组
  • index:当前渲染的 DOMRect 区域的 index

函数需要返回一个 konva Shape 类型的实例对象

import Konva from 'konva'
import CanvasHighlighter, { IRectPosition } from 'canvas-highlighter'

// 注意:并不是一个划词区域只会调用一次 createLine 函数,因为划词区域可能被拆分成多个(比如换行或者字体大小不同导致的划词区域高度不同),所以 createLine 函数可能会被调用多次。
// 可以根据 domRects.length 判断当前划词区域被拆分为几个,index 表示当前渲染的是第几个。
function createLine(position: IRectPosition, id: string, domRects: DOMRect[], index: number) {
  const { x, y, width, height } = position
  return new Konva.Line({
    points: [
      x,
      y + height + 4,
      x + width,
      y + height + 4
    ],
    stroke: 'red',
    strokeWidth: 2
  })
}

const container = document.getElementById('container')
// 添加一个自定义 Line 线段凑成双下划线
const highlighter = new CanvasHighlighter(container, {
  shapeConstructors: [createLine]
})

更多例子

1. 划词点击高亮

在线演示

源码

2. 实现类似语雀的划词评论功能

在线演示

源码

API

CanvasHighlighter(container [, config])

container

需要划词高亮区域的 DOM 对象,必须在该对象内容渲染完成时再调用 new CanvasHighlighter(container)

config

| 参数 | 说明 | 类型 | 默认值 | | - | - | - | - | | position | container 要设置的 position 属性 | relative / absolute | relative | | delay | container 元素 ResizeObserver 触发函数的防抖 delay | number | 300 | | rectFill | 矩形默认填充颜色 | string | rgba(255, 170, 0, 0.2) | | lineStroke | 线段默认填充颜色 | string | rgba(255, 170, 0, 1) | | strokeWidth | 线段默认的宽度 | number | 2 | | shapeConstructors | 自定义图形构造函数数组 | ShapeConstructor[] | — | | pixelRatio | canvas 渲染像素比,当 canvas 元素占用内存过大时可以设置小一点来减少内存占用 | number | — |

instance methods

/**
 * 根据 selection 获取 range,未传 selection 则通过 document.getSelection() 获取
 */
getSelectionRange(selection?: Selection | null): IRange | null

/**
 * 根据 selection 获取头尾两个字符的 DOMRect 对象,未传 selection 则通过 document.getSelection() 获取
 */
getSelectionPosition(selection?: Selection | null): { start: DOMRect, end: DOMRect } | null

/**
 * 清空页面所有 range 并渲染传入的 range 列表
 */
renderRanges(ranges: IRange[]): void

/**
 * 添加 range 并渲染
 * @return ture 表示添加成功,false 表示无效 range
 */
addRange(range: IRange): boolean

/**
 * 根据 id 获取 range
 */
getRange(id: string): IRange | null

/**
 * 根据 id 删除 range
 * @return ture 表示删除成功,false 表示未找到
 */
deleteRange(id: string): boolean

/**
 * 重新渲染已存在 range(根据 id 判断)
 */
updateRange(range: IRange): void

/**
 * 根据 id 获取 range 相对于 container 的位置信息
 */
getRangePositions(id: string): IRectPosition[] | null

/**
 * 获取当前所有 range 的列表
 */
getAllRange(): IRange[]

/**
 * 清除所有 range
 */
clear(): void

/**
 * 根据页面坐标点判断处于哪个 range 范围内,返回该 id
 */
getRangeIdByPointer(x: number, y:number): string | null

/**
 * 根据页面坐标点判断处于哪个 range 范围内,返回所有 range 的 id
 */
getAllRangeIdByPointer(x: number, y: number): string[]

Range

interface IRange {
  // 每个 range 的唯一 id,不能重复
  id: string
  // 划词文本内容
  text: string
  // 开始文本节点
  start: IRangeNode
  // 结束文本节点
  end: IRangeNode
  // 高亮区域的渲染配置项,使用 konva 库进行渲染,可自定义
  config: IRangeConfig
}

interface IRangeNode {
  // 从 container 找到该节点的路径数组
  path: number[]
  // 划词开始偏移量
  offset: number
  // 在该文本中划词的
  text: string
}

interface IRangeConfig {
  // 矩形配置项
  rect: {
    // 填充颜色
    fill: string
    // 是否显示
    visible: boolean
    // 自定义 konva 配置,参考 https://konvajs.org/api/Konva.Rect.html#Rect__anchor
    konvaConfig?: Konva.RectConfig
  }
  // 线段配置项
  line: {
    // 线段颜色
    stroke: string
    // 线段宽度
    strokeWidth: number
    // 是否显示
    visible: boolean
    // 自定义 konva 配置,参考 https://konvajs.org/api/Konva.Line.html#Line__anchor
    konvaConfig?: Konva.LineConfig
  }
}