2013-02-22 74 views
1

我想要一个类似按钮的对象,包含一个SVG矩形作为前景中的背景和HTML文本。 Raphael SVG库为创建,修改和动画SVG元素提供了很好的可能性。在div元素中使用拉斐尔SVG元素设置动画文本

I found a solution可以沿着Raphael对象/在Raphael对象上绘制DIV元素中的HTML文本。我如何使用Raphael的动画方法使文本随背景移动?

我只对基本的2D运动感兴趣,没有旋转或变形......我知道我可以使用支持拉斐尔的SVG文本元素,但是这不允许我文本包装,文本样式(css )。我试图找到一个方法来获取动画过程中的动画对象的坐标失败。

下面是一些coffeescript中的示例代码,灵感来自上面的例子,Kelley Reynolds。我的问题是如何将你的背景的运动与覆盖DIV同步:

nodeBox = (paper, params, attrs) -> 
params = params or {} 
attrs = attrs or {} 
@paper = paper 
@x = params.x or 0 
@y = params.y or 0 
@width = params.width or @paper.width 
@height = params.height or @paper.height 
@xMargin = params.xMargin or 5 
@yMargin = params.yMargin or 5 
@rounding = params.rounding or 0 
@backgBox = this.paper.rect(@[email protected], @[email protected], @width+2*@xMargin, @height+2*@yMargin, this.rounding).attr(attrs) 
containerId = @backgBox.node.parentNode.parentNode.id 
containerId = containerId or @backgBox.node.parentNode.parentNode.parentNode.id 
@container = jQuery('#' + containerId) 

@div = jQuery('<div style="position: absolute; overflow: auto; width: 0; height: 0;"></div>').insertAfter(@container) 
jQuery(document).bind('ready', this, (event) -> 
    event.data.update() 
    ) 
jQuery(window).bind('resize', this, (event) -> 
    event.data.update() 
    ) 
return this 

# update function 
nodeBox::update =() -> 
offset = @container.offset() 
@div.css(
    'top': (@y + (@rounding) + (offset.top)) + 'px', 
    'left': (@x + (@rounding) + (offset.left)) + 'px', 
    'height': (@height - (@rounding*2) + 'px'), 
    'width': (@width - (@rounding*2) + 'px') 
) 

# animate function 
nodeBox::animate = (attrs, duration, type) -> 
    @backgBox.animate(attrs, duration, type) 
    ### 
    Animation of the div ??? 
    ### 

$(document).ready -> 
paper = new Raphael document.getElementById('canvas_container'), '100%', '100%' 
node1 = new nodeBox(paper, x:200, y:200, width:200, height:60, rounding: 10, xMargin: 8, yMargin: 4, 'showBorder': true).attr(fill: 'lightblue', stroke: '#3b4449', 'stroke-width': 3) 
node1.div.html('This is some crazy content that goes inside of that box that will wrap around.') 
node1.div.css('font-family': 'Helvetica','font-size': 16, 'text-align': 'justify') 

# animate : 
node1.animate({x: moveX}, 1000, 'bounce') 
+1

请提供代码或jsfiddle示例 – Dom 2013-02-22 15:24:45

回答

0

所以我想通了这一点我自己。第一种可能性是使用已经与Raphael 2.x一起提供的前夕图书馆。您可以更新div的坐标使用eve.on()对应的背景框的坐标动画的每一帧上:

nodeBox::animate = (attrs, duration, type) -> 

offset = @canvasContainer.offset() 
strokeWidth = @backgBox.attrs['stroke-width'] 
textBox = @div 
rounding = @rounding 
xMargin = @xMargin 
yMargin = @yMargin 

### we animate the underlying box 
@backgBox.animate(attrs, duration, type, eve.unbind('raphael.anim.frame.' + @backgBox.id, onAnimate)) 

    ### the coordinates of the div are updated on every frame 
eve.on('raphael.anim.frame.' + @backgBox.id, onAnimate = (animationObject) -> 
    textBox.css(
     'top': (@attrs.y + (rounding) + (yMargin) + (offset.top) + strokeWidth) + 'px', 
     'left': (@attrs.x + (rounding) + (xMargin) + (offset.left) + strokeWidth) + 'px', # scrollbar width 
     'height': (@attrs.height - (rounding*2) - (yMargin*2) - strokeWidth + 'px'), 
     'width': (@attrs.width - (rounding*2) - (xMargin*2) - strokeWidth + 'px') 
     ) 
    ) 

这种解决方案的缺点是,它不会觉得很顺利的话,可以看到文字“跟随”框。因此,我不会尝试为Raphael提供插件的GreenSock动画平台,并应提供矢量图形和覆盖DOM的同步动画。 Take a look here