feat: 同步长江大学的风采墙优化

This commit is contained in:
2026-10-21 15:23:13 +08:00
parent 88d624172c
commit b19996f57e
15 changed files with 2383 additions and 756 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 714 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB

@@ -0,0 +1,152 @@
Vue.component("spread-back-button", {
template: `<div
class="float-btn"
:class="{ 'is-dragging': dragging }"
:style="{ left: x + 'px', top: y + 'px' }"
@mousedown="startDrag"
@touchstart="startDrag"
@click="handleClick"
>
<!-- 外发光 -->
<div class="glow-ring"></div>
<!-- 点击涟漪 -->
<span
v-for="r in ripples"
:key="r.id"
class="ripple"
:style="{ left: r.x + 'px', top: r.y + 'px' }"
></span>
<!-- 图标 -->
<div class="icon-wrap">
<van-icon name="share-o" size="28" class="flip-icon" ></van-icon>
</div>
</div>`,
props: {
path: {
type: String,
default: '/platform/h5/home'
}
},
data() {
return {
x: 20,
y: 200,
dragging: false,
offsetX: 0,
offsetY: 0,
startX: 0,
startY: 0,
moved: false,
ripples: [],
rippleId: 0
}
},
mounted() {
const pos = localStorage.getItem("float-btn-pos")
if (pos) {
const { x, y } = JSON.parse(pos)
this.x = x
this.y = y
}
window.addEventListener("mousemove", this.onDrag)
window.addEventListener("mouseup", this.endDrag)
window.addEventListener("touchmove", this.onDrag, { passive: false })
window.addEventListener("touchend", this.endDrag)
},
beforeDestroy() {
window.removeEventListener("mousemove", this.onDrag)
window.removeEventListener("mouseup", this.endDrag)
window.removeEventListener("touchmove", this.onDrag)
window.removeEventListener("touchend", this.endDrag)
},
methods: {
startDrag(e) {
const point = e.touches ? e.touches[0] : e
this.dragging = true
this.moved = false
this.startX = point.clientX
this.startY = point.clientY
this.offsetX = point.clientX - this.x
this.offsetY = point.clientY - this.y
},
onDrag(e) {
if (!this.dragging) return
if (e.cancelable) e.preventDefault()
const point = e.touches ? e.touches[0] : e
let newX = point.clientX - this.offsetX
let newY = point.clientY - this.offsetY
const btnSize = 54
const maxX = window.innerWidth - btnSize
const maxY = window.innerHeight - btnSize
this.x = Math.max(0, Math.min(newX, maxX))
this.y = Math.max(0, Math.min(newY, maxY))
const dx = Math.abs(point.clientX - this.startX)
const dy = Math.abs(point.clientY - this.startY)
if (dx > 5 || dy > 5) {
this.moved = true
}
},
endDrag() {
if (!this.dragging) return
this.dragging = false
localStorage.setItem(
"float-btn-pos",
JSON.stringify({
x: this.x,
y: this.y
})
)
},
handleClick(e) {
if (this.moved) return
const point = e.changedTouches ? e.changedTouches[0] : e
const rect = this.$el.getBoundingClientRect()
const id = this.rippleId++
this.ripples.push({
id,
x: point.clientX - rect.left,
y: point.clientY - rect.top
})
setTimeout(() => {
this.ripples = this.ripples.filter(r => r.id !== id)
}, 600)
if (this.path === '-1') {
window.history.back()
} else {
this.$pjaxReplace(this.path)
}
}
}
})