GIF file wont load no matter what I do

I uploaded a new GIF asset to my project. It is the same file size as the old one at 3mb, it is a GIF with a transparent background and uploaded successfully to assets.

It just wont load and I get the empty green circle next to the asset when I launch it and the notification: %ccore:schema:warn %cDefault value null does not match type string in component undefined%c color: orange color: inherit color: orange

I’ve tried everything!
It’s the same exact file type as the old GIF that still works if I switch back.

It looks like your AFrame component might not be registering correctly. Could you either share the project in the β€˜support’ workspace or paste the code here so I can take a look?

https://www.8thwall.com/fetchmark/oldflowerco/project
I can’t share because I’m only on a plus plan.

Would you mind sharing your code files here or through DM?

A frame gif shader

/** *** */ (function (modules) {  // webpackBootstrap
/** *** */ 	// The module cache
/** *** */ 	const installedModules = {}

  /** *** */ 	// The require function
  /** *** */ 	function __webpack_require__(moduleId) {
    /** *** */  // Check if module is in cache
    /** *** */ 		if (installedModules[moduleId])
    /** *** */ 			{
      return installedModules[moduleId].exports
    }

    /** *** */  // Create a new module (and put it into the cache)
    /** *** */ 		const module = installedModules[moduleId] = {
      /** *** */ 			exports: {},
      /** *** */ 			id: moduleId,
      /** *** */ 			loaded: false,
      /** *** */}

    /** *** */  // Execute the module function
    /** *** */ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__)

    /** *** */  // Flag the module as loaded
    /** *** */ 		module.loaded = true

    /** *** */  // Return the exports of the module
    /** *** */ 		return module.exports
    /** *** */ 	}

  /** *** */ 	// expose the modules object (__webpack_modules__)
  /** *** */ 	__webpack_require__.m = modules

  /** *** */ 	// expose the module cache
  /** *** */ 	__webpack_require__.c = installedModules

  /** *** */ 	// __webpack_public_path__
  /** *** */ 	__webpack_require__.p = ''

  /** *** */ 	// Load entry module and return exports
  /** *** */ 	return __webpack_require__(0)
/** *** */ }([
/* 0 */
/***/ function (module, exports, __webpack_require__) {
    const _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function (obj) {
      return typeof obj
    } : function (obj) {
      return obj && typeof Symbol === 'function' && obj.constructor === Symbol ? 'symbol' : typeof obj
    }

    const _gifsparser = __webpack_require__(1)

    if (typeof AFRAME === 'undefined') {
      throw 'Component attempted to register before AFRAME was available.'
    }

    /* get util from AFRAME */
    const {parseUrl} = AFRAME.utils.srcLoader
    const {debug} = AFRAME.utils
    // debug.enable('shader:gif:*')

    debug.enable('shader:gif:warn')
    const warn = debug('shader:gif:warn')
    const log = debug('shader:gif:debug')

    /* store data so that you won't load same data */
    const gifData = {}

    /* create error message */
    function createError(err, src) {
	  return {status: 'error', src, message: err, timestamp: Date.now()}
    }

    AFRAME.registerShader('gif', {

	  /**
	   * For material component:
	   * @see https://github.com/aframevr/aframe/blob/60d198ef8e2bfbc57a13511ae5fca7b62e01691b/src/components/material.js
	   * For example of `registerShader`:
	   * @see https://github.com/aframevr/aframe/blob/41a50cd5ac65e462120ecc2e5091f5daefe3bd1e/src/shaders/flat.js
	   * For MeshBasicMaterial
	   * @see http://threejs.org/docs/#Reference/Materials/MeshBasicMaterial
	   */

	  schema: {

	    /* For material */
	    color: {type: 'color'},
	    fog: {default: true},

	    /* For texuture */
        src: {default: null},
        autoplay: {default: true},
        transparent: {default: false},
	  },

	  /**
	   * Initialize material. Called once.
	   * @protected
	   */
	  init: function init(data) {
	    log('init', data)
	    log(this.el.components)

        this.__transparent = data.transparent

	    this.__cnv = document.createElement('canvas')
	    this.__cnv.width = 2
	    this.__cnv.height = 2
	    this.__ctx = this.__cnv.getContext('2d')
	    this.__texture = new THREE.Texture(this.__cnv)  // renders straight from a canvas
	    this.__material = {}
	    this.__reset()
	    this.material = new THREE.MeshBasicMaterial({map: this.__texture})
	    this.el.sceneEl.addBehavior(this)
	    this.__addPublicFunctions()
	    return this.material
	  },

	  /**
	   * Update or create material.
	   * @param {object|null} oldData
	   */
	  update: function update(oldData) {
	    log('update', oldData)
	    this.__updateMaterial(oldData)
	    this.__updateTexture(oldData)
	    return this.material
	  },

	  /**
	   * Called on each scene tick.
	   * @protected
	   */
	  tick: function tick(t) {
	    if (!this.__frames || this.paused()) return
	    if (Date.now() - this.__startTime >= this.__nextFrameTime) {
	      this.nextFrame()
	    }
	  },

	  // ================================
	  // =            material            =
	  // ================================

	  /**
	   * Updating existing material.
	   * @param {object} data - Material component data.
	   */
	  __updateMaterial: function __updateMaterial(data) {
	    const {material} = this

	    const newData = this.__getMaterialData(data)
	    Object.keys(newData).forEach((key) => {
	      material[key] = newData[key]
	    })
	  },

	  /**
	   * Builds and normalize material data, normalizing stuff along the way.
	   * @param {Object} data - Material data.
	   * @return {Object} data - Processed material data.
	   */
	  __getMaterialData: function __getMaterialData(data) {
	    return {
	      fog: data.fog,
	      color: new THREE.Color(data.color),
	    }
	  },

	  // ==============================
	  // =            texure            =
	  // ==============================

	  /**
	   * set texure
	   * @private
	   * @param {Object} data
	   * @property {string} status - success / error
	   * @property {string} src - src url
	   * @property {array} times - array of time length of each image
	   * @property {number} cnt - total counts of gif images
	   * @property {array} frames - array of each image
	   * @property {Date} timestamp - created at the texure
	   */

	  __setTexure: function __setTexure(data) {
	    log('__setTexure', data)
	    if (data.status === 'error') {
	      warn(`Error: ${data.message}\nsrc: ${data.src}`)
	      this.__reset()
	    } else if (data.status === 'success' && data.src !== this.__textureSrc) {
	      this.__reset()
	      /* Texture added or changed */
	      this.__ready(data)
	    }
	  },

	  /**
	   * Update or create texure.
	   * @param {Object} data - Material component data.
	   */
	  __updateTexture: function __updateTexture(data) {
	    const {src} = data
	    const {autoplay} = data

	    /* autoplay */

	    if (typeof autoplay === 'boolean') {
	      this.__autoplay = autoplay
	    } else if (typeof autoplay === 'undefined') {
	      this.__autoplay = true
	    }
	    if (this.__autoplay && this.__frames) {
	      this.play()
	    }

	    /* src */
	    if (src) {
	      this.__validateSrc(src, this.__setTexure.bind(this))
	    } else {
	      /* Texture removed */
	      this.__reset()
	    }
	  },

	  // =============================================
	  // =            varidation for texure            =
	  // =============================================

	  __validateSrc: function __validateSrc(src, cb) {
	    /* check if src is a url */
	    const url = parseUrl(src)
	    if (url) {
	      this.__getImageSrc(url, cb)
	      return
	    }

	    let message = void 0

	    /* check if src is a query selector */
	    const el = this.__validateAndGetQuerySelector(src)
	    if (!el || (typeof el === 'undefined' ? 'undefined' : _typeof(el)) !== 'object') {
	      return
	    }
	    if (el.error) {
	      message = el.error
	    } else {
	      const tagName = el.tagName.toLowerCase()
	      if (tagName === 'video') {
	        src = el.src
	        message = 'For video, please use `aframe-video-shader`'
	      } else if (tagName === 'img') {
	        this.__getImageSrc(el.src, cb)
	        return
	      } else {
	        message = `For <${tagName}> element, please use \`aframe-html-shader\``
	      }
	    }

	    /* if there is message, create error data */
	    if (message) {
	      (function () {
	        const srcData = gifData[src]
	        const errData = createError(message, src)
	        /* callbacks */
	        if (srcData && srcData.callbacks) {
	          srcData.callbacks.forEach(cb => cb(errData))
	        } else {
	          cb(errData)
	        }
	        /* overwrite */
	        gifData[src] = errData
	      }())
	    }
	  },

	  /**
	   * Validate src is a valid image url
	   * @param  {string} src - url that will be tested
	   * @param  {function} cb - callback with the test result
	   */
	  __getImageSrc: function __getImageSrc(src, cb) {
	    const _this = this

	    /* if src is same as previous, ignore this */
	    if (src === this.__textureSrc) {
	      return
	    }

	    /* check if we already get the srcData */
	    let srcData = gifData[src]
	    if (!srcData || !srcData.callbacks) {
	      /* create callback */
	      srcData = gifData[src] = {callbacks: []}
	      srcData.callbacks.push(cb)
	    } else if (srcData.src) {
	      cb(srcData)
	      return
	    } else if (srcData.callbacks) {
	      /* add callback */
	      srcData.callbacks.push(cb)
	      return
	    }
	    const tester = new Image()
	    tester.crossOrigin = 'Anonymous'
	    tester.addEventListener('load', (e) => {
	      /* check if it is gif */
	      _this.__getUnit8Array(src, (arr) => {
	        if (!arr) {
	          onError('This is not gif. Please use `shader:flat` instead')
	          return
	        }
	        /* parse data */
	        (0, _gifsparser.parseGIF)(arr, (times, cnt, frames) => {
	          /* store data */
	          const newData = {status: 'success', src, times, cnt, frames, timestamp: Date.now()}
	          /* callbacks */
	          if (srcData.callbacks) {
	            srcData.callbacks.forEach(cb => cb(newData))
	            /* overwrite */
	            gifData[src] = newData
	          }
	        }, err => onError(err))
	      })
	    })
	    tester.addEventListener('error', e => onError('Could be the following issue\n - Not Image\n - Not Found\n - Server Error\n - Cross-Origin Issue'))
	    function onError(message) {
	      /* create error data */
	      const errData = createError(message, src)
	      /* callbacks */
	      if (srcData.callbacks) {
	        srcData.callbacks.forEach(cb => cb(errData))
	        /* overwrite */
	        gifData[src] = errData
	      }
	    }
	    tester.src = src
	  },

	  /**
	   *
	   * get mine type
	   *
	   */
	  __getUnit8Array: function __getUnit8Array(src, cb) {
	    if (typeof cb !== 'function') {
	      return
	    }

	    const xhr = new XMLHttpRequest()
	    xhr.open('GET', src)
	    xhr.responseType = 'arraybuffer'
	    xhr.addEventListener('load', (e) => {
	      const uint8Array = new Uint8Array(e.target.response)
	      const arr = uint8Array.subarray(0, 4)
	      // const header = arr.map(value => value.toString(16)).join('')
	      let header = ''
	      for (let i = 0; i < arr.length; i++) {
	        header += arr[i].toString(16)
	      }
	      if (header === '47494638') {
	        cb(uint8Array)
	      } else {
	        cb()
	      }
	    })
	    xhr.addEventListener('error', (e) => {
	      log(e)
	      cb()
	    })
	    xhr.send()
	  },

	  /**
	   * Query and validate a query selector,
	   *
	   * @param  {string} selector - DOM selector.
	   * @return {object} Selected DOM element | error message object.
	   */
	  __validateAndGetQuerySelector: function __validateAndGetQuerySelector(selector) {
	    try {
	      const el = document.querySelector(selector)
	      if (!el) {
	        return {error: 'No element was found matching the selector'}
	      }
	      return el
	    } catch (e) {
	      // Capture exception if it's not a valid selector.
	      return {error: 'no valid selector'}
	    }
	  },

	  // ================================
	  // =            playback            =
	  // ================================

	  /**
	   * add public functions
	   * @private
	   */
	  __addPublicFunctions: function __addPublicFunctions() {
	    this.el.gif = {
	      play: this.play.bind(this),
	      pause: this.pause.bind(this),
	      togglePlayback: this.togglePlayback.bind(this),
	      paused: this.paused.bind(this),
	      nextFrame: this.nextFrame.bind(this),
	    }
	  },

	  /**
	   * Pause gif
	   * @public
	   */
	  pause: function pause() {
	    log('pause')
	    this.__paused = true
	  },

	  /**
	   * Play gif
	   * @public
	   */
	  play: function play() {
	    log('play')
	    this.__paused = false
	  },

	  /**
	   * Toggle playback. play if paused and pause if played.
	   * @public
	   */

	  togglePlayback: function togglePlayback() {
	    if (this.paused()) {
	      this.play()
	    } else {
	      this.pause()
	    }
	  },

	  /**
	   * Return if the playback is paused.
	   * @public
	   * @return {boolean}
	   */
	  paused: function paused() {
	    return this.__paused
	  },

	  /**
	   * Go to next frame
	   * @public
	   */
	  nextFrame: function nextFrame() {
	    this.__draw()

	    /* update next frame time */
	    while (Date.now() - this.__startTime >= this.__nextFrameTime) {
	      this.__nextFrameTime += this.__delayTimes[this.__frameIdx++]
	      if ((this.__infinity || this.__loopCnt) && this.__frameCnt <= this.__frameIdx) {
	        /* go back to the first */
	        this.__frameIdx = 0
	      }
	    }
	  },

	  // ==============================
	  // =            canvas            =
	  // ==============================

	  /**
	   * clear canvas
	   * @private
	   */
	  __clearCanvas: function __clearCanvas() {
	    this.__ctx.clearRect(0, 0, this.__width, this.__height)
	    this.__texture.needsUpdate = true
	  },

	  /**
	   * draw
	   * @private
	   */
	  __draw: function __draw() {
        if (this.__transparent) {
          this.__ctx.clearRect(0, 0, this.__width, this.__height)
        }
	    this.__ctx.drawImage(this.__frames[this.__frameIdx], 0, 0, this.__width, this.__height)
	    this.__texture.needsUpdate = true
	  },

	  // ============================
	  // =            ready            =
	  // ============================

	  /**
	   * setup gif animation and play if autoplay is true
	   * @private
	   * @property {string} src - src url
	   * @param {array} times - array of time length of each image
	   * @param {number} cnt - total counts of gif images
	   * @param {array} frames - array of each image
	   */
	  __ready: function __ready(_ref) {
	    const {src} = _ref
	    const {times} = _ref
	    const {cnt} = _ref
	    const {frames} = _ref

	    log('__ready')
	    this.__textureSrc = src
	    this.__delayTimes = times
	    cnt ? this.__loopCnt = cnt : this.__infinity = true
	    this.__frames = frames
	    this.__frameCnt = times.length
	    this.__startTime = Date.now()
	    this.__width = THREE.Math.floorPowerOfTwo(frames[0].width)
	    this.__height = THREE.Math.floorPowerOfTwo(frames[0].height)
	    this.__cnv.width = this.__width
	    this.__cnv.height = this.__height
	    this.__draw()
	    if (this.__autoplay) {
	      this.play()
	    } else {
	      this.pause()
	    }
	  },

	  // =============================
	  // =            reset            =
	  // =============================

	  /**
	   * @private
	   */

	  __reset: function __reset() {
	    this.pause()
	    this.__clearCanvas()
	    this.__startTime = 0
	    this.__nextFrameTime = 0
	    this.__frameIdx = 0
	    this.__frameCnt = 0
	    this.__delayTimes = null
	    this.__infinity = false
	    this.__loopCnt = 0
	    this.__frames = null
	    this.__textureSrc = null
	  },
    })
    /***/ },
  /* 1 */
  /***/ function (module, exports) {
    /**
	 *
	 * Gif parser by @gtk2k
	 * https://github.com/gtk2k/gtk2k.github.io/tree/master/animation_gif
	 *
	 */

    exports.parseGIF = function (gif, successCB, errorCB) {
	  let pos = 0
	  const delayTimes = []
	  let loadCnt = 0
	  let graphicControl = null
	  var imageData = null
	  const frames = []
	  let loopCnt = 0
	  if (gif[0] === 0x47 && gif[1] === 0x49 && gif[2] === 0x46 &&  // 'GIF'
	  gif[3] === 0x38 && gif[4] === 0x39 && gif[5] === 0x61) {
	    // '89a'
	    pos += 13 + +!!(gif[10] & 0x80) * Math.pow(2, (gif[10] & 0x07) + 1) * 3
	    const gifHeader = gif.subarray(0, pos)
	    while (gif[pos] && gif[pos] !== 0x3b) {
	      const offset = pos
	          const blockId = gif[pos]
	      if (blockId === 0x21) {
	        const label = gif[++pos]
	        if ([0x01, 0xfe, 0xf9, 0xff].indexOf(label) !== -1) {
	          label === 0xf9 && delayTimes.push((gif[pos + 3] + (gif[pos + 4] << 8)) * 10)
	          label === 0xff && (loopCnt = gif[pos + 15] + (gif[pos + 16] << 8))
	          while (gif[++pos]) {
	            pos += gif[pos]
	          }label === 0xf9 && (graphicControl = gif.subarray(offset, pos + 1))
	        } else {
	          errorCB && errorCB('parseGIF: unknown label'); break
	        }
	      } else if (blockId === 0x2c) {
	        pos += 9
	        pos += 1 + +!!(gif[pos] & 0x80) * (Math.pow(2, (gif[pos] & 0x07) + 1) * 3)
	        while (gif[++pos]) {
	          pos += gif[pos]
	        } var imageData = gif.subarray(offset, pos + 1)
	        frames.push(URL.createObjectURL(new Blob([gifHeader, graphicControl, imageData])))
	      } else {
	        errorCB && errorCB('parseGIF: unknown blockId'); break
	      }
	      pos++
	    }
	  } else {
	    errorCB && errorCB('parseGIF: no GIF89a')
	  }
	  if (frames.length) {
	    let cnv = document.createElement('canvas')
	    const loadImg = function loadImg() {
	      frames.forEach((src, i) => {
	        const img = new Image()
	        img.onload = function (e, i) {
	          if (i === 0) {
	            cnv.width = img.width
	            cnv.height = img.height
	          }
	          loadCnt++
	          frames[i] = this
	          if (loadCnt === frames.length) {
	            loadCnt = 0
	            imageFix(1)
	          }
	        }.bind(img, null, i)
	        img.src = src
	      })
	    }
	    var imageFix = function imageFix(i) {
	      const img = new Image()
	      img.onload = function (e, i) {
	        loadCnt++
	        frames[i] = this
	        if (loadCnt === frames.length) {
	          cnv = null
	          successCB && successCB(delayTimes, loopCnt, frames)
	        } else {
	          imageFix(++i)
	        }
	      }.bind(img)
	      img.src = cnv.toDataURL('image/gif')
	    }
	    loadImg()
	  }
    }
    /***/ },
/** *** */ ]))```

app.js

// Copyright (c) 2022 8th Wall, Inc.
//
// app.js is the main entry point for your 8th Wall app. Code here will execute after head.html
// is loaded, and before body.html is loaded.

import './aframe-gif-shader.js'

// Wait for the scene to load
AFRAME.registerComponent('link-to-site', {
  init: function () {
    // Select the entity with class 'can-tap'
    const tappableElement = document.querySelector('.can-tap');

    // Attach an event listener to handle clicks
    tappableElement.addEventListener('click', function () {
      // Redirect to a website when the PNG is tapped
      window.open('https://oldflower.co/', '_blank'); // Replace with your URL
    });
  }
});


Body.html

<a-scene
  xrextras-gesture-detector
  landing-page
  xrextras-loading
  xrextras-runtime-error
  renderer="colorManagement:true; webgl2: true;"
  xrweb="disableWorldTracking: true; allowedDevices: any">


  <a-assets>
    <img id="bee-image" src="assets/bee1.png"/>
    <img id="gif-text" src="assets/tele.gif"/>
  </a-assets>

  <a-camera
    position="0 0 0"
       raycaster="objects: .can-tap"
    cursor="fuse: false; rayOrigin: mouse;">
  </a-camera>
 
  <a-light type="directional" intensity="0.5" position="1 1 1"></a-light>

  <a-light type="ambient" intensity="0.7"></a-light>

  <xrextras-named-image-target name="qdt-flower">
     <a-entity position="0 0 0.15" 
      scale="0.8 0.8 0.8"
      geometry="primitive:plane; height: 1; width:1.4;" 
      material="shader:gif; src:#gif-text; transparent:true">
    </a-entity>

    <a-entity position="0.65 0.4 0.1" 
      scale="0.6 0.6 0.6"
      geometry="primitive:plane; height: 0.3; width: 0.3;" 
      material="src:#bee-image; transparent:true"
      class="can-tap" 
      link-to-site 
    ></a-entity>

  </xrextras-named-image-target>


</a-scene>


head.html

<!-- Copyright (c) 2022 8th Wall, Inc. -->
<!-- head.html is optional; elements will be added to your html head before app.js is loaded. -->

<!-- Use "8thwall:" meta tags to hook into 8th Wall's build process and developer tools. -->
<meta name="8thwall:renderer" content="aframe:1.2.0">
<meta name="8thwall:package" content="@8thwall.xrextras">
<meta name="8thwall:package" content="@8thwall.landing-page">

<!-- Other external scripts and meta tags can also be added. -->
<meta name="apple-mobile-web-app-capable" content="yes">```