我有多条Bezier曲线,它们从上到下延伸并稍微摇摆!如在此CodePen中可以看到的那样,这些曲线似乎按照预期的那样进行动画处理,但是没有按照我的预期进行绘制。如果我增加似乎可以拉伸Beziers的画布的大小,以便在一定高度后看起来还不错,但我无法理解曲线是否都在一个较小的画布高度上被弄皱了,就像在此示例中一样。 下面是我的代码:
function milestoneLines() {
//get all canvases from the DOM
const canvas = document.querySelectorAll('canvas');
console.log(canvas);
//loop through array of canvases
canvas.forEach(makeCanvas);
function makeCanvas(canvas, index) {
// get canvas width/height
canvas.width = $(".main").eq(index).width();
canvas.height = $(".main").eq(index).height();
//getting the height of all milestones
let milestoneHeight = $(".main").eq(index)
.find('.info_wrapper');
let totalMilestoneHeight = 0;
milestoneHeight.each(function() {
totalMilestoneHeight += $(this).outerHeight();
});
const c = canvas.getContext('2d');
let milestoneHalfHeight = totalMilestoneHeight / 2;
let milestoneQuarterHeight = totalMilestoneHeight / 4;
let milestoneHalfWidth = canvas.width / 2;
let bezEndY = $('.main').eq(index).offset().top +
$('.main').eq(index).outerHeight();
let bezStartY = $('.main').eq(index)
.find(".dot").eq(0).offset().top;
// Bezier Curve points
let bezStart = {
x: milestoneHalfWidth,
y: bezStartY
};
let bezCp1 = {
x: milestoneHalfWidth - 35,
y: milestoneHalfHeight
};
let bezCp2 = {
x: milestoneHalfWidth,
y: milestoneHalfHeight + milestoneQuarterHeight
};
let bezEnd = {
x: milestoneHalfWidth,
y: bezEndY
};
//Line 1
//dx = xvelocity
let dx1Line1 = .6;
let dx2Line1 = .6;
let bezCp1Line1x = bezCp1.x;
let bezCp2Line1x = bezCp2.x;
//Line 2
//dx = xvelocity
let dx1Line2 = .8;
let dx2Line2 = .8;
let bezCp1Line2x = bezCp1.x;
let bezCp2Line2x = bezCp2.x;
//Line 3
//dx = xvelocity
let dx1Line3 = 1;
let dx2Line3 = 1;
let bezCp1Line3x = bezCp1.x;
let bezCp2Line3x = bezCp2.x;
//Line 4
//dx = xvelocity
let dx1Line4 = .9;
let dx2Line4 = .9;
let bezCp1Line4x = bezCp1.x;
let bezCp2Line4x = bezCp2.x;
function bezCurve() {
c.clearRect(0, 0, canvas.width, canvas.height);
//different start positions for the bezier curves
let bufferX = 120;
let bufferY = 120;
let bufferStartY = 80;
for (var i = 0; i < 4; i++) {
c.beginPath();
if (i == 0) {
c.moveTo(bezStart.x, bezStart.y + bufferStartY);
c.bezierCurveTo(bezCp1Line1x - bufferX, bezCp1.y - bufferY, bezCp2Line1x + bufferX, bezCp2.y - bufferY, bezEnd.x, bezEnd.y);
if (bezCp1Line1x > (bezCp1.x + 280) || bezCp1Line1x < bezCp1.x) {
dx1Line1 = -dx1Line1;
}
if (bezCp2Line1x < (bezCp2.x - 280) || bezCp2Line1x > bezCp2.x) {
dx2Line1 = -dx2Line1;
}
bezCp1Line1x -= dx1Line1;
bezCp2Line1x += dx2Line1;
c.strokeStyle = "red";
}
if (i == 2) {
c.moveTo(bezStart.x, bezStart.y + bufferStartY);
c.bezierCurveTo(bezCp1Line3x + bufferX, bezCp1.y + bufferY, bezCp2Line3x - bufferX, bezCp2.y + bufferY, bezEnd.x, bezEnd.y);
if (bezCp1Line3x < (bezCp1.x - 320) || bezCp1Line3x > bezCp1.x) {
dx1Line3 = -dx1Line3;
}
if (bezCp2Line3x > (bezCp2.x + 320) || bezCp2Line3x < bezCp2.x) {
dx2Line3 = -dx2Line3;
}
bezCp1Line3x -= dx1Line3;
bezCp2Line3x += dx2Line3;
c.strokeStyle = "green";
}
if (i == 1) {
c.moveTo(bezStart.x, bezStart.y + bufferStartY);
c.bezierCurveTo(bezCp1Line2x + bufferX, bezCp1.y + bufferY, bezCp2Line2x - bufferX, bezCp2.y + bufferY, bezEnd.x, bezEnd.y);
if (bezCp1Line2x < (bezCp1.x - 350) || bezCp1Line2x > bezCp1.x) {
dx1Line2 = -dx1Line2;
}
if (bezCp2Line2x > (bezCp2.x + 350) || bezCp2Line2x < bezCp2.x) {
dx2Line2 = -dx2Line2;
}
bezCp1Line2x -= dx1Line2;
bezCp2Line2x += dx2Line2;
c.strokeStyle = "blue";
}
if (i == 3) {
c.moveTo(bezStart.x, bezStart.y + bufferStartY);
c.bezierCurveTo(bezCp1Line4x - bufferX, bezCp1.y - bufferY, bezCp2Line4x + bufferX, bezCp2.y - bufferY, bezEnd.x, bezEnd.y);
if (bezCp1Line4x > (bezCp1.x + 320) || bezCp1Line4x < bezCp1.x) {
dx1Line4 = -dx1Line4;
}
if (bezCp2Line4x < (bezCp2.x - 320) || bezCp2Line4x > bezCp2.x) {
dx2Line4 = -dx2Line4;
}
bezCp1Line4x -= dx1Line4;
bezCp2Line4x += dx2Line4;
c.strokeStyle = "grey";
}
c.lineWidth = 6;
//c.strokeStyle = "#FCE6DF";
c.stroke();
bufferX = bufferX - 30;
bufferY = bufferY - 30;
bufferStartY = bufferStartY - 20;
}
requestAnimationFrame(bezCurve);
}
bezCurve();
}
}
$(document).ready(milestoneLines);
#milestone_canvas {
position: absolute;
}
.main {
background-color: wheat;
}
.info_wrapper {
margin-top: 70px;
margin-bottom: 50px;
border: solid 2px;
}
.container {
height: 50%;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
}
.dot {
width: 30px;
height: 30px;
border-radius: 20px;
background-color: maroon;
border: solid 4px green;
z-index: 100;
}
.header {
width: 100%;
height: 50px;
background-color: lightblue;
}
.text {
float: left;
position: absolute;
max-width: 500px;
}
<div class="main">
<canvas id="milestone_canvas"> </canvas>
<div class="header"></div>
<div class="container">
<div class="info_wrapper">
<div class="text">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
<div class="dot "></div>
</div>
<div class="info_wrapper">
<div class="text">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
<div class="dot "></div>
</div>
<div class="info_wrapper">
<div class="text">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
<div class="dot "></div>
</div>
<div class="info_wrapper">
<div class="text">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
<div class="dot "></div>
</div>
<div class="info_wrapper">
<div class="text">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
<div class="dot "></div>
</div>
</div>
</div>