首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用html5为字符文本设置动画

如何使用html5为字符文本设置动画
EN

Stack Overflow用户
提问于 2010-05-15 05:59:24
回答 1查看 5.5K关注 0票数 2

如何在HTML5中使页面上的文本的单个字符具有动画效果。就像flash中的这个例子。http://www.greensock.com/splittextfield/

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-05-15 07:30:42

您必须将每个字符包装在一个<span>中,然后使用CSS position/top/left.移动该跨度。

您不能完全重现Flash示例所做的事情,因为该示例使用了模糊效果。CSS不能做到这一点;SVG可以做到这一点,IE的非标准filter可以做到这一点,但这将意味着总的代码分支。

您可以通过设置font-size来更改每个字母的大小,但为了使示例中的剪切/旋转效果生效,您必须使用CSS transform。这还不是标准化的,浏览器的支持也存在漏洞。

这是我刚刚为Firefox做的一个概念验证(很抱歉代码太长了):

代码语言:javascript
复制
<p id="effect">I've got a lovely bunch of coconuts.</p>
<button id="animate">Animate</button>


// Add ECMA262-5 method binding if not supported natively
//
if (!('bind' in Function.prototype)) {
    Function.prototype.bind= function(owner) {
        var that= this;
        if (arguments.length<=1) {
            return function() {
                return that.apply(owner, arguments);
            };
        } else {
            var args= Array.prototype.slice.call(arguments, 1);
            return function() {
                return that.apply(owner, arguments.length===0? args : args.concat(Array.prototype.slice.call(arguments)));
            };
        }
    };
}

// Lightweight class/instance system
//
Function.prototype.makeSubclass= function() {
    function Class() {
        if (!(this instanceof Class))
            throw 'Constructor function requires new operator';
        if ('_init' in this)
            this._init.apply(this, arguments);
    }
    if (this!==Object) {
        Function.prototype.makeSubclass.nonconstructor.prototype= this.prototype;
        Class.prototype= new Function.prototype.makeSubclass.nonconstructor();
    }
    return Class;
};
Function.prototype.makeSubclass.nonconstructor= function() {};

// Abstract base for animated linear sliding switch between 0 and 1
//
var Animation= Object.makeSubclass();
Animation.prototype._init= function(period, initial) {
    this.period= period;
    this.interval= null;
    this.aim= initial || 0;
    this.t= 0;
};
Animation.prototype.set= function(aim) {
    if (aim===this.aim)
        return;
    this.aim= aim;
    var now= new Date().getTime();
    if (this.interval===null) {
        this.t= now;
        this.interval= window.setInterval(this.update.bind(this), 32);
    } else {
        this.t= now-this.t-this.period+now
        this.update();
    }
};
Animation.prototype.toggle= function() {
    this.set(this.aim===0? 1 : 0);
};
Animation.prototype.update= function() {
    var now= new Date().getTime();
    var x= Math.min((now-this.t)/this.period, 1);
    this.show(this.aim===0? 1-x : x);
    if (x===1) {
        window.clearInterval(this.interval);
        this.interval= null;
    }
};
Animation.prototype.show= function(d) {};

// Animation that spins each character in a text node apart
//
var ExplodeAnimation= Animation.makeSubclass();
ExplodeAnimation.prototype._init= function(node, period) {
    Animation.prototype._init.call(this, period, 0);
    this.spans= [];

    // Wrap each character in a <span>
    //
    for (var i= 0; i<node.data.length; i++) {
        var span= document.createElement('span');
        span.style.position= 'relative';
        span.appendChild(document.createTextNode(node.data.charAt(i)));
        node.parentNode.insertBefore(span, node);
        this.spans.push(span);
    }

    // Make up random positions and speeds for each character.
    // Possibly this should be re-randomised on each toggle?
    //
    this.randomness= [];
    for (var i= this.spans.length; i-->0;)
        this.randomness.push({
            dx: Math.random()*200-100, dy: Math.random()*200-150,
            sx: Math.random()*1.5, sy: Math.random()*1.5,
            dr: Math.random()*240-120, og: Math.random()+0.5
        });

    node.parentNode.removeChild(node);
};
ExplodeAnimation.prototype.show= function(d) {
    for (var i= this.spans.length; i-->0;) {
        var style= this.spans[i].style;
        var r= this.randomness[i];

        style.left= d*r.dx+'px';
        style.top= d*r.dy+'px';
        var transform= 'rotate('+Math.floor(d*r.dr)+'deg) scale('+(d*r.sx+1-d)+', '+(d*r.sy+1-d)+')';
        if ('transform' in style)
            style.transform= transform;
        else if ('MozTransform' in style)
            style.MozTransform= transform;

        var o= 1-Math.pow(d, r.og);
        if ('opacity' in style)
            style.opacity= o+'';
        else if ('filter' in style)
            style.filter= 'opacity(alpha='+Math.ceil(o*100)+')';
    }
};


var animation= new ExplodeAnimation(document.getElementById('effect').firstChild, 1000);
document.getElementById('animate').onclick= animation.toggle.bind(animation);

这可以通过添加重力和当前完全随机变换的更好的3D空间建模,以及在Firefox以外的浏览器中对缩放/旋转的更好的浏览器支持来改进。

(IE有它自己可能支持的非标准CSS transform filters;Webkit和Opera有webkitTransformoTransform样式,但它们拒绝转换相对定位内联跨度,所以你必须绝对定位每个字符,这意味着读取它们的所有正常位置作为基线。在这一点上,我感到很无聊。)

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2837902

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档