(三) 渲染基础图形

100 阅读1分钟

新建Base类

base类用来抽象基础的属性,例如每个图形基础的背景色,填充色等,定义他的get和set方法。详细代码见base.js,所有的图形统一继承自Base

line渲染

对于线的渲染,首先要计算出点的位置

mpoint类如下

const store = require('@/store/index').default

class MPoint {
  constructor(argv = {
    x: 0,
    y: 0
  }) {
    this.x = Number(argv.x)
    this.y = Number(argv.y)
  }

  equals(other) {
    return (Math.abs(other.x - this.x) <= 0.0001 && Math.abs(other.y - this.y) <= 0.0001)
  }

  get tx() {
    const {
      minX
    } = store.state.svgJSON

    return Number(this.x) - Number(minX)
  }

  set tx(value) {
    const {
      minX
    } = store.state.svgJSON
    this.x = Number(value) + Number(minX)
  }

  get ty() {
    const {
      maxY,
      minY
    } = store.state.svgJSON
    const cadHeight = maxY - minY
    return cadHeight - (Number(this.y) - Number(minY))
  }

  set ty(value) {
    const {
      minY,
      maxY
    } = store.state.svgJSON
    const cadHeight = maxY - minY
    this.y = cadHeight + Number(minY) - Number(value)
  }
}

export default MPoint

这个tx,ty才是点的真正位置,因为json文件的坐标位置相对于minx,minY,所以要减掉这两个值才是真正的位置,因为我们的viewbox是从0,0开始算的

渲染线的基础代码:

render() {
     if (this.show) {
       this.line ? this.line.clear() : ''
       this.group = this.draw.group()
       this.line = this.draw.line(`${this.startPoint.tx},${this.startPoint.ty} ${this.endPoint.tx},${this.endPoint.ty}`).css({
         stroke: this.myColor ? this.myColor : this.color,
         'stroke-dasharray': this.dashArray,
         'stroke-width': this.stokeWidth < 0.01 ? 0.4 : this.stokeWidth
       }).attr({
         id: this.id
       })
     }
   }

如果不熟悉svg.js的操作,可以参考svg.js文档

实现之后画面已经把线段实现出来了,并且可以缩放 如下图

image.png

circle 渲染

circle类的render函数如下, SVG<ellipse>元素可以用来绘制椭圆。椭圆其实就是有不同高度和宽度的圆,即其在x和y方向上的半径不同, majorRadius,minorRadius相同就是圆,不同就是椭圆 this.draw.ellipse(x方向长度,y方向长度)

  render() {
    if (this.show) {
      this.group = this.draw.group()
      this.circle ? this.circle.clear() : ''
      // 初始化时用的是直径
      this.circle = this.draw.ellipse(this.majorRadius * 2, this.minorRadius * 2).cx(this.center.tx).cy(this.center.ty).css({
        stroke: this.myColor ? this.myColor : this.color,
        fill: 'transparent',
        'stroke-dasharray': this.dashArray,
        'stroke-width': this.stokeWidth
      }).attr({
        id: this.id
      })
      this.group.add(this.circle)

    }
  }

image.png

polyline的渲染

polyline主要是用path去实现的,要根据点算出path路径,同时结合了原生的polygon闭合属性,可以描述他为多边形或者闭合多边形

polyline的渲染函数如下:

getPathStr() {
    let tmp = ''

    if (this.points.length <= 0) {
      return tmp
    }
    tmp += `M ${this.points[0].tx},${this.points[0].ty} `


    for (let i = 1; i < this.points.length; i++) {
      const point = this.points[i]
      const segType = this.segTypes[i - 1]

      if (segType === PolyLineSegType.arc) {
        const segRadius = this.segRadius[i - 1]
        const largeArcFlag = this.segTotalAngle[i - 1] < Math.PI ? 0 : 1
        const sweepFlag = this.segClockWise[i - 1] ? 1 : 0

        tmp += `A ${segRadius} ${segRadius} `
        tmp += `0 ${largeArcFlag} ${sweepFlag} `
        tmp += `${point.tx} ${point.ty}`
      } else {
        tmp += `L ${point.tx},${point.ty} `
      }
    }
    if (this.closed) {
      const lastIndex = this.points.length - 1
      const segType = this.segTypes[lastIndex]

      if (segType === PolyLineSegType.arc) {
        const segRadius = this.segRadius[lastIndex]
        const largeArcFlag = this.segTotalAngle[lastIndex] < Math.PI ? 0 : 1
        const sweepFlag = this.segClockWise[lastIndex] ? 1 : 0

        tmp += `A ${segRadius} ${segRadius} `
        tmp += `0 ${largeArcFlag} ${sweepFlag} `
        tmp += `${this.points[0].tx} ${this.points[0].ty} `
      }
      tmp += 'z'
    }
    return tmp
  }


  render() {
    if (this.show) {
      this.group = this.draw.group()
      this.polyline ? this.polyline.clear() : ''
      this.polyline = this.draw.path(this.getPathStr()).css({
        stroke: this.myColor ? this.myColor : this.color,
        fill: this.myFillColor ? this.myFillColor : this.fillColor,
        'stroke-dasharray': this.dashArray,
        'stroke-width': this.stokeWidth < 0.01 ? 0.4 : this.stokeWidth
      }).attr({
        id: this.id
      })

      this.group.add(this.polyline)
    }
  }

image.png