<my-canvas title="click me"></my-canvas>

<dom-module id="my-canvas">
    <template>
        <style>
            :host {
                display: block;
                width: 100vw;
                height: 100vh;
                background: grey;
                cursor: crosshair;
            }
        </style>
        <dom-repeat items="{{forms}}" as="form">
            <template>
                <my-form x="{{form.x}}"
                         y="{{form.y}}"
                         color="{{form.color}}"
                         type="{{form.type}}"></my-form>
            </template>
        </dom-repeat>
    </template>
</dom-module>

<dom-module id="shared-styles">
    <template>
        <style>
            :host {
                --my-color: transparent;
                --my-height: 0;
                --my-width: 0;
                --my-x: 0;
                --my-y: 0;
                --my-radius: 0;
            }
        </style>
    </template>
</dom-module>

<dom-module id="my-form">
    <template>
        <style include="shared-styles">
            #container {
                position: absolute;
                background-color: var(--my-color);
                height: var(--my-height);
                width: var(--my-width);
                left: var(--my-x);
                top: var(--my-y);
                border-radius: var(--my-radius);
            }
        </style>
        <div id="container"></div>
    </template>
    <script>
        class Figure {
            set styles(values) {
                Object.keys(values).forEach(elem => this[elem] = values[elem]);
            }

            get styles() {
                return {
                    '--my-height': this.height + 'px',
                    '--my-width': this.width + 'px',
                    '--my-color': this.color,
                    '--my-x': this.x + 'px',
                    '--my-y': this.y + 'px',
                    '--my-radius': this.radius
                }
            }
        }

        class Square extends Figure {
            constructor(args) {
                super().styles = {
                    x: (args.x - (args.size / 2)),
                    y: (args.y - (args.size / 2)),
                    height: args.size,
                    width: args.size,
                    color: args.color
                };
            }
        }

        class Circle extends Figure {
            constructor(args) {
                super().styles = {
                    x: (args.x - (args.size / 2)),
                    y: (args.y - (args.size / 2)),
                    height: args.size,
                    width: args.size,
                    color: args.color,
                    radius: 50 + '%'
                };
            }
        }
    </script>
</dom-module>
 window.addEventListener('WebComponentsReady', () => {
           class MyCanvas extends Polymer.Element {
            static get is() {
                return 'my-canvas';
            }

            static get properties() {
                return {
                    forms: {
                        type: Array,
                        value() {
                            return []
                        }
                    }
                }
            }

            addForm(event) {
                this.push('forms', {
                    color: this.methods.getRandomColor(),
                    type: this.methods.getRandomType(),
                    x: event.clientX,//TODO: add touch
                    y: event.clientY
                });
            }

            get methods() {
                return {
                    getRandomColor() {
                        return '#' + (0x1000000 + (Math.random()) * 0xffffff).toString(16).substr(1, 6);
                    },
                    getRandomType() {
                        const enumType = ['circle', 'square'];

                        return enumType[Math.floor(Math.random() * enumType.length)];
                    }
                }
            }

            connectedCallback() {
                super.connectedCallback();
                this.addEventListener('click', (event) => {
                    this.addForm(event);
                });
            }
        }
        class MyForm extends Polymer.Element {
            static get is() {
                return 'my-form';
            }

            static get properties() {
                return {
                    x: Number,
                    y: Number,
                    color: String,
                    type: String
                }
            }

            get methods() {
                return {
                    getRandomInt: (min, max) => {
                        return Math.floor(Math.random() * (max - min + 1)) + min;
                    }
                }
            }

            disconnectedCallback() {
                //...
            }

            connectedCallback() {
                super.connectedCallback();

                switch (this.type) {
                    case 'square': {
                        const square = new Square({
                            x: this.x,
                            y: this.y,
                            color: this.color,
                            size: this.methods.getRandomInt(20, 150),
                        });
                        this.updateStyles(square.styles);

                        break;
                    }
                    case 'circle': {
                        const circle = new Circle({
                            x: this.x,
                            y: this.y,
                            color: this.color,
                            size: this.methods.getRandomInt(30, 200)
                        });
                        this.updateStyles(circle.styles);

                        break;
                    }
                    default: {
                        throw new Error('wrong type exception');
                    }
                }

                this.$.container.addEventListener('click', (event) => {
                    this.remove();
                    event.stopImmediatePropagation();
                });
            }
        }

        customElements.define(MyForm.is, MyForm);
        customElements.define(MyCanvas.is, MyCanvas);
 });

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.