Browse Source

测试更新

master
常熟吴彦祖 2 weeks ago
parent
commit
9d3a21bd9b
  1. 2
      src/main.js
  2. 6
      src/store/modules/common.js
  3. 334
      src/utils/clickBloom.js
  4. 1
      src/views/common/login.vue
  5. 7
      src/views/common/theme.vue

2
src/main.js

@ -18,6 +18,7 @@ import decimalUtil from '@/utils/decimalUtil.js'
import getLodop from '@/utils/LodopFuncs.js'
import pdf from 'vue-pdf'
import { debounce,throttle} from '@/utils/common.js'
import { installClickBloom } from '@/utils/clickBloom'
Vue.component('downloadExcel', JsonExcel)
Vue.component('pdf', pdf)
@ -40,6 +41,7 @@ Vue.prototype.throttle = throttle // 限流
// 保存整站vuex本地储存初始状态
window.SITE_CONFIG['storeState'] = cloneDeep(store.state)
installClickBloom(store)
/* eslint-disable no-new */
new Vue({

6
src/store/modules/common.js

@ -16,7 +16,8 @@ export default {
contentIsNeedRefresh: false,
// 主入口标签页
mainTabs: [],
mainTabsActiveName: ''
mainTabsActiveName: '',
clickEffectEnabled: false
},
mutations: {
updateDocumentClientHeight (state, height) {
@ -45,6 +46,9 @@ export default {
},
updateMainTabsActiveName (state, name) {
state.mainTabsActiveName = name
},
updateClickEffectEnabled (state, enabled) {
state.clickEffectEnabled = !!enabled
}
}
}

334
src/utils/clickBloom.js

@ -0,0 +1,334 @@
const EFFECT_MS = 2500
const MAX_BURSTS = 4
let canvas = null
let ctx = null
let bursts = []
let frameId = 0
function ensureCanvas () {
if (canvas) {
return
}
canvas = document.createElement('canvas')
canvas.style.position = 'fixed'
canvas.style.left = '0'
canvas.style.top = '0'
canvas.style.width = '100%'
canvas.style.height = '100%'
canvas.style.pointerEvents = 'none'
canvas.style.zIndex = '10000'
document.body.appendChild(canvas)
ctx = canvas.getContext('2d')
resizeCanvas()
window.addEventListener('resize', resizeCanvas)
}
function resizeCanvas () {
if (!canvas) {
return
}
const ratio = window.devicePixelRatio || 1
canvas.width = Math.floor(window.innerWidth * ratio)
canvas.height = Math.floor(window.innerHeight * ratio)
if (ctx) {
ctx.setTransform(ratio, 0, 0, ratio, 0, 0)
}
}
function removeCanvas () {
if (frameId) {
cancelAnimationFrame(frameId)
frameId = 0
}
window.removeEventListener('resize', resizeCanvas)
if (canvas && canvas.parentNode) {
canvas.parentNode.removeChild(canvas)
}
canvas = null
ctx = null
bursts = []
}
function farthestScreenDistance (x, y) {
const width = window.innerWidth
const height = window.innerHeight
const corners = [[0, 0], [width, 0], [0, height], [width, height]]
let maxDistance = 0
corners.forEach(function (corner) {
const dx = corner[0] - x
const dy = corner[1] - y
const distance = Math.sqrt(dx * dx + dy * dy)
if (distance > maxDistance) {
maxDistance = distance
}
})
return maxDistance + 48
}
function createBurst (x, y) {
const reach = farthestScreenDistance(x, y)
const particles = []
const particleCount = 46
for (let i = 0; i < particleCount; i++) {
const angle = Math.random() * Math.PI * 2
particles.push({
angle: angle,
speed: reach * (0.72 + Math.random() * 0.38),
size: 2.2 + Math.random() * 3.6
})
}
const bolts = []
const boltCount = 18
for (let i = 0; i < boltCount; i++) {
const angle = (Math.PI * 2 * i) / boltCount + (Math.random() - 0.5) * 0.28
const length = reach * (0.92 + Math.random() * 0.16)
const segments = 16
const points = [{ x: x, y: y }]
for (let s = 1; s <= segments; s++) {
const ratio = s / segments
const dist = length * ratio
const sway = (Math.random() - 0.5) * 54 * (1 - ratio * 0.25)
points.push({
x: x + Math.cos(angle) * dist + Math.cos(angle + Math.PI / 2) * sway,
y: y + Math.sin(angle) * dist + Math.sin(angle + Math.PI / 2) * sway
})
}
bolts.push({ points: points })
}
const stars = []
const starCount = 200
for (let i = 0; i < starCount; i++) {
stars.push({
x: Math.random() * window.innerWidth,
y: Math.random() * window.innerHeight,
size: 1.4 + Math.random() * 6.2,
phase: Math.random() * Math.PI * 2,
blinks: 3 + Math.floor(Math.random() * 4),
gold: i % 2 === 0
})
}
return {
x: x,
y: y,
reach: reach,
start: performance.now(),
particles: particles,
bolts: bolts,
stars: stars
}
}
function pointOnBolt (points, t) {
const clamped = Math.max(0, Math.min(1, t))
const scaled = clamped * (points.length - 1)
const index = Math.floor(scaled)
const next = Math.min(index + 1, points.length - 1)
const mix = scaled - index
return {
x: points[index].x + (points[next].x - points[index].x) * mix,
y: points[index].y + (points[next].y - points[index].y) * mix
}
}
function drawBolt (bolt, progress) {
const travel = Math.min(1, progress / 0.42)
const head = travel
const tail = Math.max(0, head - 0.16)
if (head <= tail) {
return
}
const steps = 10
ctx.beginPath()
const start = pointOnBolt(bolt.points, tail)
ctx.moveTo(start.x, start.y)
for (let step = 1; step <= steps; step++) {
const point = pointOnBolt(bolt.points, tail + (head - tail) * (step / steps))
ctx.lineTo(point.x, point.y)
}
const tipFade = travel < 1 ? 1 : Math.max(0, 1 - (progress - 0.42) / 0.58)
ctx.save()
ctx.globalAlpha = tipFade
ctx.lineCap = 'round'
ctx.lineJoin = 'round'
ctx.strokeStyle = 'rgba(70, 225, 255, 0.95)'
ctx.lineWidth = 5.5
ctx.shadowColor = 'rgba(0, 200, 255, 1)'
ctx.shadowBlur = 18
ctx.stroke()
ctx.shadowBlur = 0
ctx.strokeStyle = 'rgba(255, 255, 255, 0.98)'
ctx.lineWidth = 1.7
ctx.stroke()
ctx.restore()
}
function drawSeismicWave (burst, progress) {
const delays = [0, 0.1, 0.2]
delays.forEach(function (delay, index) {
const span = 1 - delay
const local = (progress - delay) / span
if (local <= 0 || local > 1) {
return
}
const eased = 1 - Math.pow(1 - local, 2)
const radius = 28 + eased * (burst.reach + index * 36)
const alpha = (1 - local) * 0.42
const steps = 80
ctx.save()
ctx.beginPath()
for (let i = 0; i <= steps; i++) {
const angle = (Math.PI * 2 * i) / steps
const wobble = 1 + Math.sin(angle * 7 + index * 1.4) * 0.04
const pointX = burst.x + Math.cos(angle) * radius * wobble
const pointY = burst.y + Math.sin(angle) * radius * wobble
if (i === 0) {
ctx.moveTo(pointX, pointY)
} else {
ctx.lineTo(pointX, pointY)
}
}
ctx.closePath()
ctx.lineWidth = 10 * (1 - local * 0.55)
ctx.strokeStyle = 'rgba(190, 245, 255, ' + alpha + ')'
ctx.shadowColor = 'rgba(140, 230, 255, ' + alpha + ')'
ctx.shadowBlur = 14
ctx.stroke()
ctx.restore()
})
}
function drawDiamond (x, y, size, alpha) {
if (alpha <= 0.02) {
return
}
ctx.save()
ctx.translate(x, y)
ctx.rotate(Math.PI / 4)
ctx.fillStyle = 'rgba(176, 232, 255, ' + alpha + ')'
ctx.fillRect(-size, -size, size * 2, size * 2)
ctx.fillStyle = 'rgba(255, 255, 255, ' + alpha + ')'
ctx.fillRect(-size * 0.38, -size * 0.38, size * 0.76, size * 0.76)
ctx.restore()
}
function drawScreenStars (burst, progress) {
const fade = 0.45 + (1 - progress) * 0.55
burst.stars.forEach(function (star) {
const twinkle = Math.abs(Math.sin(progress * Math.PI * star.blinks + star.phase))
if (twinkle < 0.12) {
return
}
const alpha = fade * twinkle
ctx.save()
ctx.translate(star.x, star.y)
ctx.rotate(Math.PI / 4)
ctx.fillStyle = star.gold ? 'rgba(255, 230, 0, ' + alpha + ')' : 'rgba(0, 245, 255, ' + alpha + ')'
ctx.fillRect(-star.size, -star.size, star.size * 2, star.size * 2)
ctx.restore()
})
}
function drawWaveDiamonds (burst, progress) {
const delays = [0, 0.1, 0.2]
delays.forEach(function (delay, index) {
const span = 1 - delay
const local = (progress - delay) / span
if (local <= 0 || local > 1) {
return
}
const eased = 1 - Math.pow(1 - local, 2)
const radius = 28 + eased * (burst.reach + index * 36)
const alpha = (1 - local) * 0.9
const count = 26
for (let i = 0; i < count; i++) {
const angle = (Math.PI * 2 * i) / count + progress * 0.6 + index
const wobble = 1 + Math.sin(angle * 7 + index * 1.4) * 0.04
drawDiamond(
burst.x + Math.cos(angle) * radius * wobble,
burst.y + Math.sin(angle) * radius * wobble,
2.2 + (i % 3) * 0.7,
alpha
)
}
})
}
function drawBurst (burst, now) {
const progress = Math.min(1, (now - burst.start) / EFFECT_MS)
const fade = 1 - progress
drawSeismicWave(burst, progress)
drawWaveDiamonds(burst, progress)
drawScreenStars(burst, progress)
burst.particles.forEach(function (particle) {
const dist = particle.speed * progress
const px = burst.x + Math.cos(particle.angle) * dist
const py = burst.y + Math.sin(particle.angle) * dist
const radius = particle.size * (1 - progress * 0.25)
ctx.save()
ctx.beginPath()
ctx.fillStyle = 'rgba(214, 224, 236, ' + fade + ')'
ctx.shadowColor = 'rgba(236, 244, 255, ' + fade + ')'
ctx.shadowBlur = 16
ctx.arc(px, py, radius * 2.1, 0, Math.PI * 2)
ctx.fill()
ctx.shadowBlur = 0
ctx.beginPath()
ctx.fillStyle = 'rgba(120, 230, 255, ' + fade + ')'
ctx.arc(px, py, radius * 0.72, 0, Math.PI * 2)
ctx.fill()
ctx.restore()
})
burst.bolts.forEach(function (bolt) {
drawBolt(bolt, progress)
})
return progress < 1
}
function render (now) {
if (!ctx || !canvas) {
frameId = 0
return
}
ctx.clearRect(0, 0, window.innerWidth, window.innerHeight)
const alive = []
bursts.forEach(function (burst) {
if (drawBurst(burst, now)) {
alive.push(burst)
}
})
bursts = alive
if (bursts.length === 0) {
removeCanvas()
return
}
frameId = requestAnimationFrame(render)
}
function spawn (x, y) {
ensureCanvas()
bursts.push(createBurst(x, y))
if (bursts.length > MAX_BURSTS) {
bursts.splice(0, bursts.length - MAX_BURSTS)
}
if (!frameId) {
frameId = requestAnimationFrame(render)
}
}
export function installClickBloom (store) {
if (!store || window.__wmsClickBloomInstalled) {
return
}
window.__wmsClickBloomInstalled = true
document.addEventListener('mousedown', function (event) {
const enabled = store.state && store.state.common && store.state.common.clickEffectEnabled
if (!enabled || event.button !== 0) {
if (!enabled) {
removeCanvas()
}
return
}
spawn(event.clientX, event.clientY)
}, true)
}

1
src/views/common/login.vue

@ -241,6 +241,7 @@
localStorage.setItem('site', this.selectedSite) // 保存选择的工厂
// 登录后立即回写store.user.site,保证菜单拉取前可读取当前工厂 - rqrq
this.$store.commit('user/updateSite', this.selectedSite)
this.$store.commit('common/updateClickEffectEnabled', false)
this.getConfigParams()
this.cacheUserAuthorizedSubSiteCodes(this.dataForm.userName, this.selectedSite).finally(() => {

7
src/views/common/theme.vue

@ -13,6 +13,9 @@
<el-radio label="dark" border>dark</el-radio>
</el-radio-group>
</el-form-item>
<!-- <el-form-item label="动感特效">----纯测试 别打开 别好奇----- -->
<!-- <el-switch v-model="clickEffectEnabled" active-text="开" inactive-text="关"></el-switch>-->
<!-- </el-form-item>-->
</el-form>
</template>
@ -26,6 +29,10 @@
sidebarLayoutSkin: {
get () { return this.$store.state.common.sidebarLayoutSkin },
set (val) { this.$store.commit('common/updateSidebarLayoutSkin', val) }
},
clickEffectEnabled: {
get () { return this.$store.state.common.clickEffectEnabled },
set (val) { this.$store.commit('common/updateClickEffectEnabled', val) }
}
}
}

Loading…
Cancel
Save