| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444 | /** * echarts图表特效基类 * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author Kener (@Kener-林峰, kener.linfeng@gmail.com) * */define(function (require) {    var ecData = require('../util/ecData');        var CircleShape = require('zrender/shape/Circle');    var ImageShape = require('zrender/shape/Image');    var curveTool = require('zrender/tool/curve');    var IconShape = require('../util/shape/Icon');    var SymbolShape = require('../util/shape/Symbol');    var ShapeBundle = require('zrender/shape/ShapeBundle');    var Polyline = require('zrender/shape/Polyline');    var vec2 = require('zrender/tool/vector');    var canvasSupported = require('zrender/tool/env').canvasSupported;        function point(zr, effectList, shape, zlevel) {        var effect = shape.effect;        var color = effect.color || shape.style.strokeColor || shape.style.color;        var shadowColor = effect.shadowColor || color;        var size = effect.scaleSize;        var distance = effect.bounceDistance;        var shadowBlur = typeof effect.shadowBlur != 'undefined'                         ? effect.shadowBlur : size;        var effectShape;        if (shape.type !== 'image') {            effectShape = new IconShape({                zlevel : zlevel,                style : {                    brushType : 'stroke',                    iconType : shape.style.iconType != 'droplet'                               ? shape.style.iconType                               : 'circle',                    x : shadowBlur + 1, // 线宽                    y : shadowBlur + 1,                    n : shape.style.n,                    width : shape.style._width * size,                    height : shape.style._height * size,                    lineWidth : 1,                    strokeColor : color,                    shadowColor : shadowColor,                    shadowBlur : shadowBlur                },                draggable : false,                hoverable : false            });            if (shape.style.iconType == 'pin') {                effectShape.style.y += effectShape.style.height / 2 * 1.5;            }            if (canvasSupported) {  // 提高性能,换成image                effectShape.style.image = zr.shapeToImage(                    effectShape,                     effectShape.style.width + shadowBlur * 2 + 2,                     effectShape.style.height + shadowBlur * 2 + 2                ).style.image;                                effectShape = new ImageShape({                    zlevel : effectShape.zlevel,                    style : effectShape.style,                    draggable : false,                    hoverable : false                });            }        }        else {            effectShape = new ImageShape({                zlevel : zlevel,                style : shape.style,                draggable : false,                hoverable : false            });        }                ecData.clone(shape, effectShape);                // 改变坐标,不能移到前面        effectShape.position = shape.position;        effectList.push(effectShape);        zr.addShape(effectShape);                var devicePixelRatio = shape.type !== 'image' ? (window.devicePixelRatio || 1) : 1;        var offset = (effectShape.style.width / devicePixelRatio - shape.style._width) / 2;        effectShape.style.x = shape.style._x - offset;        effectShape.style.y = shape.style._y - offset;        if (shape.style.iconType == 'pin') {            effectShape.style.y -= shape.style.height / 2 * 1.5;        }        var duration = (effect.period + Math.random() * 10) * 100;                zr.modShape(            shape.id,             { invisible : true}        );                var centerX = effectShape.style.x + (effectShape.style.width) / 2 / devicePixelRatio;        var centerY = effectShape.style.y + (effectShape.style.height) / 2 / devicePixelRatio;        if (effect.type === 'scale') {            // 放大效果            zr.modShape(                effectShape.id,                 {                    scale : [0.1, 0.1, centerX, centerY]                }            );                        zr.animate(effectShape.id, '', effect.loop)                .when(                    duration,                    {                        scale : [1, 1, centerX, centerY]                    }                )                .done(function() {                    shape.effect.show = false;                    zr.delShape(effectShape.id);                })                .start();        }        else {            zr.animate(effectShape.id, 'style', effect.loop)                .when(                    duration,                    {                        y : effectShape.style.y - distance                    }                )                .when(                    duration * 2,                    {                        y : effectShape.style.y                    }                )                .done(function() {                    shape.effect.show = false;                    zr.delShape(effectShape.id);                })                .start();        }            }        function largePoint(zr, effectList, shape, zlevel) {        var effect = shape.effect;        var color = effect.color || shape.style.strokeColor || shape.style.color;        var size = effect.scaleSize;        var shadowColor = effect.shadowColor || color;        var shadowBlur = typeof effect.shadowBlur != 'undefined'                         ? effect.shadowBlur : (size * 2);        var devicePixelRatio = window.devicePixelRatio || 1;        var effectShape = new SymbolShape({            zlevel : zlevel,            position : shape.position,            scale : shape.scale,            style : {                pointList : shape.style.pointList,                iconType : shape.style.iconType,                color : color,                strokeColor : color,                shadowColor : shadowColor,                shadowBlur : shadowBlur * devicePixelRatio,                random : true,                brushType: 'fill',                lineWidth:1,                size : shape.style.size            },            draggable : false,            hoverable : false        });                effectList.push(effectShape);        zr.addShape(effectShape);        zr.modShape(            shape.id,             { invisible : true}        );                var duration = Math.round(effect.period * 100);        var clip1 = {};        var clip2 = {};        for (var i = 0; i < 20; i++) {            effectShape.style['randomMap' + i] = 0;            clip1 = {};            clip1['randomMap' + i] = 100;            clip2 = {};            clip2['randomMap' + i] = 0;            effectShape.style['randomMap' + i] = Math.random() * 100;            zr.animate(effectShape.id, 'style', true)                .when(duration, clip1)                .when(duration * 2, clip2)                .when(duration * 3, clip1)                .when(duration * 4, clip1)                .delay(Math.random() * duration * i)                //.delay(duration / 15 * (15 - i + 1))                .start();                    }    }        function line(zr, effectList, shape, zlevel, isLarge) {        var effect = shape.effect;        var shapeStyle = shape.style;        var color = effect.color || shapeStyle.strokeColor || shapeStyle.color;        var shadowColor = effect.shadowColor || shapeStyle.strokeColor || color;        var size = shapeStyle.lineWidth * effect.scaleSize;        var shadowBlur = typeof effect.shadowBlur != 'undefined'                         ? effect.shadowBlur : size;        var effectShape = new CircleShape({            zlevel : zlevel,            style : {                x : shadowBlur,                y : shadowBlur,                r : size,                color : color,                shadowColor : shadowColor,                shadowBlur : shadowBlur            },            hoverable : false        });        var offset = 0;        if (canvasSupported && ! isLarge) {  // 提高性能,换成image            var zlevel = effectShape.zlevel;            effectShape = zr.shapeToImage(                effectShape,                (size + shadowBlur) * 2,                (size + shadowBlur) * 2            );            effectShape.zlevel = zlevel;            effectShape.hoverable = false;            offset = shadowBlur;        }        if (! isLarge) {            ecData.clone(shape, effectShape);            // 改变坐标, 不能移到前面            effectShape.position = shape.position;            effectList.push(effectShape);            zr.addShape(effectShape);        }        var effectDone = function () {            if (! isLarge) {                shape.effect.show = false;                zr.delShape(effectShape.id);               }            effectShape.effectAnimator = null;        };        if (shape instanceof Polyline) {            var distanceList = [0];            var totalDist = 0;            var pointList = shapeStyle.pointList;            var controlPointList = shapeStyle.controlPointList;            for (var i = 1; i < pointList.length; i++) {                if (controlPointList) {                    var cp1 = controlPointList[(i - 1) * 2];                    var cp2 = controlPointList[(i - 1) * 2 + 1];                    totalDist += vec2.dist(pointList[i - 1], cp1)                         + vec2.dist(cp1, cp2)                         + vec2.dist(cp2, pointList[i]);                }                else {                    totalDist += vec2.dist(pointList[i - 1], pointList[i]);                }                distanceList.push(totalDist);            }            var obj = { p: 0 };            var animator = zr.animation.animate(obj, { loop: effect.loop });            for (var i = 0; i < distanceList.length; i++) {                animator.when(distanceList[i] * effect.period, { p: i });            }            animator.during(function () {                var i = Math.floor(obj.p);                var x, y;                if (i == pointList.length - 1) {                    x = pointList[i][0];                    y = pointList[i][1];                }                else {                    var t = obj.p - i;                    var p0 = pointList[i];                    var p1 = pointList[i + 1];                    if (controlPointList) {                        var cp1 = controlPointList[i * 2];                        var cp2 = controlPointList[i * 2 + 1];                        x = curveTool.cubicAt(                            p0[0], cp1[0], cp2[0], p1[0], t                        );                        y = curveTool.cubicAt(                            p0[1], cp1[1], cp2[1], p1[1], t                        );                    }                    else {                        x = (p1[0] - p0[0]) * t + p0[0];                        y = (p1[1] - p0[1]) * t + p0[1];                       }                }                effectShape.style.x = x;                effectShape.style.y = y;                if (! isLarge) {                    zr.modShape(effectShape);                }            })            .done(effectDone)            .start();            animator.duration = totalDist * effect.period;            effectShape.effectAnimator = animator;        }        else {            var x0 = shapeStyle.xStart - offset;            var y0 = shapeStyle.yStart - offset;            var x2 = shapeStyle.xEnd - offset;            var y2 = shapeStyle.yEnd - offset;            effectShape.style.x = x0;            effectShape.style.y = y0;            var distance = (x2 - x0) * (x2 - x0) + (y2 - y0) * (y2 - y0);            var duration = Math.round(Math.sqrt(Math.round(                distance * effect.period * effect.period            )));            if (shape.style.curveness > 0) {                var x1 = shapeStyle.cpX1 - offset;                var y1 = shapeStyle.cpY1 - offset;                effectShape.effectAnimator = zr.animation.animate(effectShape, { loop: effect.loop })                    .when(duration, { p: 1 })                    .during(function (target, t) {                        effectShape.style.x = curveTool.quadraticAt(                            x0, x1, x2, t                        );                        effectShape.style.y = curveTool.quadraticAt(                            y0, y1, y2, t                        );                        if (! isLarge) {                            zr.modShape(effectShape);                        }                    })                    .done(effectDone)                    .start();            }            else {                // 不用 zr.animate,因为在用 ShapeBundle 的时候单个 effectShape 不会                // 被加到 zrender 中                effectShape.effectAnimator = zr.animation.animate(effectShape.style, { loop: effect.loop })                    .when(duration, {                        x: x2,                        y: y2                    })                    .during(function () {                        if (! isLarge) {                            zr.modShape(effectShape);                        }                    })                    .done(effectDone)                    .start();            }            effectShape.effectAnimator.duration = duration;        }        return effectShape;    }    function largeLine(zr, effectList, shape, zlevel) {        var effectShape = new ShapeBundle({            style: {                shapeList: []            },            zlevel: zlevel,            hoverable: false        });        var shapeList = shape.style.shapeList;        var effect = shape.effect;        effectShape.position = shape.position;        var maxDuration = 0;        var subEffectAnimators = [];        for (var i = 0; i < shapeList.length; i++) {            shapeList[i].effect = effect;            var subEffectShape = line(zr, null, shapeList[i], zlevel, true);            var subEffectAnimator = subEffectShape.effectAnimator;            effectShape.style.shapeList.push(subEffectShape);            if (subEffectAnimator.duration > maxDuration) {                maxDuration = subEffectAnimator.duration;            }            if (i === 0) {                effectShape.style.color = subEffectShape.style.color;                effectShape.style.shadowBlur = subEffectShape.style.shadowBlur;                effectShape.style.shadowColor = subEffectShape.style.shadowColor;            }            subEffectAnimators.push(subEffectAnimator);        }        effectList.push(effectShape);        zr.addShape(effectShape);        var clearAllAnimators = function () {            for (var i = 0; i < subEffectAnimators.length; i++) {                subEffectAnimators[i].stop();            }        };        if (maxDuration) {            effectShape.__dummy = 0;            // Proxy animator            var animator = zr.animate(effectShape.id, '', effect.loop)                .when(maxDuration, {                    __dummy: 1                })                .during(function () {                    zr.modShape(effectShape);                })                .done(function () {                    shape.effect.show = false;                    zr.delShape(effectShape.id);                })                .start();            var oldStop = animator.stop;            animator.stop = function () {                clearAllAnimators();                oldStop.call(this);            };        }    }    return {        point : point,        largePoint : largePoint,        line : line,        largeLine: largeLine    };});
 |