我可以控制段的车把的平滑处理吗?
Can I control how smooth handles the handlebar of a segment?
我现在是第一次使用 Paper.js,我正在处理一个有 fluid/waving 个边的黄色立方体。我想要的是像这样的立方波的边:
http://paperjs.org/tutorials/animation/creating-animations/#animating-path-segments
但是我想要固定立方体的角。我快到了,但我遇到了一个问题段 1(左上角是 [0])表现得很奇怪。把手是对角线的,不像其他把手是水平的。
我该如何解决这个问题?
我现在的草图可以找到here。
完整代码为
var values = {
margin: 64,
header: 132,
height: 60,
amount: 5
};
var path, springs;
function createPath(strength) {
var size = view.size;
var blockSize = {
width: size.width - values.margin,
height: size.height - values.header,
segmentX: (size.width - values.margin)/(values.amount + 1),
segmentY: (size.height - values.header)/(values.amount + 1)
};
var blockPosition = {
top: size.height - blockSize.height,
left: 0
}
var path = new Path({
fillColor: 'yellow'
});
for (var i = 0; i <= values.amount; i++) {
//top
path.add(new Point((blockPosition.left + (blockSize.segmentX * i)), blockPosition.top));
}
for (var i = 0; i <= values.amount; i++) {
//left
path.add(new Point(blockSize.width, blockPosition.top + (blockSize.segmentY * i)));
}
path.add(new Point(blockSize.width, blockSize.height + blockPosition.top));
path.add(new Point(blockPosition.left, blockSize.height + blockPosition.top));
path.fullySelected = true;
path.closed = true;
return path;
}
function onResize() {
if (path)
path.remove();
path = createPath();
}
function onFrame(event) {
for (var i = 1; i <= values.amount - 1; i++) {
var segmentTop = path.segments[i];
var segmentRight = path.segments[i + values.amount + 1];
// A cylic value between -1 and 1
var sinus = Math.sin(event.time * 3 + i);
// Change the y position of the segment point:
segmentTop.point.y = sinus * values.height + 100;
// segmentRight.point.x = sinus * 1;
path.smooth();
}
path.segments[0].handleIn.x = 0;
path.segments[0].handleIn.y = 100;
path.segments[0].handleOut.x = 100;
path.segments[0].handleOut.y = 0;
path.segments[6].handleIn.x = -100;
path.segments[6].handleIn.y = 0;
path.segments[6].handleOut.x = 0;
path.segments[6].handleOut.y = 100;
}
您遇到的问题是因为您在整个正方形(包括角)上应用了平滑算法。
因此,如果您在将角柄设置为 horizontal/vertical 之前截取屏幕截图,您会看到:
我认为这很清楚地解释了为什么你的第二段有一个对角手柄,这是因为前一段也有一个...
这里有一个 sketch 演示了与您尝试实现的效果相似的效果。
// Define constants.
const POINTS_AMOUNT = 7;
const SQUARE_WIDTH = 500;
const WAVE_AMPLITUDE = 25;
const SQUARE_OFFSET = new Point(100, 100);
// Initialize path variable, we will use this reference to delete the previous
// path on each frame.
let path;
function draw(time) {
// Delete existing path.
if (path) {
path.remove();
}
// Create new path.
path = new Path();
// First, draw the top side.
for (let i = 0; i < POINTS_AMOUNT; i++) {
// For each point of the line, create a wave effect by using sine
// function. Do not apply it on first and last point to make square
// corners stay constant.
const sinus = i === 0 || i === POINTS_AMOUNT - 1
? 0
: Math.sin(time * 3 + i);
const x = SQUARE_WIDTH / POINTS_AMOUNT * i;
const y = sinus * WAVE_AMPLITUDE;
path.add(new Point(x, y));
}
// Apply smoothing algorithm on the line.
path.smooth();
// Duplicate this line 3 times to form a square.
const right = path.clone().rotate(-90, path.lastSegment.point);
right.reverse();
const bottom = right.clone().rotate(-90, right.lastSegment.point);
bottom.reverse();
const left = bottom.clone().rotate(-90, bottom.lastSegment.point);
// Join all parts together.
path.join(right).join(bottom).join(left);
path.closed = true;
// Place the square somewhere we can see it.
path.translate(SQUARE_OFFSET);
// Stylize the square.
path.fullySelected = true;
path.fillColor = 'yellow';
}
function onFrame(event) {
draw(event.time);
}
我现在是第一次使用 Paper.js,我正在处理一个有 fluid/waving 个边的黄色立方体。我想要的是像这样的立方波的边:
http://paperjs.org/tutorials/animation/creating-animations/#animating-path-segments
但是我想要固定立方体的角。我快到了,但我遇到了一个问题段 1(左上角是 [0])表现得很奇怪。把手是对角线的,不像其他把手是水平的。
我该如何解决这个问题?
我现在的草图可以找到here。
完整代码为
var values = {
margin: 64,
header: 132,
height: 60,
amount: 5
};
var path, springs;
function createPath(strength) {
var size = view.size;
var blockSize = {
width: size.width - values.margin,
height: size.height - values.header,
segmentX: (size.width - values.margin)/(values.amount + 1),
segmentY: (size.height - values.header)/(values.amount + 1)
};
var blockPosition = {
top: size.height - blockSize.height,
left: 0
}
var path = new Path({
fillColor: 'yellow'
});
for (var i = 0; i <= values.amount; i++) {
//top
path.add(new Point((blockPosition.left + (blockSize.segmentX * i)), blockPosition.top));
}
for (var i = 0; i <= values.amount; i++) {
//left
path.add(new Point(blockSize.width, blockPosition.top + (blockSize.segmentY * i)));
}
path.add(new Point(blockSize.width, blockSize.height + blockPosition.top));
path.add(new Point(blockPosition.left, blockSize.height + blockPosition.top));
path.fullySelected = true;
path.closed = true;
return path;
}
function onResize() {
if (path)
path.remove();
path = createPath();
}
function onFrame(event) {
for (var i = 1; i <= values.amount - 1; i++) {
var segmentTop = path.segments[i];
var segmentRight = path.segments[i + values.amount + 1];
// A cylic value between -1 and 1
var sinus = Math.sin(event.time * 3 + i);
// Change the y position of the segment point:
segmentTop.point.y = sinus * values.height + 100;
// segmentRight.point.x = sinus * 1;
path.smooth();
}
path.segments[0].handleIn.x = 0;
path.segments[0].handleIn.y = 100;
path.segments[0].handleOut.x = 100;
path.segments[0].handleOut.y = 0;
path.segments[6].handleIn.x = -100;
path.segments[6].handleIn.y = 0;
path.segments[6].handleOut.x = 0;
path.segments[6].handleOut.y = 100;
}
您遇到的问题是因为您在整个正方形(包括角)上应用了平滑算法。
因此,如果您在将角柄设置为 horizontal/vertical 之前截取屏幕截图,您会看到:
这里有一个 sketch 演示了与您尝试实现的效果相似的效果。
// Define constants.
const POINTS_AMOUNT = 7;
const SQUARE_WIDTH = 500;
const WAVE_AMPLITUDE = 25;
const SQUARE_OFFSET = new Point(100, 100);
// Initialize path variable, we will use this reference to delete the previous
// path on each frame.
let path;
function draw(time) {
// Delete existing path.
if (path) {
path.remove();
}
// Create new path.
path = new Path();
// First, draw the top side.
for (let i = 0; i < POINTS_AMOUNT; i++) {
// For each point of the line, create a wave effect by using sine
// function. Do not apply it on first and last point to make square
// corners stay constant.
const sinus = i === 0 || i === POINTS_AMOUNT - 1
? 0
: Math.sin(time * 3 + i);
const x = SQUARE_WIDTH / POINTS_AMOUNT * i;
const y = sinus * WAVE_AMPLITUDE;
path.add(new Point(x, y));
}
// Apply smoothing algorithm on the line.
path.smooth();
// Duplicate this line 3 times to form a square.
const right = path.clone().rotate(-90, path.lastSegment.point);
right.reverse();
const bottom = right.clone().rotate(-90, right.lastSegment.point);
bottom.reverse();
const left = bottom.clone().rotate(-90, bottom.lastSegment.point);
// Join all parts together.
path.join(right).join(bottom).join(left);
path.closed = true;
// Place the square somewhere we can see it.
path.translate(SQUARE_OFFSET);
// Stylize the square.
path.fullySelected = true;
path.fillColor = 'yellow';
}
function onFrame(event) {
draw(event.time);
}