1

我想知道是否有人可以帮助我找到解决方案。我使用 KineticJS 制作了一个非常简单的动画。一切都在桌面上完美运行,不幸的是不能在移动设备(iPhone、iPad、Android)上运行。

结果是一个缓慢的表现,但最重要的是扭曲的形状。

我怀疑它与分辨率或视口有关,但不确定。

预览在 www.bartvanhelsdingen.com

任何建议都受到高度赞赏。

下面是代码:

var shapes = {
    sizes: [30, 40, 50, 55, 60, 80],
    gradients: [
        [0, '#fdfaee', 1, '#524f43'],
        [0, '#a39175', 1, '#dbae5e'],
        [0, '#b4c188', 1, '#f3de7c'],
        [0, '#eaf2ef', 1, '#587c71'],
        [0, '#a39175', 1, '#dbae5e'],
        [0, '#61845c', 1, '#b4b092']
    ],
},
dims = {
    width: 300,
    height: 500
},
stage = new Kinetic.Stage({
    container: 'animation',
    width: dims.width,
    height: dims.height,
    x: 0,
    y: 0,
    draggable: false
});

function getRandomColor() {
    return colors[getRandomFromInterval(0, colors.length - 1)];
}

function getRandomGradient() {
    return gradients[getRandomFromInterval(0, gradients.length - 1)];
}

function getRandomFromInterval(from, to) {
    return Math.floor(Math.random() * (to - from + 1) + from);
}

function getRandomSpeed() {
    var speed = getRandomFromInterval(1, 1);
    return getRandomFromInterval(0, 1) ? speed : speed * -1;
}

function createGroup(x, y, size, strokeWidth) {
    return new Kinetic.Group({
        x: x,
        y: y,
        width: size,
        height: size,
        opacity: 0,
        draggable: false,
        clipFunc: function (canvas) {
            var context = canvas.getContext();
            context.beginPath();
            context.moveTo(0, 0);
            context.lineTo(0, size);
            context.lineTo(size, size);
            context.lineTo(size, 0);
            context.rect(strokeWidth, strokeWidth, size - strokeWidth * 2, size - strokeWidth * 2);
        }

    });
}

function createShape(size, gradient, strokeWidth, cornerRadius) {
    return new Kinetic.Rect({
        x: 0,
        y: 0,
        width: size,
        height: size,
        fillLinearGradientStartPoint: [size, 0],
        fillLinearGradientEndPoint: [size, size],
        fillLinearGradientColorStops: gradient,
        opacity: 1,
        lineJoin: 'bevel',
        strokeWidth: 0,
        cornerRadius: cornerRadius
    });
}
var layer = new Kinetic.Layer(),
    animAttribs = [];

for (var n = 0; n < 6; n++) {
    var size = shapes.sizes[n],
        strokeWidth = Math.ceil(size * 0.12),
        cornerRadius = Math.ceil(size * 0.04),
        gradient = shapes.gradients[n],
        x = getRandomFromInterval(size, dims.width) - size,
        y = getRandomFromInterval(size, dims.height) - size;

    var group = createGroup(x, y, size, strokeWidth);

    var shape = createShape(size, gradient, strokeWidth, cornerRadius);

    animAttribs.push({
        nextChange: getRandomFromInterval(1, 3) * 1000,
        startTime: 1000,
        duration: 0,
        x: getRandomSpeed(),
        y: getRandomSpeed()
    });

    group.add(shape);
    layer.add(group);
}

stage.add(layer);

anim = new Kinetic.Animation(function (frame) {
    var time = frame.time,
        timeDiff = frame.timeDiff,
        frameRate = frame.frameRate;
    for (var n = 0; n < layer.getChildren().length; n++) {
        var shape = layer.getChildren()[n],
            opacity = shape.getOpacity() + 0.01 > 1 ? 1 : shape.getOpacity() + 0.01,
            attribs = animAttribs[n],
            x, y;

        if (attribs.duration >= attribs.nextChange) {
            attribs.x = getRandomSpeed();
            attribs.y = getRandomSpeed();
            attribs.nextChange = getRandomFromInterval(3, 5) * 1000;
            attribs.duration = 0;
        }

        if (time >= attribs.startTime) {
            if (shape.getX() + attribs.x + shape.getWidth() >= stage.getWidth() || shape.getX() + attribs.x - shape.getWidth() / 2 <= 0) {
                attribs.x *= -1;
            }
            if (shape.getY() + attribs.y + shape.getHeight() >= stage.getHeight() || shape.getY() + attribs.y - shape.getHeight() / 2 <= 0) {
                attribs.y *= -1;
            }
            x = shape.getX() + attribs.x;
            y = shape.getY() + attribs.y;
            attribs.duration += timeDiff;
            shape.setOpacity(opacity);
            shape.setX(x);
            shape.setY(y);
        }

    }
}, layer);
anim.start();
4

1 回答 1

0

the problem you are facing is, that clipFunc isn't currently working on devices with pixelratio != 1.

This problem came up in this post as well. Eric Rowell, the creator of KineticJS added this issue to his release scedule for late September.

So there is nothing wrong with your animations, they're working as expected, but you can't see them because of the distorted clipping region

To resolve this issue "unofficially" you can simply replace the last line of the _clip function in your kinetic.js with the following: context.setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0); (credits for that go to Mark Smits)

于 2013-07-29T11:36:22.097 回答