|
@@ -3,16 +3,25 @@
|
|
|
class="jigsaw-game"
|
|
|
>
|
|
|
<div class="left-wrapper">
|
|
|
- <div
|
|
|
- @dragover.prevent
|
|
|
- @drop.prevent="onDrop"
|
|
|
- >
|
|
|
+ <div class="object-wrapper">
|
|
|
<object
|
|
|
ref="svgContainer"
|
|
|
:data="require(`@/assets/images/jigsaw-game-${$route.query.sceneL2Idx}/compound.svg`)"
|
|
|
type=""
|
|
|
/>
|
|
|
</div>
|
|
|
+ <div
|
|
|
+ ref="forDrop"
|
|
|
+ class="for-drop"
|
|
|
+ :style="{
|
|
|
+ left: leftForDrop + 'px',
|
|
|
+ top: topForDrop + 'px',
|
|
|
+ width: widthForDrop + 'px',
|
|
|
+ height: heightForDrop + 'px',
|
|
|
+ }"
|
|
|
+ @dragover.prevent
|
|
|
+ @drop.prevent="onDrop"
|
|
|
+ />
|
|
|
</div>
|
|
|
|
|
|
<div class="jigsaw-list">
|
|
@@ -53,10 +62,7 @@
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import { computed, onMounted, reactive, toRefs, ref } from 'vue'
|
|
|
import useWindowSizeAdaptor from '@/useFunctions/useWindowSizeAdaptor.js'
|
|
|
-import { useRoute } from "vue-router"
|
|
|
-import { useStore } from "vuex"
|
|
|
import { ElMessageBox } from 'element-plus'
|
|
|
|
|
|
export default {
|
|
@@ -64,13 +70,6 @@ export default {
|
|
|
setup () {
|
|
|
const { windowSizeWhenDesign, unit } = useWindowSizeAdaptor()
|
|
|
|
|
|
- // const route = useRoute()
|
|
|
- // const store = useStore()
|
|
|
-
|
|
|
- // const jigsawNameList = computed(() => {
|
|
|
- // config.sceneTree[route.query.sceneL2Idx]
|
|
|
- // })
|
|
|
-
|
|
|
return {
|
|
|
windowSizeWhenDesign,
|
|
|
unit
|
|
@@ -78,7 +77,11 @@ export default {
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
- jigsawItemsFlatten: []
|
|
|
+ jigsawItemsFlatten: [],
|
|
|
+ leftForDrop: 0,
|
|
|
+ topForDrop: 0,
|
|
|
+ widthForDrop: 0,
|
|
|
+ heightForDrop: 0,
|
|
|
}
|
|
|
},
|
|
|
computed: {
|
|
@@ -101,8 +104,8 @@ export default {
|
|
|
}
|
|
|
setTimeout(() => {
|
|
|
if (!this.jigsawProgressSceneL2.isJigsawDone) {
|
|
|
- const svgRoot = this.$refs.svgContainer.contentDocument
|
|
|
- const gList = svgRoot.getElementsByTagName('g')
|
|
|
+ const objectDocument = this.$refs.svgContainer.contentDocument
|
|
|
+ const gList = objectDocument.getElementsByTagName('g')
|
|
|
for (let index = 1; index < gList.length; index++) {
|
|
|
const element = gList[index]
|
|
|
element.setAttribute('visibility', 'hidden')
|
|
@@ -117,34 +120,96 @@ export default {
|
|
|
'recordJigsawDone',
|
|
|
]),
|
|
|
onDragStart(e, jigsawImgName, idx) {
|
|
|
- console.log(jigsawImgName) // 1.马路.png
|
|
|
+ // 不知道为啥,在svg内部元素上无法触发drop事件,求助gpt也没用。只好用一个透明方块放在需要能drop的svg内部元素上面。
|
|
|
+
|
|
|
+ // reset for drop
|
|
|
+ this.leftForDrop = 0
|
|
|
+ this.topForDrop = 0
|
|
|
+ this.widthForDrop = 0
|
|
|
+ this.heightForDrop = 0
|
|
|
+
|
|
|
+ // get id
|
|
|
let temp = jigsawImgName.split('.')
|
|
|
temp.pop()
|
|
|
const id = `_${temp.join('.')}-剪影_图像`
|
|
|
- // console.log(id)
|
|
|
- const svgRoot = this.$refs.svgContainer.contentDocument
|
|
|
- svgRoot.getElementById(id).setAttribute('visibility', 'show')
|
|
|
+
|
|
|
+ // get elements
|
|
|
+ const objectDocument = this.$refs.svgContainer.contentDocument
|
|
|
+ const svgEl = objectDocument.getElementsByTagName('svg')[0]
|
|
|
+ const gTarget = objectDocument.getElementById(id)
|
|
|
+ const imgTarget = gTarget.getElementsByTagName('image')[0]
|
|
|
+
|
|
|
+ // get svg original size from viewBox attribute
|
|
|
+ const svgWidth = Number(svgEl.getAttribute('viewBox').split(' ')[2])
|
|
|
+ const svgHeight = Number(svgEl.getAttribute('viewBox').split(' ')[3])
|
|
|
+ console.log('svg original size by viewBox attribute: ', svgWidth, svgHeight)
|
|
|
+
|
|
|
+ // show g element
|
|
|
+ gTarget.setAttribute('visibility', 'show')
|
|
|
+
|
|
|
+ // save drag info
|
|
|
e.dataTransfer.setData('text/plain', jigsawImgName)
|
|
|
- e.dataTransfer.setData('text/html', String(idx))
|
|
|
+ e.dataTransfer.setData('text/html', String(idx)) // 并非真的html类型,只是为了传输数据
|
|
|
+
|
|
|
+ // get image's original size
|
|
|
+ const imageWidthOriginal = Number(imgTarget.getAttribute('width'))
|
|
|
+ const imageHeightOriginal = Number(imgTarget.getAttribute('height'))
|
|
|
+ console.log("image's original size: ", imageWidthOriginal, imageHeightOriginal)
|
|
|
+
|
|
|
+ // get image's original top left from transform attribute
|
|
|
+ let imageLeftOriginal = 0
|
|
|
+ let imageTopOriginal = 0
|
|
|
+ const transformString = imgTarget.getAttribute('transform')
|
|
|
+ if (transformString) {
|
|
|
+ const regForTransform = /translate\((.+)\)/
|
|
|
+ const matchRes = transformString.match(regForTransform)
|
|
|
+ if (matchRes) {
|
|
|
+ imageLeftOriginal = Number(matchRes[1].split(' ')[0])
|
|
|
+ imageTopOriginal = Number(matchRes[1].split(' ')[1]) || 0
|
|
|
+ } else {
|
|
|
+ imageLeftOriginal = 0
|
|
|
+ imageTopOriginal = 0
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ imageLeftOriginal = 0
|
|
|
+ imageTopOriginal = 0
|
|
|
+ }
|
|
|
+ console.log("image's original top left: ", imageLeftOriginal, imageTopOriginal)
|
|
|
+
|
|
|
+ // compute image's actual left top
|
|
|
+ const topLeft = utils.mapPosFromDraftToWindow({
|
|
|
+ x: imageLeftOriginal,
|
|
|
+ y: imageTopOriginal,
|
|
|
+ }, 'cover', svgWidth, svgHeight, this.$refs.svgContainer.clientWidth, this.$refs.svgContainer.clientHeight)
|
|
|
+ console.log("image's actual left top: ", topLeft.x, topLeft.y)
|
|
|
+
|
|
|
+ const rightBottom = utils.mapPosFromDraftToWindow({
|
|
|
+ x: imageLeftOriginal + imageWidthOriginal,
|
|
|
+ y: imageTopOriginal + imageHeightOriginal,
|
|
|
+ }, 'cover', svgWidth, svgHeight, this.$refs.svgContainer.clientWidth, this.$refs.svgContainer.clientHeight)
|
|
|
+ console.log("image's actual right top: ", rightBottom.x, rightBottom.y)
|
|
|
+
|
|
|
+ this.leftForDrop = topLeft.x
|
|
|
+ this.topForDrop = topLeft.y
|
|
|
+ this.widthForDrop = rightBottom.x - topLeft.x
|
|
|
+ this.heightForDrop = rightBottom.y - topLeft.y
|
|
|
+ console.log("image's actual ltwh for render: ", this.leftForDrop, this.topForDrop, this.widthForDrop, this.heightForDrop)
|
|
|
},
|
|
|
onDragEnd(jigsawImgName) {
|
|
|
- // console.log(jigsawImgName) // 1.马路.png
|
|
|
let temp = jigsawImgName.split('.')
|
|
|
temp.pop()
|
|
|
const id = `_${temp.join('.')}-剪影_图像`
|
|
|
- // console.log(id)
|
|
|
- const svgRoot = this.$refs.svgContainer.contentDocument
|
|
|
- svgRoot.getElementById(id).setAttribute('visibility', 'hidden')
|
|
|
+ const objectDocument = this.$refs.svgContainer.contentDocument
|
|
|
+ objectDocument.getElementById(id).setAttribute('visibility', 'hidden')
|
|
|
},
|
|
|
onDrop(e) {
|
|
|
+ e.preventDefault()
|
|
|
let jigsawImgName = e.dataTransfer.getData('text/plain')
|
|
|
- console.log(jigsawImgName)
|
|
|
let temp = jigsawImgName.split('.')
|
|
|
temp.pop()
|
|
|
const id = `_${temp.join('.')}_图像`
|
|
|
- // console.log(id)
|
|
|
- const svgRoot = this.$refs.svgContainer.contentDocument
|
|
|
- svgRoot.getElementById(id).setAttribute('visibility', 'show')
|
|
|
+ const objectDocument = this.$refs.svgContainer.contentDocument
|
|
|
+ objectDocument.getElementById(id).setAttribute('visibility', 'show')
|
|
|
|
|
|
const idx = Number(e.dataTransfer.getData('text/html'))
|
|
|
this.jigsawItemsFlatten[idx].hasPut = true
|
|
@@ -160,7 +225,10 @@ export default {
|
|
|
})
|
|
|
this.recordJigsawDone(Number(this.$route.query.sceneL2Idx))
|
|
|
}
|
|
|
- }
|
|
|
+ },
|
|
|
+ onDragOver(e) {
|
|
|
+ e.preventDefault()
|
|
|
+ },
|
|
|
},
|
|
|
}
|
|
|
</script>
|
|
@@ -188,7 +256,8 @@ export default {
|
|
|
background-position: center center;
|
|
|
margin-right: calc(83 / v-bind('windowSizeWhenDesign') * v-bind('unit'));
|
|
|
padding: calc(15 / v-bind('windowSizeWhenDesign') * v-bind('unit'));
|
|
|
- >div {
|
|
|
+ position: relative;
|
|
|
+ >.object-wrapper {
|
|
|
width: 100%;
|
|
|
height: 100%;
|
|
|
overflow: hidden;
|
|
@@ -197,6 +266,12 @@ export default {
|
|
|
// width: 100%;
|
|
|
}
|
|
|
}
|
|
|
+ >.for-drop {
|
|
|
+ position: absolute;
|
|
|
+ // background-color: red;
|
|
|
+ // opacity: 0.2;
|
|
|
+ z-index: 1;
|
|
|
+ }
|
|
|
}
|
|
|
>.jigsaw-list {
|
|
|
position: relative;
|