raphael

Raphael

安装使用

yarn add raphael

官方链接

raphael文档

import React, { Component, Fragment } from 'react'
import Raphael from 'raphael'
import imgurl from './DJI_0004_R.JPG'
// 初始界面矩形参数
const rects = [
  {
    id: 1,
    rx: 35,
    ry: 45,
    rw: 20,
    rh: 20,
  }, {
    id: 2,
    rx: 75,
    ry: 45,
    rw: 20,
    rh: 20,
  }, {
    id: 3,
    rx: 115,
    ry: 45,
    rw: 20,
    rh: 20,
  }
]

export default class App extends Component {
  state = {
    targetLegend: null,
    legendId: 1,
    paper: null,
  }

  componentDidMount() {
    let paper = Raphael("raphaelmap", 640, 512)
    const _this = this
    this.setState({
      paper,
    }, () => {
      _this.paintingReady()
      _this.paintRects()
    })
  }
  // 首屏加载,根据参数绘制矩形
  paintRects() {
    const { paper } = this.state
    const _this = this
    let legendId = rects.length + 1
    this.setState({
      legendId,
    })
    rects && rects.forEach(el => {
      let ele = paper.rect(el.rx, el.ry, el.rw, el.rh)
      let ew, eh, ex, ey
      console.log(ele)
      ele.id = el.id
      ele.attr({
        "fill": "transparent",
        "stroke": "red",
        "title": "标记 " + ele.id,
      })
        .drag(
          // 拖动状态中
          (dx, dy, x, y, event) => {
            if (event.shiftKey) {
              // 临界边界判定
              let boundrayW1 = ew + dx > 0,
                boundrayW2 = ex + ew + dx < 640,
                boundrayH1 = eh + dy > 0,
                boundrayH2 = ey + eh + dy < 512
              ele.attr({
                "width": boundrayW1 ? boundrayW2 ? ew + dx : 640 - ex : 3,
                "height": boundrayH1 ? boundrayH2 ? eh + dy : 512 - ey : 3,
                "cursor": "nwse-resize",
              })
            } else {
              // 临界边界判定
              let boundrayX1 = ex + dx > 0,
                boundrayX2 = ex + dx < 640 - ele.attrs.width,
                boundrayY1 = ey + dy > 0,
                boundrayY2 = ey + dy < 512 - ele.attrs.height
              ele.attr({
                "x": boundrayX1 ? boundrayX2 ? ex + dx : 640 - ele.attrs.width : 0,
                "y": boundrayY1 ? boundrayY2 ? ey + dy : 512 - ele.attrs.height : 0,
                "cursor": "move",
              })
            }
          },
          // 拖动状态初始化
          (x, y, event) => {
            const { pretarget } = this.state
            ele.attr({
              "fill": "#ffcdd2",
              "fill-opacity": 0.5,
            })
            pretarget && pretarget !== ele && pretarget.attr({
              "fill": "transparent",
              "fill-opacity": 0,
            })
            ew = ele.attrs.width
            eh = ele.attrs.height
            ex = ele.attrs.x
            ey = ele.attrs.y
            _this.setState({
              pretarget: ele,
            })
          },
          // 拖动状态结束
          () => {
            ele.attr({
              "cursor": "default"
            })
          }
        )
    })
  }
    // 初始化画板
  paintingReady() {
    const { paper } = this.state
    let x1, y1, x2, y2, set, cando = false, _this = this
    let element = paper.rect(0, 0, 640, 512)
    // 链式编程,绑定事件
    element.attr({ "fill": "transparent" })
      .mousedown((e) => {
        const { pretarget } = this.state
        x1 = e.layerX
        y1 = e.layerY
        cando = true
        pretarget && pretarget.attr({
          "fill": "transparent",
          "fill-opacity": 0,
        })
        _this.setState({
          pretarget: null,
        })
      })

      .mousemove((e) => {
        set && set.remove()
        let _x = e.layerX, _y = e.layerY, _width = _x - x1, _height = _y - y1
        if (cando && _width > 0 && _height > 0) {
          paper.setStart()
          paper.rect(x1, y1, _width, _height)
          set = paper.setFinish()
          set.attr({
            "fill": "transparent",
            "stroke": "red",
          })
        }
      })

      .mouseup((e) => {
        const { legendId } = this.state
        cando = false
        x2 = e.layerX
        y2 = e.layerY
        let width = x2 - x1, height = y2 - y1, ex, ey, ew, eh
        if (width > 3 && height > 3) {
          set && set.remove()
          let ele = paper.rect(x1, y1, width, height)
          console.log(ele)
          ele.id = legendId
          _this.setState({
            legendId: legendId + 1,
          })
          ele.attr({
            "fill": "transparent",
            "stroke": "red",
            "title": "标记 " + ele.id,
          })
            .drag(
              // 拖动状态中
              (dx, dy, x, y, event) => {
                if (event.shiftKey) {
                  // 临界边界判定
                  let boundrayW1 = ew + dx > 0,
                    boundrayW2 = ex + ew + dx < 640,
                    boundrayH1 = eh + dy > 0,
                    boundrayH2 = ey + eh + dy < 512
                  ele.attr({
                    "width": boundrayW1 ? boundrayW2 ? ew + dx : 640 - ex : 3,
                    "height": boundrayH1 ? boundrayH2 ? eh + dy : 512 - ey : 3,
                    "cursor": "nwse-resize",
                  })
                } else {
                  // 临界边界判定
                  let boundrayX1 = ex + dx > 0,
                    boundrayX2 = ex + dx < 640 - ele.attrs.width,
                    boundrayY1 = ey + dy > 0,
                    boundrayY2 = ey + dy < 512 - ele.attrs.height
                  ele.attr({
                    "x": boundrayX1 ? boundrayX2 ? ex + dx : 640 - ele.attrs.width : 0,
                    "y": boundrayY1 ? boundrayY2 ? ey + dy : 512 - ele.attrs.height : 0,
                    "cursor": "move",
                  })
                }
              },
              // 拖动状态初始化
              (x, y, event) => {
                const { pretarget } = this.state
                ele.attr({
                  "fill": "#ffcdd2",
                  "fill-opacity": 0.5,
                })
                pretarget && pretarget !== ele && pretarget.attr({
                  "fill": "transparent",
                  "fill-opacity": 0,
                })
                ew = ele.attrs.width
                eh = ele.attrs.height
                ex = ele.attrs.x
                ey = ele.attrs.y
                _this.setState({
                  pretarget: ele,
                })
              },
              // 拖动状态结束
              () => {
                ele.attr({
                  "cursor": "default"
                })
              }
            )
        }
      })
  }

  render() {
    return (
      <Fragment>
        <img src={imgurl} alt="pic" />
        <div id="raphaelmap" style={{ position: "absolute", top: 0, left: 0 }}></div>
      </Fragment>
    )
  }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,753评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,668评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,090评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,010评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,054评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,806评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,484评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,380评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,873评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,021评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,158评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,838评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,499评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,044评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,159评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,449评论 3 374
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,136评论 2 356

推荐阅读更多精彩内容

  • Readme 根据 Raphael官网翻译过来的 http://raphaeljs.com/一方面是联系markd...
    半夕蝶阅读 2,669评论 3 4
  • 本文大部分内容来自文章结尾参考资料中的内容,只是做了部分删减整理。 创建画布 在浏览器窗口中初始化画布 在元素中创...
    mujiaxiansheng阅读 1,893评论 0 0
  • 首先,我和你一样很迷茫这个库,不知道它是用来干嘛的。 只记得任务来了,顺便给了一本全英文的电子书,关于这个库的所有...
    _信仰zmh阅读 3,868评论 0 0
  • [译] 关于 Yarn 和 npm 你所需要知道的一切 原文地址:Yarn vs npm: Everything ...
    暮雨默默阅读 1,521评论 1 2
  • 前端绘图用的最多的就是svg和canvas,现在有许多基于这两种技术的图形框架,比如基于svg的D3 和基于can...
    雨未浓阅读 5,477评论 0 0