html5 canvas弹性字符串文字动画特效



56 222 75



特效描述:html5 canvas弹性字符串 文字动画特效,html5基于canvas制作拖动文字字符串弹性动画特效。

代码结构

1. 引入JS

<script type="text/javascript" src="js/kzymdn.js"></script>

2. HTML代码

<canvas id='c'></canvas>
<script type="text/javascript">
/**
 * requestAnimationFrame
 */
window.requestAnimationFrame = (function(){
    return  window.requestAnimationFrame       ||
            window.webkitRequestAnimationFrame ||
            window.mozRequestAnimationFrame    ||
            window.oRequestAnimationFrame      ||
            window.msRequestAnimationFrame     ||
            function (callback) { window.setTimeout(callback, 1000 / 60); };
})();
/**
 * ElasticString
 */
var ElasticString = (function(document) {
    'use strict';
    /**
     * @constructor
     */
    function ElasticString(fontSize, fontFamily, friction, spring) {
        this._fontSize = fontSize;
        this.points = [];
        this.fontFamily = fontFamily || 'serif';
        if (friction !== undefined) this.friction = friction;
        if (spring !== undefined) this.spring = spring;
        this._endPoint = new Point();
        this._ctx = document.createElement('canvas').getContext('2d');
    }
    ElasticString.prototype = {
        points: null,
        fontFamily: 'serif',
        friction: 0.02,
        spring: 0.6,
        _text: '',
        _fontSize: 1,
        _endPoint: null,
        setFontSize: function(fontSize) {
            this._fontSize = fontSize;
            this.setText(this._text);
        },
        getFontSize: function() { return this._fontSize; },
        setText: function(text, positions) {
            var points = this.points,
                p, letter, between,
                i, len;
            if (text.length < points.length) {
                points = points.slice(0, text.length);
            }
            this._ctx.font = this._fontSize + 'px ' + this.fontFamily;
            for (i = 0, len = text.length; i < len; i++) {
                letter = text.charAt(i);
                between = this._ctx.measureText(letter).width;
                p = points[i];
                if (p) {
                    p.letter = letter;
                    p.between = between;
                } else {
                    p = new Point(letter, between);
                    points[i] = p;
                }
                if (positions && positions.length) {
                    p.x = p.px = positions[i][0];
                    p.y = p.py = positions[i][1];
                }
            }
            this.points = points;
            this._text = text;
        },
        getText: function() { return this._text; },
        render: function(ctx) {
            var points = this.points,
                pointBetween = this._fontSize,
                spring = this.spring,
                text = this.text,
                dx, dy, dist, scale,
                p0, p1, size, angle,
                i, len;
            points.push(this._endPoint);
            this._updatePoint(points[0]);
            for (i = 0, len = points.length - 1; i < len; i++) {
                p0 = points[i];
                p1 = points[i + 1];
                this._updatePoint(p1);
                dx = p0.x - p1.x;
                dy = p0.y - p1.y;
                dist = Math.sqrt(dx * dx + dy * dy);
                scale = dist ? (p0.between - dist) / dist * 0.5 * spring : 0;
                dx *= scale;
                dy *= scale;
                p0.x += dx;
                p0.y += dy;
                p1.x -= dx;
                p1.y -= dy;
            }
            for (i = 0; i < len; i++) {
                p0 = points[i];
                p1 = points[i + 1];
                dx = p1.x - p0.x;
                dy = p1.y - p0.y;
                dist = Math.sqrt(dx * dx + dy * dy);
                angle = Math.atan2(dy, dx);
                ctx.save();
                size = pointBetween > dist ? pointBetween : dist;
                ctx.font = size + 'px ' + this.fontFamily;
                ctx.translate(p0.x, p0.y);
                ctx.rotate(angle);
                ctx.fillText(p0.letter, 0, 0);
                ctx.restore();
            }
            points.pop();
        },
        _updatePoint: function(p) {
            var friction = 1 - this.friction,
                px = p.px,
                py = p.py;
            p.px = p.x;
            p.py = p.y;
            if (p.fixed) return;
            p.x += (p.x - px) * friction;
            p.y += (p.y - py) * friction;
        }
    };
    /**
     * Point
     */
    function Point(letter, between, x, y) {
        this.letter = letter || '';
        this.between = between || 0;
        this.x = this.px = x || 0;
        this.y = this.py = y || 0;
    }
    Point.prototype = {
        letter: '',
        between: 1,
        x: 0,
        y: 0
    };
    return ElasticString;
})(document);
(function(window, document) {
    'use strict';
    // Configs
    var TEXT = 'The quick brown fox jumps over the lazy dog.',
        FONT_SIZE = 25;
    // Vars
    var canvas, context,
        elasticString,
        mouse = { x: 0, y: 0 },
        drag = null,
        gui, guiOptions;
    // Init
    function init() {
        var pos = [], i, len;
        canvas  = document.getElementById('c');
        context = canvas.getContext('2d');
        resize(null);
        elasticString = new ElasticString(FONT_SIZE, 'Georgia, serif');
        for (i = 0, len = TEXT.length; i < len; i++) {
            if (i === 0)
                pos.push([100, 100]);
            else
                pos.push([canvas.width * Math.random(), canvas.height * Math.random()]);
        }
        elasticString.setText(TEXT, pos);
        window.addEventListener('resize', resize, false);
        canvas.addEventListener('mousemove', mouseMove, false);
        canvas.addEventListener('mousedown', mouseDown, false);
        document.body.addEventListener('mouseup', mouseUp, false);
        // GUI
        guiOptions = {
            text: elasticString.getText(),
            fontSize: elasticString.getFontSize()
        };
        gui = new dat.GUI();
        gui.add(guiOptions, 'text').onFinishChange(function() {
            elasticString.setText(guiOptions.text);
        });
        gui.add(guiOptions, 'fontSize', 1, 50).onChange(function() {
            elasticString.setFontSize(guiOptions.fontSize);
        });
        gui.add(elasticString, 'friction', 0, 1);
        gui.add(elasticString, 'spring', 0, 1);
        gui.close();
        update();
    }
    // Event Listeners
    function resize(e) {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
        context.fillStyle = '#3a3a2c';
    }
    function mouseMove(e) {
        mouse.x = e.clientX;
        mouse.y = e.clientY;
    }
    function mouseDown(e) {
        var points = elasticString.points,
            p,
            hit = null,
            rangeSq = FONT_SIZE * FONT_SIZE,
            hitNear = FONT_SIZE * FONT_SIZE,
            mx = e.clientX,
            my = e.clientY,
            dx, dy, distSq,
            i, len;
        for (i = 0, len = points.length; i < len; i++) {
            p = points[i];
            dx = mx - p.x;
            dy = my - p.y;
            distSq = dx * dx + dy * dy;
            if (distSq < rangeSq && distSq < hitNear) {
                hitNear = distSq;
                hit = points[i];
            }
        }
        drag = hit;
    }
    function mouseUp(e) {
        drag = null;
    }
    // Update
    function update() {
        var points = elasticString.points,
            p,
            w = canvas.width,
            h = canvas.height,
            i, len;
        if (drag) {
            drag.x = mouse.x;
            drag.y = mouse.y;
        }
        for (i = 0, len = points.length; i < len; i++) {
            p = points[i];
            if (0 > p.x) p.x = 0;
            if (w < p.x) p.x = w;
            if (0 > p.y) p.y = 0;
            if (h < p.y) p.y = h;
        }
        context.clearRect(0, 0, canvas.width, canvas.height);
        elasticString.render(context);
        requestAnimationFrame(update);
    }
    // Run
    init();
})(window, document);
</script>



用户评论
大牛,别默默的看了,快登录帮我点评一下吧!:)      登录 | 注册


热门标签: 加载动画 拖动 拖拽 拖动插件 拖拽插件 h5弹窗动画 html5弹窗动画 h5动画 h5背景动画 h5场景动画 h53D动画 h5界面动画 html5动画 h5按钮动画 html5按钮动画 文字拖动 文字拖拽 h5文字动画 h5文字边框动画 html5文字动画 html5文字边框动画

×
×

注册

官方QQ群

扫描上面二维码加微信群

官方QQ群

jQuery/js讨论群
群号:642649996
Css3+Html5讨论群
群号:322131262

加群请备注:从官网了解到