反馈已提交

网络繁忙

当前为10.0版本文档,只有最新版本的文档支持在线编辑修改,如果想创建/编辑文档,请移步至 最新版帮助文档

JS 实现文字雪花效果

  • 文档创建者:Kevin-s
  • 历史版本:11
  • 最近更新:RosieY 于 2021-02-02
  • 1. 概述

    1.1 预期效果

    通过 FineReport 集成文字雪花特效,可以根据自己的要求对代码进行修改,直接修改文字即可。效果图如下:

    JS 文字雪花特效.gif

    1.2 实现思路

    通过 HTIML 和 JS 可以实现集成文字雪花特效。

    2. 示例

    2.1 准备模板

    1)新建普通报表,在报表内合并单元格,并在单元格输入 HTML 代码,单元格显示方式选择「用 HTML 显示内容」,如下图所示:

    111.png

    HTML 代码如下:

    <div class="cs">
        <img src="/webroot/scripts/css/Kevin.jpg" id="logo">  
    </div> 
    <canvas class="canvas" width="1020" height="800"></canvas> 
    <p class="text" style="color: #ed3073;">
       我已经度过了
       <br/>     
       <span id="span_dt_dt"></span> 
    </p> 
    <p class="text" style="color: #ed3073;" id="text">
        我希望余生可以慢点
        <br/>     
    <span id="span_dt_dt1"></span> 
    </p>

    2)引入中间头像图片,放入路径:%FR_HOME%\webapps\webroot\scripts\css下,文件名称为:Kevin

    点击可下载图片:Kevin.jpg

    2.2 引入 CSS

    1)将 文字效果.css 放到%FR_HOME%\webapps\webroot\scripts\css路径下。

    点击可下载:文字效果.css

    2)点击菜单栏「模板>模板Web属性>引用 CSS」,将 文字效果.css 引入。如下图所示:

    image.png

    2.3 添加事件

    点击「模板>模板Web属性>数据分析设置」,选择「为该模板单独设置」,增加一个「加载结束」事件,如下图所示:

    JavaScript 代码如下:

    function show_date_time() {
            window.setTimeout("show_date_time()", 1000);
            BirthDay = new Date("2/23/1996 00:00:00");//这个日期是可以修改的
            today = new Date();
            timeold = (today.getTime() - BirthDay.getTime());//计算出今天到你出生的时间差,毫秒数
            sectimeold = timeold / 1000 //日期转化成秒
            secondsold = Math.floor(sectimeold);
            msPerDay = 24 * 60 * 60 * 1000
            e_daysold = timeold / msPerDay
            daysold = Math.floor(e_daysold);  //度过多少天
            e_hrsold = (e_daysold - daysold) * 24;
            hrsold = Math.floor(e_hrsold);  //度过多少小时
            e_minsold = (e_hrsold - hrsold) * 60;
            minsold = Math.floor((e_hrsold - hrsold) * 60); //度过多少分钟
            seconds = Math.floor((e_minsold - minsold) * 60); //度过多少秒
            span_dt_dt.innerHTML = daysold + "天" + hrsold + "小时" + minsold + "分" + seconds + "秒";
           
        }
        show_date_time();
         //以上模块主要是呈现日期模块,可集成到其他JS代码中
        var S = {
            init: function () {
                S.Drawing.init('.canvas');
                document.body.classList.add('body--ready');
                //想说的话
                S.UI.simulate("zhuzhu | Thanks| --Kevin|#countdown 3|#time");
                S.Drawing.loop(function () {
                    S.Shape.render();
                });
            }
        };//JSON的写法,方便调用里面的变量和function
        S.Drawing = (function () {
            var canvas,
                context,
                renderFn,
                requestFrame = window.requestAnimationFrame ||
                    window.webkitRequestAnimationFrame ||
                    window.mozRequestAnimationFrame ||
                    window.oRequestAnimationFrame ||
                    window.msRequestAnimationFrame ||
                    function (callback) {
                        window.setTimeout(callback, 1000 / 60);
                    };//实现重复动画效果的方法,以上封装后可兼容所有浏览器
            return {
                init: function (el) {
                    canvas = document.querySelector(el);
                    context = canvas.getContext('2d');
                    this.adjustCanvas();
                    window.addEventListener('resize', function (e) {
                        S.Drawing.adjustCanvas();
                    });
                },//初始画布
                loop: function (fn) {
                    renderFn = !renderFn ? fn : renderFn;
                    this.clearFrame();
                    renderFn();
                    requestFrame.call(window, this.loop.bind(this));
                },//循环动画
                adjustCanvas: function () {
                    canvas.width = window.innerWidth - 100;
                    canvas.height = window.innerHeight - 30;
                },//设置屏幕自适应画布
                clearFrame: function () {
                    context.clearRect(0, 0, canvas.width, canvas.height);
                },//清空画布
                getArea: function () {
                    return {w: canvas.width, h: canvas.height};
                },//获取画布长宽
                drawCircle: function (p, c) {
                    context.fillStyle = c.render();
                    context.beginPath();
                    context.arc(p.x, p.y, p.z, 0, 2 * Math.PI, true);
                    context.closePath();
                    context.fill();
                }//画小圆
            };
        }());
        S.UI = (function () {
            var interval,
                currentAction,
                time,
                maxShapeSize = 30,
                sequence = [],
                cmd = '#';
            function formatTime(date) {
                var h = date.getHours(),
                    m = date.getMinutes(),
                    m = m < 10 ? '0' + m : m;
                return h + ':' + m;
            }//获取到小时和分钟时间
            function getValue(value) {
                return value && value.split(' ')[1];
            }//文字分割
            function getAction(value) {
                value = value && value.split(' ')[0];
                return value && value[0] === cmd && value.substring(1);
            }//文字处理
            function timedAction(fn, delay, max, reverse) {
                clearInterval(interval);
                currentAction = reverse ? max : 1;
                fn(currentAction);
                if (!max || (!reverse && currentAction < max) || (reverse && currentAction > 0)) {
                    interval = setInterval(function () {
                        currentAction = reverse ? currentAction - 1 : currentAction + 1;
                        fn(currentAction);
                        if ((!reverse && max && currentAction === max) || (reverse && currentAction === 0)) {
                            clearInterval(interval);
                        }
                    }, delay);
                }
            }
            function performAction(value) {
                var action,
                    value,
                    current;
                sequence = typeof (value) === 'object' ? value : sequence.concat(value.split('|'));
                timedAction(function (index) {
                    current = sequence.shift();
                    action = getAction(current);
                    value = getValue(current);
                    switch (action) {
                        case 'countdown':
                            value = parseInt(value) || 10;
                            value = value > 0 ? value : 10;
                            timedAction(function (index) {
                                if (index === 0) {
                                    if (sequence.length === 0) {
                                        S.Shape.switchShape(S.ShapeBuilder.letter(''));
                                    } else {
                                        performAction(sequence);
                                    }
                                } else {
                                    S.Shape.switchShape(S.ShapeBuilder.letter(index), true);
                                }
                            }, 1000, value, true);
                            break;
                        case 'rectangle':
                            value = value && value.split('x');
                            value = (value && value.length === 2) ? value : [maxShapeSize, maxShapeSize / 2];
                            S.Shape.switchShape(S.ShapeBuilder.rectangle(Math.min(maxShapeSize, parseInt(value[0])), Math.min(maxShapeSize, parseInt(value[1]))));
                            break;
                        case 'circle':
                            value = parseInt(value) || maxShapeSize;
                            value = Math.min(value, maxShapeSize);
                            S.Shape.switchShape(S.ShapeBuilder.circle(value));
                            break;
                        case 'time':
                            var t = formatTime(new Date());
                            if (sequence.length > 0) {
                                S.Shape.switchShape(S.ShapeBuilder.letter(t));
                            } else {
                                timedAction(function () {
                                    t = formatTime(new Date());
                                    if (t !== time) {
                                        time = t;
                                        S.Shape.switchShape(S.ShapeBuilder.letter(time));
                                    }
                                }, 1000);
                            }
                            break;
                        default:
                            S.Shape.switchShape(S.ShapeBuilder.letter(current[0] === cmd ? 'HacPai' : current));
                    }
                }, 2000, sequence.length);
            }
            return {
                simulate: function (action) {
                    performAction(action);
                }//文字处理
            };
        }());//最终实现文字处理,以及时间,倒计时等处理
        S.Point = function (args) {
            this.x = args.x;
            this.y = args.y;
            this.z = args.z;
            this.a = args.a;
            this.h = args.h;
        };//坐标方法
        S.Color = function (r, g, b, a) {
            this.r = r;
            this.g = g;
            this.b = b;
            this.a = a;
        };//颜色方法
        S.Color.prototype = {
            render: function () {
                return 'rgba(' + this.r + ',' + +this.g + ',' + this.b + ',' + this.a + ')';
            }
        };//颜色调用绘制使用
        S.Dot = function (x, y) {
            this.p = new S.Point({
                x: x,
                y: y,
                z: 5,
                a: 1,
                h: 0
            });
            this.e = 0.07;
            this.s = true;
            this.c = new S.Color(255, 255, 255, this.p.a);
            this.t = this.clone();
            this.q = [];
        };//小圆点方法
        S.Dot.prototype = {
            clone: function () {
                return new S.Point({
                    x: this.x,
                    y: this.y,
                    z: this.z,
                    a: this.a,
                    h: this.h
                });
            },
            _draw: function () {
                this.c.a = this.p.a;
                S.Drawing.drawCircle(this.p, this.c);
            },
            _moveTowards: function (n) {
                var details = this.distanceTo(n, true),
                    dx = details[0],
                    dy = details[1],
                    d = details[2],
                    e = this.e * d;
                if (this.p.h === -1) {
                    this.p.x = n.x;
                    this.p.y = n.y;
                    return true;
                }
                if (d > 1) {
                    this.p.x -= ((dx / d) * e);
                    this.p.y -= ((dy / d) * e);
                } else {
                    if (this.p.h > 0) {
                        this.p.h--;
                    } else {
                        return true;
                    }
                }
                return false;
            },
            _update: function () {
                if (this._moveTowards(this.t)) {
                    var p = this.q.shift();
                    if (p) {
                        this.t.x = p.x || this.p.x;
                        this.t.y = p.y || this.p.y;
                        this.t.z = p.z || this.p.z;
                        this.t.a = p.a || this.p.a;
                        this.p.h = p.h || 0;
                    } else {
                        if (this.s) {
                            this.p.x -= Math.sin(Math.random() * 3.142);
                            this.p.y -= Math.sin(Math.random() * 3.142);
                        } else {
                            this.move(new S.Point({
                                x: this.p.x + (Math.random() * 50) - 25,
                                y: this.p.y + (Math.random() * 50) - 25
                            }));
                        }
                    }
                }
                d = this.p.a - this.t.a;
                this.p.a = Math.max(0.1, this.p.a - (d * 0.05));
                d = this.p.z - this.t.z;
                this.p.z = Math.max(1, this.p.z - (d * 0.05));
            },
            distanceTo: function (n, details) {
                var dx = this.p.x - n.x,
                    dy = this.p.y - n.y,
                    d = Math.sqrt(dx * dx + dy * dy);
                return details ? [dx, dy, d] : d;
            },
            move: function (p, avoidStatic) {
                if (!avoidStatic || (avoidStatic && this.distanceTo(p) > 1)) {
                    this.q.push(p);
                }
            },
            render: function () {
                this._update();
                this._draw();
            }
        };//小圆点圆形绘制
        S.ShapeBuilder = (function () {
            var gap = 13,
                shapeCanvas = document.createElement('canvas'),
                shapeContext = shapeCanvas.getContext('2d'),
                fontSize = 500,
                fontFamily = 'Avenir, Helvetica Neue, Helvetica, Arial, sans-serif';
            function fit() {
                shapeCanvas.width = Math.floor(window.innerWidth / gap) * gap;
                shapeCanvas.height = Math.floor(window.innerHeight / gap) * gap;
                shapeContext.fillStyle = 'red';
                shapeContext.textBaseline = 'middle';
                shapeContext.textAlign = 'center';
            }
            function processCanvas() {
                var pixels = shapeContext.getImageData(0, 0, shapeCanvas.width, shapeCanvas.height).data;
                dots = [],
                    pixels,
                    x = 0,
                    y = 0,
                    fx = shapeCanvas.width,
                    fy = shapeCanvas.height,
                    w = 0,
                    h = 0;
                for (var p = 0; p < pixels.length; p += (4 * gap)) {
                    if (pixels[p + 3] > 0) {
                        dots.push(new S.Point({
                            x: x,
                            y: y
                        }));
                        w = x > w ? x : w;
                        h = y > h ? y : h;
                        fx = x < fx ? x : fx;
                        fy = y < fy ? y : fy;
                    }
                    x += gap;
                    if (x >= shapeCanvas.width) {
                        x = 0;
                        y += gap;
                        p += gap * 4 * shapeCanvas.width;
                    }
                }
                return {dots: dots, w: w + fx, h: h + fy};
            }
            function setFontSize(s) {
                shapeContext.font = 'bold ' + s + 'px ' + fontFamily;
            }
            function isNumber(n) {
                return !isNaN(parseFloat(n)) && isFinite(n);
            }
            function init() {
                fit();
                window.addEventListener('resize', fit);
            }
            // Init
            init();
            return {
                imageFile: function (url, callback) {
                    var image = new Image(),
                        a = S.Drawing.getArea();
                    image.onload = function () {
                        shapeContext.clearRect(0, 0, shapeCanvas.width, shapeCanvas.height);
                        shapeContext.drawImage(this, 0, 0, a.h * 0.6, a.h * 0.6);
                        callback(processCanvas());
                    };
                    image.onerror = function () {
                        callback(S.ShapeBuilder.letter('What?'));
                    };
                    image.src = url;
                },
                circle: function (d) {
                    var r = Math.max(0, d) / 2;
                    shapeContext.clearRect(0, 0, shapeCanvas.width, shapeCanvas.height);
                    shapeContext.beginPath();
                    shapeContext.arc(r * gap, r * gap, r * gap, 0, 2 * Math.PI, false);
                    shapeContext.fill();
                    shapeContext.closePath();
                    return processCanvas();
                },
                letter: function (l) {
                    var s = 0;
                    setFontSize(fontSize);
                    s = Math.min(fontSize,
                        (shapeCanvas.width / shapeContext.measureText(l).width) * 0.8 * fontSize,
                        (shapeCanvas.height / fontSize) * (isNumber(l) ? 1 : 0.45) * fontSize);
                    setFontSize(s);
                    shapeContext.clearRect(0, 0, shapeCanvas.width, shapeCanvas.height);
                    shapeContext.fillText(l, shapeCanvas.width / 2, shapeCanvas.height / 2);
                    return processCanvas();
                },
                rectangle: function (w, h) {
                    var dots = [],
                        width = gap * w,
                        height = gap * h;
                    for (var y = 0; y < height; y += gap) {
                        for (var x = 0; x < width; x += gap) {
                            dots.push(new S.Point({
                                x: x,
                                y: y
                            }));
                        }
                    }
                    return {dots: dots, w: width, h: height};
                }
            };
        }());//画布添加图片,文字,圆等设置,这个主要是letter
        S.Shape = (function () {
            var dots = [],
                width = 0,
                height = 0,
                cx = 0,
                cy = 0;
            function compensate() {
                var a = S.Drawing.getArea();
                cx = a.w / 2 - width / 2;
                cy = a.h / 2 - height / 2;
            }
            return {
                shuffleIdle: function () {
                    var a = S.Drawing.getArea();
                    for (var d = 0; d < dots.length; d++) {
                        if (!dots[d].s) {
                            dots[d].move({
                                x: Math.random() * a.w,
                                y: Math.random() * a.h
                            });
                        }
                    }
                },
                switchShape: function (n, fast) {
                    var size,
                        a = S.Drawing.getArea();
                    width = n.w;
                    height = n.h;
                    compensate();
                    if (n.dots.length > dots.length) {
                        size = n.dots.length - dots.length;
                        for (var d = 1; d <= size; d++) {
                            dots.push(new S.Dot(a.w / 2, a.h / 2));
                        }
                    }
                    var d = 0,
                        i = 0;
                    while (n.dots.length > 0) {
                        i = Math.floor(Math.random() * n.dots.length);
                        dots[d].e = fast ? 0.25 : (dots[d].s ? 0.14 : 0.11);
                        if (dots[d].s) {
                            dots[d].move(new S.Point({
                                z: Math.random() * 20 + 10,
                                a: Math.random(),
                                h: 18
                            }));
                        } else {
                            dots[d].move(new S.Point({
                                z: Math.random() * 5 + 5,
                                h: fast ? 18 : 30
                            }));
                        }
                        dots[d].s = true;
                        dots[d].move(new S.Point({
                            x: n.dots[i].x + cx,
                            y: n.dots[i].y + cy,
                            a: 1,
                            z: 5,
                            h: 0
                        }));
                        n.dots = n.dots.slice(0, i).concat(n.dots.slice(i + 1));
                        d++;
                    }
                    for (var i = d; i < dots.length; i++) {
                        if (dots[i].s) {
                            dots[i].move(new S.Point({
                                z: Math.random() * 20 + 10,
                                a: Math.random(),
                                h: 20
                            }));
                            dots[i].s = false;
                            dots[i].e = 0.04;
                            dots[i].move(new S.Point({
                                x: Math.random() * a.w,
                                y: Math.random() * a.h,
                                a: 0.3, //.4
                                z: Math.random() * 4,
                                h: 0
                            }));
                        }
                    }
                },
                render: function () {
                    for (var d = 0; d < dots.length; d++) {
                        dots[d].render();
                    }
                }
            };
        }());//区域圆字小圆的随机分布,转换,添加
        S.init();

    2.4 效果预览

    保存模板,点击「数据分析」,效果如上图所示:

    1564488221579110.gif

    注:不支持移动端。

    3. 模板下载

    附件列表


    主题: 决策报表应用
    已经是第一篇
    已经是最后一篇
    • 有帮助
    • 没帮助
    • 只是浏览

    售前咨询电话

    400-811-8890转1

    在线技术支持

    请前往「服务平台」,选择「在线支持」

    热线电话:400-811-8890转2

    总裁办24H投诉

    热线电话:173-1278-1526