PolymerElements / iron-overlay-behavior

Makes an element an overlay with an optional backdrop
41 stars 71 forks source link

clientwidth in polymer is showing ZERO #258

Closed sudipta1411 closed 6 years ago

sudipta1411 commented 6 years ago

I am trying to display a audio waveform in polymer using peaks.js from BBC. https://gist.github.com/anonymous/3a9dc1613a9f8e3de61712df8a1d6a84 code runs perfectly. Based on the gist, I have created a simple polymer webcomponent that should display the audio waveform.


 <!doctype HTML>
        <link rel="import" href="../bower_components/iron-overlay-behavior/iron-overlay-behavior.html">
        <link rel="import" href="../bower_components/iron-flex-layout/iron-flex-layout.html">
        <script type="text/javascript" src="peaks.js"></script>
    <dom-module id="overlay-dialog">
        <template>
            <style is="custom-style">
                :host {
                    background: white;
                    color: black;
                    padding: 24px;
                    border: 2px solid;
                    border-color: #3386ce;
                    width:1100px;
                    height:450px;
                    box-shadow: rgba(0, 0, 0, 0.24) -2px 5px 12px 0px, rgba(0, 0, 0, 0.12) 0px 0px 12px 0px;
                }
            </style>
            <slot></slot>
        </template>
    </dom-overlay>
    <dom-module id="audiowaveform-dialog">
        <template>
            <style>
                 .scrollable {
                     border: 1px solid lightgray;
                     padding: 24px;
                     @apply --layout-scroll;
                 }
                 #container {
                     margin: 24px auto;
                     width: 1000px;
                 }
                 .zoom-container {
                     box-shadow: 3px 3px 20px #919191;
                     margin: 0 0 24px 0;
                     -moz-box-shadow: 3px 3px 20px #919191;
                     -webkit-box-shadow: 3px 3px 20px #919191;
                     line-height: 0;
                 }
                .overview-container {
                    height: 85px;
                }
            </style>
            <overlay-dialog id="dialog" tabindex="-1" no-cancel-on-esc-key
                no-cancel-on-outside-click always-on-top
                on-iron-overlay-closed="closePerformed"
                <h2>Dialog Title</h2>
                <div id="container" class="scrollable">
                    <div class="waveform">
                        <div class="zoom-container" hidden="">
                            <div class="konvajs-content" role="presentation" 
                                style="position: relative; width: 1000px; height: 200px;">
                                <canvas width="1000" height="200" style="padding: 0px; margin: 0px; border: 0px; background: transparent; position: absolute; top: 0px; left: 0px; width: 1000px; height: 200px;">
                                </canvas>
                                <canvas width="1000" height="200" style="padding: 0px; margin: 0px; border: 0px; background: transparent; position: absolute; top: 0px; left: 0px; width: 1000px; height: 200px;">
                                </canvas>
                                <canvas width="1000" height="200" style="padding: 0px; margin: 0px; border: 0px; background: transparent; position: absolute; top: 0px; left: 0px; width: 1000px; height: 200px;">
                                </canvas>
                                <canvas width="1000" height="200" style="padding: 0px; margin: 0px; border: 0px; background: transparent; position: absolute; top: 0px; left: 0px; width: 1000px; height: 200px;">
                                </canvas>
                                <canvas width="1000" height="200" style="padding: 0px; margin: 0px; border: 0px; background: transparent; position: absolute; top: 0px; left: 0px; width: 1000px; height: 200px;">
                                </canvas>
                            </div>
                        </div>
                        <div class="overview-container" hidden="">
                            <div class="konvajs-content" role="presentation" style="position: relative; width: 1000px; height: 85px;">
                                <canvas width="1000" height="85" style="padding: 0px; margin: 0px; border: 0px; background: transparent; position: absolute; top: 0px; left: 0px; width: 1000px; height: 85px;">
                                </canvas>
                                <canvas width="1000" height="85" style="padding: 0px; margin: 0px; border: 0px; background: transparent; position: absolute; top: 0px; left: 0px; width: 1000px; height: 85px;">
                                </canvas>
                                <canvas width="1000" height="85" style="padding: 0px; margin: 0px; border: 0px; background: transparent; position: absolute; top: 0px; left: 0px; width: 1000px; height: 85px;">
                                </canvas>
                                <canvas width="1000" height="85" style="padding: 0px; margin: 0px; border: 0px; background: transparent; position: absolute; top: 0px; left: 0px; width: 1000px; height: 85px;">
                                </canvas>
                                <canvas width="1000" height="85" style="padding: 0px; margin: 0px; border: 0px; background: transparent; position: absolute; top: 0px; left: 0px; width: 1000px; height: 85px;">
                                </canvas>
                                <canvas width="1000" height="85" style="padding: 0px; margin: 0px; border: 0px; background: transparent; position: absolute; top: 0px; left: 0px; width: 1000px; height: 85px;">
                                </canvas>
                            </div>
                        </div>
                    </div>
                </div>
                <div id="audio-controls">
                    <audio controls="controls" id='audiowaveform'>
                        <source src="sample_21.wav" type="audio/mpeg">
                        Your browser does not support the audio element.
                    </audio>
                    <button data-action="zoom-in">Zoom in</button>
                    <button data-action="zoom-out">Zoom out</button>
                    <button data-action="add-segment">Add a Segment at current time</button>
                    <button data-action="add-point">Add a Point at current time</button>
                    <button data-action="log-data">Log segments/points</button>
                    <button data-action="loop">Loop</button>
                </div>
                <!--p> Hello World</p>
                <p class="scrollable">
                </p-->
                <vaadin-button on-click="closeDialog">Close</vaadin-button>
            </overlay-dialog>
        </template>
        <script>
            Polymer({
                is: 'overlay-dialog',
                behaviors: [Polymer.IronOverlayBehavior]
            });
            Polymer({
                is: 'audiowaveform-dialog',
                properties: {
                    isOpened: {
                        type: Boolean,
                        value: false
                    },
                    mediaType: {
                        type: String,
                        value: 'audio/mp3'
                    },
                    mediaSrc: {
                        type: String,
                    },
                    options: {
                        type: Object,
                        value: {
                            container: null,
                            mediaElement: null,
                            dataUri: {
                                arraybuffer: 'sample_21.dat'
                            },
                            zoomLevels : [8],
                            flags: {
                                segFlag : true,
                                segCallback : function(cb) {
                                    /*var times = cb();
                                    times.x = 'hello';
                                    console.log(times);
                                    modal.show();*/
                                },
                                loopFlag : false,
                                loopCallback :function(cb) {
                                    var times = cb();
                                    console.log(times);
                                    audio.addEventListener('timeupdate', function(){});
                                }
                            },
                            keyboard: false
                        }
                    }
                },
                observers: [
                    '_mediaChanged(mediaSrc)'
                ],
                ready: function() {
                    this.options.container = Polymer.dom(this.root).querySelector('#container');
                    this.options.mediaElement = Polymer.dom(this.root).querySelector('audio');
                },
                /*attached: function() {
                    this.async(function() {
                        console.log("clientWidth :" + this.$.container.clientWidth);
                    }, 5000);
                },*/
                showAudioDialog: function() {
                    console.log("showAudioDialog");
                    if(!this.isOpened) {
                        this.$.dialog.opened = true;
                        this.isOpened = true;
                    } else
                        console.log("Dialog already opened");
                },
                closeDialog: function() {
                    this.$.dialog.opened = false;
                    this.isOpened = false;
                },
                closePerformed: function(e) {
                    console.log("closePerformed");
                    console.log(e);
                    console.log(this.mediaSrc);
                },
                _mediaChanged: function(mediaSrc) {
                    console.log("_mediaChanged");
                    /*this.options.container = Polymer.dom(this.$.container);
                    this.options.mediaElement = Polymer.dom(this.root).querySelector('audio');*/
                    console.log(this.options);

                    var peaksInstance = peaks.init(this.options);

                }
            });
        </script>
    </dom-module>

When the code is run, the peaks.js throws an

error:Uncaught TypeError: [Peaks.init] Please ensure that the container has a width.

On further investigation, I have found that the "this.$.options.container.clientwidth" is 0. Whereas in the original example code it is 1000. Can someone please point out where am I doing things the wrong way. I am new to this polymer and any help is greatly appreciated. Thank you.

valdrinkoshi commented 6 years ago

When do you check the clientWidth? Initially, the dialog will be display: none, hence everything inside it will have 0 dimensions. You need to open the dialog, and then you can measure the content's size. Since the opening is asynchronous, you can listen for the event iron-overlay-opened to know that the dialog has been fully opened

sudipta1411 commented 6 years ago

Thanks. This worked.