123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- import {CADElementTS, CADElement} from '../core/element'
- import {SVGURI} from '../constant/Element'
- import {ProcessingTS} from './processing/index'
- export type Screen = {x: number, y: number}
- interface RendererProps {
- layer: HTMLElement,
- width?: number,
- height?: number,
- processing: ProcessingTS
- }
- class Renderer {
- svg: SVGSVGElement
- g: SVGGElement
- layer: HTMLElement
- elements: Array<CADElementTS>
- processing: ProcessingTS
- props: {
- left: number;
- top: number;
- width: number;
- height: number,
- multiple: number,
- scale: number
- }
- realWidth: number
- realHeight: number
- constructor({layer, width = layer.offsetWidth, height = layer.offsetHeight, processing}: RendererProps) {
- CADElement.init(this)
- this.props = {left: 0, top: 0, width, height, multiple: 1, scale: 1}
- this.elements = []
- this.processing = processing
- this.init(layer)
- }
- private clickHandle = () => {
- this.elements.forEach(e => e.changeSelect(false))
- }
-
- private init(layer) {
- this.svg = document.createElementNS(SVGURI, 'svg')
- this.g = document.createElementNS(SVGURI, 'g')
- this.svg.appendChild(this.g)
- this.layer = layer
- this.layer.style.position = 'relative'
- this.svg.style.position = 'absolute'
- this.svg.style.left = '0'
- this.svg.style.top = '0'
- this.svg.style.right = '0'
- this.svg.style.bottom = '0'
- this.svg.setAttribute('version', '1.0')
- this.svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg')
- this.svg.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink')
- this.svg.addEventListener('click', this.clickHandle, false)
- this.layer.appendChild(this.svg)
- }
- adaptLayer(width = this.layer.offsetWidth, height = this.layer.offsetHeight) {
-
- let centerStepX = this.props.width / 2 - this.props.left
- let centerStepY = this.props.height / 2 - this.props.top
- this.g.setAttribute('transform', `
- translate(${this.props.left},${this.props.top})
- translate(${centerStepX},${centerStepY})
- scale(${this.props.scale},${this.props.scale})
- translate(${-centerStepX},${-centerStepY})
- `)
- this.svg.setAttribute('width', width.toString())
- this.svg.setAttribute('height', height.toString())
- this.svg.setAttribute('viewBox', `0 0 ${this.props.width} ${this.props.height}`)
- this.realWidth = width
- this.realHeight = height
- CADElement.update(this)
- }
- render() {
- CADElement.update(this)
- }
-
- // dom坐标转换为真实坐标
- screenToRealPoint({x, y}: Screen) {
- let centerStepX = this.props.width / 2 - this.props.left
- let centerStepY = this.props.height / 2 - this.props.top
- let width = this.props.width / this.props.multiple
- let height = this.props.height / this.props.multiple
- if(width == 0 || height == 0){
- return{
- x:centerStepX,
- y:centerStepY
- };
- }
- else{
- return {
- x: ((x * this.props.width) / width - this.props.left - centerStepX) / this.props.scale + centerStepX,
- y: ((y * this.props.height) / height - this.props.top - centerStepY) / this.props.scale + centerStepY
- }
- }
- }
- // 点坐标转换真实坐标
- realPointToScreen({x, y}: Screen) {
- let centerStepX = this.props.width / 2 - this.props.left
- let centerStepY = this.props.height / 2 - this.props.top
- let width = this.props.width / this.props.multiple
- let height = this.props.height / this.props.multiple
- return {
- x: ((x - centerStepX) * this.props.scale + centerStepX + this.props.left) * width / this.props.width,
- y: ((y - centerStepY) * this.props.scale + centerStepY + this.props.top) * height / this.props.height
- }
- }
- push (...elements: Array<CADElementTS>) {
- elements.forEach(element => {
- let prevEle = this.elements.find(ele => ele.zIndex > element.zIndex)
-
- if (prevEle) {
- try {
- this.g.insertBefore(element.real, prevEle.real)
- } catch(e) {
- this.g.appendChild(element.real)
- }
- this.elements.splice(this.elements.indexOf(prevEle), 0, element)
- } else {
- this.g.appendChild(element.real)
- this.elements.push(element)
- }
- })
- }
- remove (...elements: Array<CADElementTS>) {
- elements.forEach(element => {
- try {
- this.g.removeChild(element.real)
- } catch(e) {
- }
- ~this.elements.indexOf(element) && this.elements.splice(this.elements.indexOf(element), 1)
- })
- }
- destroy() {
- this.svg.removeEventListener('click', this.clickHandle, false)
- this.layer.removeChild(this.svg)
- }
- }
- export default Renderer
|