首先看一下这个脚本并运行它。
let element = document.querySelector('.side-canvas')
let w = element.offsetWidth;
let h = element.offsetHeight;
const config = {
startPositionX: 50,
startPositionY: 100,
ease: Elastic.easeOut,
count: 4,
distance: 90,
radius: 10,
fall: 100
}
let renderer = PIXI.autoDetectRenderer(w, h,
{antialias: true, transparent: true}
);
element.appendChild(renderer.view);
renderer.view.style.position = "absolute";
renderer.view.style.display = "block";
renderer.autoResize = true;
renderer.resize(w, h);
let stage = new PIXI.Container();
stage.interactive = true;
let line = []
let lineData = {
id: 0,
x1: 0,
x2: 0,
y1: 0,
y2: 0
}
let drawLine = function () {
console.log(lineData)
if (line[lineData.id]) {
line[lineData.id].clear()
}
line[lineData.id] = new PIXI.Graphics();
line[lineData.id].interactive = true
line[lineData.id].position.set(config.startPositionX, config.startPositionY);
line[lineData.id].lineStyle(1, 0xf44336);
line[lineData.id].moveTo(lineData.x1, lineData.y1);
line[lineData.id].lineTo(lineData.x2, lineData.y2);
stage.addChild(line[lineData.id]);
line[lineData.id].lineData = lineData
}
for (let j = 0; j < config.count - 1; j++) {
lineData = {
id: j,
x1: j * config.distance,
x2: (j + 1) * config.distance,
y1: 0,
y2: 0
}
drawLine()
}
let circle = []
let rect = []
for (let i = 0; i < config.count; i++) {
rect[i] = new PIXI.Graphics();
rect[i].interactive = true;
rect[i].lineStyle(1, '#000');
rect[i].beginFill(0xFF00FF, 0.1);
rect[i].drawRect(-config.startPositionX, -config.distance / 2, config.distance, config.distance);
rect[i].endFill();
rect[i].x = config.startPositionX + i * config.distance;
rect[i].y = config.startPositionY;
rect[i]['which'] = i;
stage.addChild(rect[i]);
circle[i] = new PIXI.Graphics();
circle[i].interactive = true;
circle[i].lineStyle(0);
circle[i].beginFill('#000000', 1);
circle[i].drawCircle(0, 0, config.radius);
circle[i].endFill();
circle[i].x = config.startPositionX + i * config.distance;
circle[i].y = config.startPositionY;
circle[i]['which'] = i;
stage.addChild(circle[i]);
rect[i]
.on('mouseover', onHover)
.on('mouseout', onLeave);
}
let actionDone = false
function onHover(e) {
actionDone = false
const backX = this.position.x;
const backY = 100;
TweenMax.to(circle[this.which], 0.9, {pixi: {x: backX, y: backY + config.fall}, ease: config.ease})
if (line[this.which - 1]) {
lineData = line[this.which - 1].lineData
TweenMax.to(lineData, 0.9, {
y2: config.fall,
onUpdate: drawLine,
ease: config.ease
})
}
if (line[this.which]) {
}
setTimeout(function () {
actionDone = true
}, 300)
}
function onLeave(e) {
// this.data = e.data;
const backX = this.position.x;
const backY = config.startPositionY;
let tl = new TimelineMax({repeat: 0, repeatDelay: 0, delay: 0, yoyo: false});
tl.to(circle[this.which], 0.9, {pixi: {x: backX, y: backY}, ease: config.ease}, "+=0")
if (line[this.which - 1]) {
lineData = line[this.which - 1].lineData
let tl2 = new TimelineMax({repeat: 0, repeatDelay: 0, delay: 0, yoyo: false});
tl2.to(lineData, 0.9, {
y2: 0,
onUpdate: drawLine,
ease: config.ease
}, "+=0")
}
}
animate();
function animate() {
renderer.render(stage);
requestAnimationFrame(animate);
}
&#13;
.side-canvas {
position: relative;
margin:0 auto;
width: 364px;
height: 600px;
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/TimelineMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/plugins/PixiPlugin.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/easing/EasePack.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.2/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.5.6/pixi.min.js"></script>
<div class="side-canvas"></div>
&#13;
有人可以为这个悬停动画提供重构,以便正确播放吗?
红色行应该回到起点!
我怎样才能为两个元素添加动画效果?
有没有办法让功能更好?
有没有外部库动画画布元素的原生方式?
提前谢谢你。