如何将路径缩放到指向的方向

时间:2017-12-10 03:27:34

标签: paperjs

在我的演示中。我能够创建一些彼此重叠的椭圆。每个椭圆都略微旋转,当点击时应向外伸展。

然而,现在我正在使用.scale(x,y)并且椭圆的高度垂直增加。

我不确定如何使用paper.js

完成此类效果

样本 Code Pen Demo

	paper.install(window);
	var canvas = document.getElementById("myCanvas");

	window.onload = function() {
		paper.setup('myCanvas');

		var numberOfRings = 6,
			rings = [],
			size = [225,400],
			colors = ['black','green','orange','blue','yellow','grey'],
			max_frame = 50,
			negative_scale = 0.99,
			positive_scale = 1.01;

		for(var i = 0; i < numberOfRings; i++)
		{
			var path = new Path.Ellipse({
			    center:view.center,
			    size: size,
			    strokeColor: colors[i],
			    strokeWidth :10
			});

			var rotate = 30*i +30;

			path.rotate(rotate);
			path.animation = false;
			path.rotateValue = rotate;

			path.animationStartFrame = 0;
			path.animationScale = positive_scale;
			path.smooth();
			path.animationIndex = i;

			path.onClick = function(event) {
				rings[this.animationIndex].animation = true;
			}

			rings.push(path);

		}

		view.onFrame = function(event) {

			for(var i = 0; i < numberOfRings; i++)
			{

				if (rings[i].animation == true){

					if (rings[i].animationStartFrame == 0)
					{
						rings[i].animationStartFrame = event.count;
					}

					if (rings[i].animationStartFrame > 0 && event.count < (rings[i].animationStartFrame + max_frame)){
          
						// TODO
						rings[i].scale(1,rings[i].animationScale);

					} else if ( event.count > (rings[i].animationStartFrame + max_frame)){
						rings[i].animation = false;
						rings[i].animationStartFrame = 0;

						if (rings[i].animationScale == negative_scale)
							rings[i].animationScale = positive_scale;
						else
							rings[i].animationScale = negative_scale;
					}
				}

			}
		}




	}
canvas{
	width: 100%;
	height: 100%;
}
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.11.5/paper-full.min.js"></script>
</head>
<body>
	<canvas id="myCanvas" resize></canvas>
</body>
</html>

1 个答案:

答案 0 :(得分:0)

首先对于这类事情,我认为将applyMatrix选项设置为false的paper.js / items更容易使用 - 这种方式转换不会应用/烘焙到item / children /路径但在转换中保持分离,因此也可以在以后以绝对的方式进行操作。

另外为了达到你想要的效果,我使用了一个技巧:Group 我将椭圆路径封装在一个组中。所以我只能旋转组。 孩子的坐标系没有被修改 - 我可以像原始坐标系一样操纵椭圆缩放,因为它没有被旋转。

我根据你的例子进行了一些其他修改 - 主要是因为它更容易在不同的画布大小和不同数量的椭圆中进行测试。

我首先测试/开发了它at sketch.paperjs.org(我觉得在那里测试/调试它更容易) 然后将其转换为适合此处的plain js版本。

如果你想做更复杂的动画,请查看好的图书馆animatePaper.js - 我大量使用它并喜欢使用它:-) 它支持纸质对象属性的简单和更复杂的动画。

paper.install(window);
var canvas = document.getElementById('myCanvas');

window.onload = function() {
    paper.setup('myCanvas');
    var numberOfRings = 5;
    var rings = [];
    let view_max_length = Math.min(view.size.width, view.size.height);
    var ringStartSize = new Size(view_max_length * 0.4, view_max_length * 0.45);
    var ringTargetLength = view_max_length * 0.9;
    var scaleStepSize = 0.01;


    function createRing(index) {
        let path = new Path.Ellipse({
            center: view.center,
            size: ringStartSize,
            strokeColor: {
                hue: (360 / numberOfRings) * index,
                saturation: 1,
                brightness: 1
            },
            strokeWidth: 10,
            applyMatrix: false,
            strokeScaling: false,
        });

        // add custom properties
        path.animate = false;
        path.animationDirectionOut = true;
        path.animationIndex = index;

        path.onClick = function(event) {
            //console.log(this);
            this.animate = true;
        };

        let rotationgroup = new Group(path);
        rotationgroup.applyMatrix = false;
        let offsetAngle = (360 / 2) / numberOfRings;
        let rotate = offsetAngle * index;
        rotationgroup.pivot = path.bounds.center;
        rotationgroup.rotation = rotate;

        return path;
    }

    function init() {
        for (let i = 0; i < numberOfRings; i++) {
            rings.push(createRing(i));
        }
    }

    function animateRing(event, ring) {
        if (ring.animate) {
            let tempScaleStep = scaleStepSize;
            if (!ring.animationDirectionOut) {
                tempScaleStep = tempScaleStep * -1;
            }
            ring.scaling.y += tempScaleStep;

            // test if we have reached destination size.
            if (
                (ring.bounds.height >= ringTargetLength) ||
                (ring.bounds.height <= ringStartSize.height)
            ) {
                ring.animate = false;
                // change direction
                ring.animationDirectionOut = !ring.animationDirectionOut;
            }
        }
    }

    view.onFrame = function(event) {
        if (rings && (rings.length > 0)) {
            for (var i = 0; i < numberOfRings; i++) {
                animateRing(event, rings[i]);
            }
        }
    };


    init();

}
canvas {
  widht: 100%;
  height: 100%;
  background-color: rgb(0,0,50);
}
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.11.5/paper-full.min.js"></script>
</head>
<body>
	<canvas id="myCanvas" resize></canvas>
</body>
</html>