分组形状上的硬币旋转效果动画
Posted
技术标签:
【中文标题】分组形状上的硬币旋转效果动画【英文标题】:Coin spin effect animation on grouped shapes 【发布时间】:2019-04-16 02:28:13 【问题描述】:有人要求我使用 Konvajs 制作一个动画,该动画将旋转一个圆圈,就像在其中心 x 轴上旋转一样。所以想象一个硬币在桌子上旋转。目的是在圆圈上显示一些文字。一开始圆圈完全可见,就像从后面看一样,所以看不到任何文字,然后它会翻转以显示文字。
我有这个代码可以像旋转的***一样旋转。
谁能给我一个补间/动画方法来实现旋转硬币效果?
// the tween has to be created after the node has been added to the layer
var tween = new Konva.Tween(
node: group,
duration: 4,
rotation: 360,
easing: Konva.Easings.BackEaseOut
);
tween.play();
经过一些研究,看起来 3D 旋转需要更重的举重,这在移动设备上可能不可用或无法正常工作。
一个好的次优似乎是使用 scaleX 并从 0 > 1 开始制作动画。
group.scaleX(0);
var tween = new Konva.Tween(
node: group,
duration: .25,
scaleX: 1,
easing: Konva.Easings.EaseOut
);
【问题讨论】:
【参考方案1】:这是使用 scaleX() 效果的次优版本的示例。因为需要计算 scaleX() 并控制文本的可见性以使圆盘看起来是实心的,所以我从补间移到了 animation()。
// Set up the canvas / stage
var s1 = new Konva.Stage(container: 'container1', width: 300, height: 200);
// Add a layer for line
var layer = new Konva.Layer(draggable: false);
s1.add(layer);
// just a plain JS object to keep common variables in hand.
var cfg = w: 300, h: 200, r: 80, txtSize: 520;
var group = new Konva.Group();
var circle = new Konva.Circle(x: cfg.w/2, y: cfg.h/2, radius: cfg.r, fill: 'DodgerBlue', stroke: 'DeepPink', strokeWidth: 5)
group.add(circle)
var textValue = new Konva.Text(
id: "t1",
x: cfg.w/2,
y: cfg.h/2,
text: '',
fill: 'DeepPink ',
fontSize: cfg.txtSize
);
group.add(textValue);
textValue.offset(x: textValue.getWidth()/2, y: textValue.getHeight()/2);
layer.add(group)
// to spin a group about a point, set the offset to that point, then set the x & y to that point to !
var pos = group.getClientRect();
RotatePoint(group, x: pos.x + pos.width/2, y: pos.y + pos.height/2);
// Everything is ready so draw the canvas objects set up so far.
s1.draw()
$('#st').on('click', function()
group.scaleX(1);
var txt = $('#theText').val();
setValue(txt);
)
// set the offset for rotation to the given location and re-position the shape
function RotatePoint(shape, pos) // where pos = x: xpos, y: yPos
var initialPos = shape.getAbsolutePosition();
var moveBy = x: pos.x - initialPos.x, y: pos.y - initialPos.y;
// offset is relative to initial x,y of shape, so deduct x,y.
shape.offsetX(moveBy.x);
shape.offsetY(moveBy.y);
shape.x(initialPos.x + moveBy.x);
shape.y(initialPos.y + moveBy.y);
var setValue = function(newText)
// work out scaling to make text fit into the circle
var txt = this.layer.find('#t1')[0];
txt.text(newText).scale(x:1, y: 1)
var txtSize = txt.getClientRect();
var maxW = (cfg.r); // max allowed width of text
var txtScaleW = (txtSize.width > maxW ? ( maxW / txtSize.width) : 1);
var maxH = cfg.r; // max allowed height of text
var txtScaleH = (txtSize.height > maxH ? ( maxH / txtSize.height) : 1);
// finally decide which is the worst case and use that scaling
var txtScale = ( txtScaleW > txtScaleH ? txtScaleH : txtScaleW);
txt.scale(x: txtScale, y: txtScale);
txt.offset(x: txt.getWidth()/2, y: txt.getHeight()/2);
layer.draw()
// set initial text & spin !
setValue('BBB');
var anim, pos = 0, frameCnt = 0
if (anim) anim.stop();
anim = new Konva.Animation(function(frame)
frameCnt = frameCnt + 1;
if (frameCnt % 2 === 0)
pos = pos + .2
var scaleX = Math.sin(pos)
textValue.visible(scaleX < 0 ? false : true);
group.scaleX(scaleX);
if (pos % 360 === 0) console.log('spin')
, layer);
anim.start();
div
float: left;
margin: 0 5px;
p
margin: 0 5px 5px 0;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/konva/2.5.1/konva.min.js"></script>
<div id='container1' style="width: 300px, height: 200px;"></div>
<div>
<p> <input type='text' id='theText' value='BBB' /> <button id='st'>Change text</button> </p>
</div>
【讨论】:
以上是关于分组形状上的硬币旋转效果动画的主要内容,如果未能解决你的问题,请参考以下文章