Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The generation of adsorption reference lines through multi-element dragging is very slow #1803

Open
ruxinzhang789 opened this issue Aug 6, 2024 · 1 comment

Comments

@ruxinzhang789
Copy link

ruxinzhang789 commented Aug 6, 2024

Demo from the official website used,There are 100 elements,use vue-konva,
https://konvajs.org/docs/sandbox/Objects_Snapping.html

<v-stage
id="stagecontent"
ref="stage"
:config="stageSize"
@mousedown="handleStageMouseDown"
@mouseup="handleStageMouseUp"
@touchstart="handleStageMouseDown"
@mousemove="handleStageDrag"
@mouseleave="handleStageMouseUp"
>






<v-rect
v-if="layer.type === 'rect'"
:key="layer.name"
:config="layer"
@transformend="handleElementTransformEnd($event, 'rect')"
@Dragend="handleElementDragEnd($event, 'rect')"
@dragmove="handleElementDragMove($event)"
@Transform="handleElementTransform($event, 'rect')"
/>
<v-text
v-if="layer.type === 'text'"
:key="layer.name"
:config="layer"
@Transform="onTextureTransform"
@DBLClick="onTextureDoubleClicked"
@Dragend="handleElementDragEnd($event, 'text')"
@transformend="handleElementTransformEnd($event, 'text')"
@dragmove="handleElementDragMove($event)"
/>
<v-image
v-if="layer.type === 'image'"
:key="layer.name"
:config="layer"
@transformend="handleElementTransformEnd($event, 'image')"
@Dragend="handleElementDragEnd($event, 'image')"
@dragmove="handleElementDragMove($event)"
@Transform="handleElementTransform($event, 'image')"
/>
<ComputerItem
v-if="layer.type === 'computer'"
:key="layer.name + time"
:config="layer"
:pcInfo="pcInfo"
@custom-dragend="handleElementDragEnd($event, 'computer')"
@custom-transformed="
handleElementTransformEnd($event, 'computer')
"
@custom-dblclicked="onTextureDoubleClicked"
@custom-dragmove="handleElementDragMove($event)"
/>
<StatisticsCom
v-if="layer.type === 'statistic'"
:key="layer.name"
:config="layer"
:statisticsData="statisticsData"
@custom-dragend="handleElementDragEnd($event, 'statistic')"
@custom-transformed="
handleElementTransformEnd($event, 'statistic')
"
@custom-dragmove="handleElementDragMove($event)"
/>
<TableWidget
v-if="layer.type === 'table'"
:key="layer.name"
:config="layer"
@custom-dragend="handleElementDragEnd($event, 'table')"
@custom-transformed="
handleElementTransformEnd($event, 'table')
"
@custom-dragmove="handleElementDragMove($event)"
/>




` handleElementDragMove(e) {
const stage = this.$refs.stage.getNode()
stage.container().style.cursor = 'move'
const layer = this.$refs.layer.getNode()
layer.find('.guid-line').forEach(l => l.destroy())
let lineGuideStops = this.getLineGuideStops(e.target)
let itemBounds = this.getObjectSnappingEdges(e.target)
let guides = this.getGuides(lineGuideStops, itemBounds)
if (!guides.length) {
return
}
this.drawGuides(guides)
let absPos = e.target.absolutePosition()
guides.forEach(lg => {
switch (lg.orientation) {
case 'V': {
absPos.x = lg.lineGuide + lg.offset
break
}
case 'H': {
absPos.y = lg.lineGuide + lg.offset
break
}
}
})
e.target.absolutePosition(absPos)
}

getLineGuideStops(skipShape) {
const transformerNode = this.$refs.transformer.getNode()
const stage = transformerNode.getStage()
var vertical = [0, stage.width() / 2, stage.width()]
var horizontal = [0, stage.height() / 2, stage.height()]
const filterList = this.layers.filter(item => {
return !this.selectedShapeName.includes(item.name)
})
const filterNode = filterList.map(item => {
return stage.findOne('.' + item.name)
})
filterNode.forEach(guideItem => {
// if (guideItem === skipShape) {
// return
// }
var box = guideItem.getClientRect()
vertical.push([box.x, box.x + box.width, box.x + box.width / 2])
horizontal.push([box.y, box.y + box.height, box.y + box.height / 2])
})
return {
vertical: [...new Set(vertical.flat())],
horizontal: [...new Set(horizontal.flat())]
}
},

getObjectSnappingEdges(node) {
  var box = node.getClientRect()
  var absPos = node.absolutePosition()
  return {
    vertical: [
      {
        guide: Math.round(box.x),
        offset: Math.round(absPos.x - box.x),
        snap: 'start'
      },
      {
        guide: Math.round(box.x + box.width / 2),
        offset: Math.round(absPos.x - box.x - box.width / 2),
        snap: 'center'
      },
      {
        guide: Math.round(box.x + box.width),
        offset: Math.round(absPos.x - box.x - box.width),
        snap: 'end'
      }
    ],
    horizontal: [
      {
        guide: Math.round(box.y),
        offset: Math.round(absPos.y - box.y),
        snap: 'start'
      },
      {
        guide: Math.round(box.y + box.height / 2),
        offset: Math.round(absPos.y - box.y - box.height / 2),
        snap: 'center'
      },
      {
        guide: Math.round(box.y + box.height),
        offset: Math.round(absPos.y - box.y - box.height),
        snap: 'end'
      }
    ]
  }
},

getGuides(lineGuideStops, itemBounds) {
  var resultV = []
  var resultH = []
  
  lineGuideStops.vertical.forEach(lineGuide => {
    itemBounds.vertical.forEach(itemBound => {
      var diff = Math.abs(lineGuide - itemBound.guide)
      if (diff < 5) {
        resultV.push({
          lineGuide: lineGuide,
          diff: diff,
          snap: itemBound.snap,
          offset: itemBound.offset
        })
      }
    })
  })

  lineGuideStops.horizontal.forEach(lineGuide => {
    itemBounds.horizontal.forEach(itemBound => {
      var diff = Math.abs(lineGuide - itemBound.guide)
      if (diff < 5) {
        resultH.push({
          lineGuide: lineGuide,
          diff: diff,
          snap: itemBound.snap,
          offset: itemBound.offset
        })
      }
    })
  })
  var guides = []
  var minV = resultV.sort((a, b) => a.diff - b.diff)[0]
  var minH = resultH.sort((a, b) => a.diff - b.diff)[0]
  if (minV) {
    guides.push({
      lineGuide: minV.lineGuide,
      offset: minV.offset,
      orientation: 'V',
      snap: minV.snap
    })
  }
  if (minH) {
    guides.push({
      lineGuide: minH.lineGuide,
      offset: minH.offset,
      orientation: 'H',
      snap: minH.snap
    })
  }
  return guides
},

drawGuides(guides) {
  const layer = this.$refs.layer.getNode()
  guides.forEach(lg => {
    if (lg.orientation === 'H') {
      var line = new Konva.Line({
        points: [-6000, 0, 6000, 0],
        stroke: 'rgb(0, 161, 255)',
        strokeWidth: 1,
        name: 'guid-line',
        dash: [4, 6]
      })
      layer.add(line)
      line.absolutePosition({
        x: 0,
        y: lg.lineGuide
      })
    } else if (lg.orientation === 'V') {
      let line = new Konva.Line({
        points: [0, -6000, 0, 6000],
        stroke: 'rgb(0, 161, 255)',
        strokeWidth: 1,
        name: 'guid-line',
        dash: [4, 6]
      })
      layer.add(line)
      line.absolutePosition({
        x: lg.lineGuide,
        y: 0
      })
    }
  })
},`
@lavrton
Copy link
Member

lavrton commented Aug 6, 2024

Demo?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
2 participants