Preload image to avoid image flicker on play
authorymh <ymh.work@gmail.com>
Sat, 19 Oct 2024 01:34:55 +0200
changeset 1075 92cb33eb7a75
parent 1074 231ea5ea7de4
child 1076 510fd2a482f4
Preload image to avoid image flicker on play
src/widgets/AnnotationsList.js
--- a/src/widgets/AnnotationsList.js	Fri Oct 18 10:24:57 2024 +0200
+++ b/src/widgets/AnnotationsList.js	Sat Oct 19 01:34:55 2024 +0200
@@ -4,7 +4,29 @@
 import _ from "lodash";
 import jQuery from "jquery";
 
+const IsImageOk = function (img) {
+  // During the onload event, IE correctly identifies any images that
+  // weren’t downloaded as not complete. Others should too. Gecko-based
+  // browsers act like NS4 in that they report this incorrectly.
+  if (!img.complete) {
+      return false;
+  }
+
+  // However, they do have two very useful properties: naturalWidth and
+  // naturalHeight. These give the true size of the image. If it failed
+  // to load, either of these should be zero.
+  if (img.naturalWidth === 0) {
+      return false;
+  }
+
+  // No other way of checking: assume it’s ok.
+  return true;
+}
+
 const AnnotationsList = function (ns) {
+
+  const thumbnailBuffer = {};
+
   return class extends ns.Widgets.Widget {
     constructor(player, config) {
       super(player, config);
@@ -278,7 +300,7 @@
       '<li class="Ldt-AnnotationsList-li Ldt-Highlighter-Annotation Ldt-TraceMe" data-annotation="{{ id }}" data-begin="{{ begin_ms }}" data-end="{{ end_ms }}" trace-info="annotation-id:{{id}}, media-id:{{media_id}}" style="{{specific_style}}">' +
       '<div data-annotation="{{ id }}" class="Ldt-AnnotationsList-ThumbContainer Ldt-AnnotationsList-Annotation-Screen Ldt-AnnotationsList-Annotation-ScreenMain">' +
       '<a {{#url}}href="{{url}}"{{/url}} draggable="true">' +
-      '<img title="{{^external}}{{ begin }} - {{ end }}{{/external}}{{#external}}{{l10n.external_annotation}}{{/external}}" class="Ldt-AnnotationsList-Thumbnail" src="{{thumbnail}}" />' +
+      '<img title="{{^external}}{{ begin }} - {{ end }}{{/external}}{{#external}}{{l10n.external_annotation}}{{/external}}" class="Ldt-AnnotationsList-Thumbnail" id="{{thumbnailId}}" />' +
       '{{#external}}<div title="{{l10n.external_annotation}}" class="Ldt-AnnotationsList-External-Icon"></div>{{/external}}' +
       "</a>" +
       "</div>" +
@@ -386,10 +408,10 @@
     importAnnotations() {
       var widget = this;
       var $ = jQuery;
-      var textarea = $("<textarea>");
-      var el = $("<div>")
+      var textarea = jQuery("<textarea>");
+      var el = jQuery("<div>")
         .append(
-          $("<span>")
+          jQuery("<span>")
             .addClass("importAnnotationsLabel")
             .text(widget.messages.import_annotations)
         )
@@ -404,7 +426,7 @@
             {
               text: "Close",
               click: function () {
-                $(this).dialog("close");
+                jQuery(this).dialog("close");
               },
             },
             // { text: "Load", click: function () {
@@ -656,11 +678,13 @@
               _annotation.project != _this.source.projectId ? true : false,
             _title = "",
             _description = _annotation.description,
+            _thumbnailId = `thumb_${_annotation.id}`,
             _thumbnail =
               typeof _annotation.thumbnail !== "undefined" &&
               _annotation.thumbnail
                 ? _annotation.thumbnail
                 : _this.default_thumbnail;
+                    
           if (_this.show_creator) {
             if (_annotation.creator) {
               var _users = [],
@@ -721,7 +745,7 @@
             show_timecode: _this.show_timecode,
             show_end_time: _this.show_end_time,
             show_title: _this.show_title && _title,
-            thumbnail: _thumbnail,
+            thumbnailId: _thumbnailId,
             url: _url,
             tags: _tags,
             specific_style:
@@ -796,13 +820,13 @@
               _this.$.find(".Ldt-AnnotationsList-li").removeClass("selected");
             };
           _el
-            .mouseover(function () {
+            .on("mouseover",function () {
               _annotation.trigger("select");
             })
-            .mouseout(function () {
+            .on("mouseout",function () {
               _annotation.trigger("unselect");
             })
-            .click(function () {
+            .on("click",function () {
               if (_this.filter_by_segments && _this.media.getTimeRange()) {
                 _ann_time = (_annotation.begin + _annotation.end) / 2;
                 if (
@@ -815,6 +839,28 @@
               _annotation.trigger("click");
             })
             .appendTo(_this.list_$);
+
+          
+          let img = thumbnailBuffer[_thumbnail];
+          if(typeof(img) == "undefined") {
+            img = new Image();
+            thumbnailBuffer[_thumbnail] = img;
+          }
+          console.log("Thumnailimg", jQuery(`#${_thumbnailId}`,_el).attr('src'));
+          if(img.src && IsImageOk(img)) {
+            jQuery(`#${_thumbnailId}`,_el).attr('src', img.src);
+          } else {
+            img.onload = function() {
+              jQuery(`#${_thumbnailId}`,_el).attr('src', img.src);
+            };
+            img.onerror = function() {
+              img.src = _this.default_thumbnail;
+              const elthumbnail = jQuery(`#${_thumbnailId}`,_el);
+              elthumbnail.attr('src', _this.default_thumbnail);
+
+            };
+            img.src = _thumbnail;
+          }
           ns.attachDndData(_el.find("[draggable]"), {
             title: _title,
             description: _description,
@@ -855,23 +901,23 @@
             if (insertion_point === undefined) insertion_point = _this;
 
             // Insert input element
-            var input_element = $(
+            var input_element = jQuery(
               _this.dataset.editable_type === "multiline"
                 ? "<textarea>"
                 : "<input>"
             )
               .addClass("editableInput")
-              .insertBefore($(insertion_point));
+              .insertBefore(jQuery(insertion_point));
             input_element[0].value = _this.dataset.editable_value;
-            $(input_element).show().focus();
-            $(_this).addClass("editing");
+            jQuery(input_element).show().focus();
+            jQuery(_this).addClass("editing");
 
             function feedback(color) {
               // Give some feedback
-              $(_this).removeClass("editing");
+              jQuery(_this).removeClass("editing");
               input_element.remove();
-              var previous_color = $(_this).css("background-color");
-              $(_this)
+              var previous_color = jQuery(_this).css("background-color");
+              jQuery(_this)
                 .stop()
                 .css("background-color", color)
                 .animate({ backgroundColor: previous_color }, 1000);
@@ -908,7 +954,7 @@
                 }
                 _this.dataset.editable_value = n;
                 n = val;
-                $(_this).text(val);
+                jQuery(_this).text(val);
               }
 
               // We cannot use .getElement since it fetches
@@ -931,7 +977,7 @@
                 feedback(feedback_ok);
               }
             }
-            $(input_element)
+            jQuery(input_element)
               .bind("keydown", function (e) {
                 if (e.which == 13) {
                   e.preventDefault();
@@ -981,7 +1027,7 @@
               widget.on_edit(_annotation);
             } else {
               // Edit annotation title. We have to specify the insertion point.
-              var element = $(this)
+              var element = jQuery(this)
                 .parents(".Ldt-AnnotationsList-li")
                 .find(".Ldt-AnnotationsList-TitleContent.Ldt-live-editable");
               edit_element(element[0]);
@@ -1030,7 +1076,7 @@
                 contentType: "application/json",
                 data: _export.serialize(),
                 success: function (_data) {
-                  $(this).addClass("published");
+                  jQuery(this).addClass("published");
                   // Save the published information
                   var an = get_local_annotation(_annotation.id);
                   // FIXME: handle "published" tag