<!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, svg {
                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(null, null, {
                    width: 500,
                    height: 500,
                    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: config.backgroundColor,
                        graphic: {
                            elements: createElements()
                        }
                    });

                    document.getElementById('main').innerHTML = chart.renderToSVGString();
                }

                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);
            });
        </script>
    </body>
</html>

