vue实现管道流动
Vue 实现管道流动效果
在 Vue 中实现管道流动效果可以通过 CSS 动画和动态数据绑定结合完成。以下是几种常见方法:
方法一:使用 CSS 动画和 SVG
创建 SVG 路径表示管道,通过 stroke-dashoffset 实现流动动画效果:
<template>
<svg width="200" height="100">
<path
d="M10,50 Q100,10 190,50"
stroke="#3498db"
stroke-width="4"
fill="none"
ref="pipePath"
/>
<circle
cx="10"
cy="50"
r="5"
fill="#e74c3c"
:style="flowStyle"
/>
</svg>
</template>
<script>
export default {
data() {
return {
position: 0,
pathLength: 0
}
},
mounted() {
this.pathLength = this.$refs.pipePath.getTotalLength()
this.animateFlow()
},
computed: {
flowStyle() {
const point = this.$refs.pipePath.getPointAtLength(this.position)
return {
transform: `translate(${point.x - 5}px, ${point.y - 5}px)`,
transition: 'transform 0.1s linear'
}
}
},
methods: {
animateFlow() {
if (this.position < this.pathLength) {
this.position += 2
requestAnimationFrame(this.animateFlow)
} else {
this.position = 0
setTimeout(this.animateFlow, 500)
}
}
}
}
</script>
方法二:纯 CSS 动画实现
利用伪元素和 CSS 关键帧动画创建流动效果:
<template>
<div class="pipe-container">
<div class="pipe"></div>
</div>
</template>
<style>
.pipe-container {
width: 200px;
height: 20px;
position: relative;
overflow: hidden;
}
.pipe {
width: 100%;
height: 100%;
background: #3498db;
position: relative;
}
.pipe::after {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg,
transparent,
rgba(255,255,255,0.5),
transparent);
animation: flow 2s linear infinite;
}
@keyframes flow {
0% { left: -100%; }
100% { left: 100%; }
}
</style>
方法三:结合 Canvas 和 Vue
对于更复杂的流动效果,可以使用 Canvas 绘制:
<template>
<canvas ref="pipeCanvas" width="300" height="100"></canvas>
</template>
<script>
export default {
mounted() {
const canvas = this.$refs.pipeCanvas
const ctx = canvas.getContext('2d')
let progress = 0
const drawPipe = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height)
// 绘制管道
ctx.beginPath()
ctx.moveTo(20, 50)
ctx.bezierCurveTo(100, 10, 200, 90, 280, 50)
ctx.strokeStyle = '#3498db'
ctx.lineWidth = 8
ctx.stroke()
// 绘制流动点
const t = progress / 100
const x = 20 + (280-20) * t
const y = 50 + (50-50) * t
ctx.beginPath()
ctx.arc(x, y, 6, 0, Math.PI * 2)
ctx.fillStyle = '#e74c3c'
ctx.fill()
progress = (progress + 1) % 100
requestAnimationFrame(drawPipe)
}
drawPipe()
}
}
</script>
方法四:使用第三方库
对于复杂管道系统,可以考虑使用 D3.js 或 Three.js:
<template>
<div ref="pipeContainer"></div>
</template>
<script>
import * as d3 from 'd3'
export default {
mounted() {
const svg = d3.select(this.$refs.pipeContainer)
.append('svg')
.attr('width', 300)
.attr('height', 100)
const path = svg.append('path')
.attr('d', 'M20,50 C100,10 200,90 280,50')
.attr('stroke', '#3498db')
.attr('stroke-width', 4)
.attr('fill', 'none')
const circle = svg.append('circle')
.attr('r', 5)
.attr('fill', '#e74c3c')
const pathLength = path.node().getTotalLength()
let position = 0
const animate = () => {
position = (position + 2) % pathLength
const point = path.node().getPointAtLength(position)
circle.attr('cx', point.x).attr('cy', point.y)
requestAnimationFrame(animate)
}
animate()
}
}
</script>
以上方法可根据实际需求选择,简单流动效果推荐 CSS 动画,复杂路径推荐 SVG 或 Canvas 方案。







