<!DOCTYPE html>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
-->


<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <script src="lib/simpleRequire.js"></script>
        <script src="lib/config.js"></script>
        <script src="lib/jquery.min.js"></script>
        <script src="lib/facePrint.js"></script>
        <script src="lib/testHelper.js"></script>
        <script src="lib/perlin.js"></script>
        <script src="lib/dat.gui.min.js"></script>
        <!-- <script src="ut/lib/canteen.js"></script> -->
        <link rel="stylesheet" href="lib/reset.css" />
    </head>
    <body>
        <style>
            body, #main {
                margin: 0;
                width: 100%;
                height: 100%;
            }
            img {
                position: absolute;
                left: 0;
                top: 0;
            }
        </style>


        <div id="main"></div>

        <script>
            require(['echarts'/*, 'map/js/china' */], function (echarts) {
                // During transition
                var chart = echarts.init(document.getElementById('main'), null, {
                    width: window.innerWidth,
                    height: window.innerHeight,
                    // renderer: 'svg',
                    // ssr: true
                })

                const width = chart.getWidth();
                const height = chart.getHeight();

                const config = {
                    minSize: 3,
                    maxSize: 30,

                    color0: '#ffa500',
                    color1: '#800080',

                    backgroundColor: '#8e2ed2',

                    duration: 4000,

                    frequency: 500,
                    offsetX: 0,
                    offsetY: 100
                }

                function createElements() {
                    const elements = [];
                    for (let x = 20; x < width; x += 40) {
                        for (let y = 20; y < height; y += 40) {
                            const rand = noise.perlin2(
                                x / config.frequency + config.offsetX,
                                y / config.frequency + config.offsetY
                            );
                            elements.push({
                                type: 'circle',
                                x, y,
                                style: {
                                    fill: config.color1
                                },
                                shape: {
                                    r: config.maxSize
                                },
                                keyframeAnimation: {
                                    duration: config.duration,
                                    loop: true,
                                    delay: (rand - 1) * 4000,
                                    keyframes: [{
                                        percent: 0.5,
                                        easing: 'sinusoidalInOut',
                                        style: {
                                            fill: config.color0
                                        },
                                        scaleX: config.minSize / config.maxSize,
                                        scaleY: config.minSize / config.maxSize
                                    }, {
                                        percent: 1,
                                        easing: 'sinusoidalInOut',
                                        style: {
                                            fill: config.color1
                                        },
                                        scaleX: 1,
                                        scaleY: 1
                                    }]
                                }
                            });
                        }
                    }
                    return elements;
                }

                function update() {
                    chart.setOption({
                        // backgroundColor: {
                        //     type: 'linear',
                        //     x: 0,
                        //     y: 0,
                        //     x2: 1,
                        //     y2: 0,
                        //     colorStops: [{
                        //         offset: 0,
                        //         color: '#8e2de2'
                        //     }, {
                        //         offset: 1,
                        //         color: '#4a00e0'
                        //     }]
                        // },
                        backgroundColor: config.backgroundColor,
                        graphic: {
                            elements: createElements()
                        }
                    })
                }

                update();


                var gui = new dat.GUI();

                gui.add(config, 'frequency', 10, 1000).onChange(update);
                gui.add(config, 'offsetX', 0, 1000).onChange(update);
                gui.add(config, 'offsetY', 0, 1000).onChange(update);

                gui.add(config, 'minSize', 0, 100).onChange(update);
                gui.add(config, 'maxSize', 0, 100).onChange(update);
                gui.add(config, 'duration', 100, 100000).onChange(update);

                gui.addColor(config, 'backgroundColor').onChange(update);
                gui.addColor(config, 'color0').onChange(update);
                gui.addColor(config, 'color1').onChange(update);

                // console.log(chart.renderToSVGString());
                // var blob = new Blob([chart.renderToSVGString()], { type: 'image/svg+xml' });
                // var a = document.createElement('a');
                // a.download = 'aaa.svg';
                // a.href = URL.createObjectURL(blob);
                // a.style.display = "none";
                // a.click();
            });
        </script>
    </body>
</html>

