我可以控制线段把手的光滑度吗?

时间:2019-03-25 10:20:33

标签: paperjs

我现在是第一次使用Paper.js,而且我正在研究一个黄色的立方体,该立方体具有流动/波动的侧面。我想要的是像这样的立方波的一面:

http://paperjs.org/tutorials/animation/creating-animations/#animating-path-segments

但是我想固定立方体的角。我快到那儿了,但是我进入一个问题部分1(左上角是[0]),感觉很奇怪。手柄是对角的,不像其他手柄那样水平。

enter image description here

我该如何解决?

我当前的草图可以找到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;
}

1 个答案:

答案 0 :(得分:1)

您遇到的问题是由于您在整个正方形(包括角)上应用了平滑算法。 因此,如果您在将角点手柄设置为水平/垂直之前拍摄了屏幕截图,则会看到以下信息: enter image description here 我认为这很清楚地解释了为什么您的第二个片段也有一个对角线手柄,这是因为前一个片段也有一个对角线手柄...

这里是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);
}