So I converted the custom html template into a vuejs project. I have imported all the css and js files that I want to use in the home page. CSS files load fine. For JS files, the theme comes with some custom js scripts as well as commonly used libraries such as Three.js, etc. I imported all of this below the HomeComponent in the script tag. But I got this error:
"Uncaught TypeError: Cannot read properties of null (reading 'offsetWidth') at eval (demo3.js?dad6:2:20) at ./src/assets/assets/js/demo3.js (app.js:92:1) at __webpack_require__ (app.js:1124:33) at fn (app.js:1357:21) at eval (index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/HomeComponent.vue?vue&type=script&lang=js:26:85) at ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/HomeComponent.vue?vue&type=script&lang=js (app.js:30:1) at __webpack_require__ (app.js:1124:33) at fn (app.js:1357:21) at eval (HomeComponent.vue?vue&type=script&lang=js:5:216) at ./src/components/HomeComponent.vue?vue&type=script&lang=js (app.js:296:1)"
The following is my App.vue code:
<template> <router-view /> </template> <script> export default { name: "App", components: {}, }; </script>
Below is my homecomponent.vue code (partially - some code is hidden inside the template):
<template> <header class="offcanvas-menu"> <input type="checkbox" id="toogle-menu" /> <label for="toogle-menu" class="toogle-open"><span></span></label> <nav> <div> <label for="toogle-menu" class="toogle-close"> <span></span> </label> </div> <ul> <li><a href="#section1">Section </a></li> <li><a href="#section2">Section </a></li> <li><a href="#section3">Section </a></li> <li><a href="#section4">Section </a></li> <li><a href="#section5">Section </a></li> </ul> </nav> </header> <main> <div class="content"> <canvas class="scene scene--full" id="scene"></canvas> <div class="content__inner"> <h2 class="content__title">مؤشر المعلوماتية</h2> <div class="content-button mt-2"> <button type="button" class="btn btn-relief-primary btn-large menu-trigger display-5" > <i data-feather="menu"></i> القائمة </button> </div> </div> </div> <nav class="grim"> <div class="grim__item"> <div class="grim__item-bg grim__item-bg--5"></div> </div> <div class="grim__item"> <div class="grim__item-bg grim__item-bg--5"></div> </div> <div class="grim__item"> <div class="grim__item-bg grim__item-bg--5"></div> <div class="grim__item-content"> <div class="grim__item-inner"></div> </div> </div> .. <div class="grim__item"> <div class="grim__item-bg grim__item-bg--9"></div> <div class="grim__item-img grim__item-img--4"></div> <a href="dashboard-region.html" class="grim__link grim__item-content"> <div class="grim__item-inner"> <h3 class="grim__item-title">test</h3> <span class="grim__item-desc">test</span> </div> </a> <div class="grim__item-bg grim__item-bg-cover grim__item-bg--9"></div> </div> <div class="grim__item"> <div class="grim__item-bg grim__item-bg--10"></div> <div class="grim__item-img grim__item-img--5" style=""></div> <a href="wizard.html" class="grim__link grim__item-content"> <div class="grim__item-inner"> <h3 class="grim__item-title">test</h3> <span class="grim__item-desc" >test</span > </div> </a> <div class="grim__item-bg grim__item-bg-cover grim__item-bg--10"></div> </div> </nav> </main> <!-- home --> </template> <style> @import url("https://fonts.googleapis.com/css?family=Barlow:400,500,700|Poppins:600"); @import url("https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,300;0,400;0,500;0,600;1,400;1,500;1,600"); </style> <script> //All css files import "../assets/assets/css/base.css"; import "../assets/app-assets/css-rtl/bootstrap.css"; import "../assets/app-assets/css-rtl/bootstrap-extended.css"; import "../assets/app-assets/css-rtl/colors.css"; import "../assets/app-assets/css-rtl/themes/dark-layout.css"; import "../assets/assets/css/menu.css"; import "../assets/app-assets/css-rtl/custom-rtl.css"; import "../assets/assets/css/style-rtl.css"; export default { name: "HomeComponent", }; //All JS files import "../assets/assets/js/demo.js"; import "../assets/assets/js/three.min.js"; import "../assets/assets/js/perlin.js"; import "../assets/assets/js/TweenMax.min.js"; import "../assets/assets/js/demo3.js"; import "../assets/assets/js/grid.js"; import "../assets/assets/js/imagesloaded.pkgd.min.js"; import "../assets/assets/js/anime.min.js"; import "../assets/assets/js/menu2.js"; </script>
The problem lies in the demo3.js file.
Demo3.js
var canvas = document.querySelector("#scene"); var width = canvas.offsetWidth, height = canvas.offsetHeight; var renderer = new THREE.WebGLRenderer({ canvas: canvas, antialias: true, }); renderer.setPixelRatio(window.devicePixelRatio > 1 ? 2 : 1); renderer.setSize(width, height); renderer.setClearColor(0x161d31); var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera(100, width / height, 0.1, 10000); camera.position.set(120, 0, 300); var light = new THREE.HemisphereLight(0xffffff, 0x0c056d, 0.6); scene.add(light); var light = new THREE.DirectionalLight(0x590d82, 0.5); light.position.set(100, 300, 400); scene.add(light); var light2 = light.clone(); light2.position.set(-100, 300, 400); scene.add(light2); var geometry = new THREE.IcosahedronGeometry(120, 4); for (var i = 0; i < geometry.vertices.length; i++) { var vector = geometry.vertices[i]; vector._o = vector.clone(); } var material = new THREE.MeshPhongMaterial({ emissive: 0x23f660, emissiveIntensity: 0.4, shininess: 0, }); var shape = new THREE.Mesh(geometry, material); scene.add(shape); function updateVertices(a) { for (var i = 0; i < geometry.vertices.length; i++) { var vector = geometry.vertices[i]; vector.copy(vector._o); var perlin = noise.simplex3( vector.x * 0.006 + a * 0.0002, vector.y * 0.006 + a * 0.0003, vector.z * 0.006 ); var ratio = perlin * 0.4 * (mouse.y + 0.3) + 0.9; vector.multiplyScalar(ratio); } geometry.verticesNeedUpdate = true; } function render(a) { requestAnimationFrame(render); updateVertices(a); renderer.render(scene, camera); } function onResize() { canvas.style.width = ""; canvas.style.height = ""; width = canvas.offsetWidth; height = canvas.offsetHeight; camera.aspect = width / height; camera.updateProjectionMatrix(); renderer.setSize(width, height); } var mouse = new THREE.Vector2(0.8, 0.5); function onMouseMove(e) { TweenMax.to(mouse, 0.8, { y: e.clientY / height, x: e.clientX / width, ease: Power1.easeOut, }); } requestAnimationFrame(render); window.addEventList ener("mousemove", onMouseMove); var resizeTm; window.addEventList ener("resize", function () { resizeTm = clearTimeout(resizeTm); resizeTm = setTimeout(onResize, 200); });
So, my app won't load at all. Now I don't know how to solve this problem. This is my first time converting html template to vuejs. I don't know what to expect. File structure screenshot (https://i.stack.imgur.com/dKzTb.png)
Screenshot of error details inconsole.log (https://i.stack.imgur.com/9Rzap.png)
You will import the
demo3.js
file (and execute it) before your app renders the DOM. Therefore element#scene
does not exist yet, resulting innull
.Several solutions:
demo3.js
file aftermounted
hook:demo3.js
code inside a function and export it.demo3.js
code to the vue component and use template references.