Here is the demo but it always says that I am missing the modules whereas I have all the dependancies : https://tympanus.net/codrops/2020/02/11/how-to-create-a-physics-based-3d-cloth-with-cannon-js-and-three-js/
Would anyone know how to code it on your computer from the sandbox example?
In all my js files calling 'three'; i get "Uncaught SyntaxError: Cannot use import statement outside a module".
<!DOCTYPE html> <html> <head> <title>Physics Slideshow - 03</title> <meta charset="UTF-8" /> </head> <body> <div id="app"> <section class="container"> <article class="tile"> <figure class="tile__figure"> <img src="https://images.unsplash.com/photo-1541737923-4dc81f2d1d41?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3334&q=80" class="tile__image" alt="My image" width="400" /> </figure> </article> </section> <canvas id="stage"></canvas> </div> <script src="src/index.js"></script> </body> </html> <—— figure.js——>
import * as THREE from "three"; import C from "cannon"; const size = 8; const mass = 1; export default class Figure { constructor(scene, world) { this.$image = document.querySelector(".tile__image"); this.$image.style.opacity = 0; this.scene = scene; this.world = world; this.loader = new THREE.TextureLoader(); this.image = this.loader.load(this.$image.src); this.sizes = new THREE.Vector2(0, 0); this.offset = new THREE.Vector2(0, 0); this.bufferV = new THREE.Vector3(); this.bufferV2 = new C.Vec3(); this.getSizes(); this.createMesh(); this.createStitches(); } getSizes() { const { width, height, top, left } = this.$image.getBoundingClientRect(); this.sizes.set(width, height); this.offset.set( left - window.innerWidth / 2 + width / 2, -top + window.innerHeight / 2 - height / 2 ); } createMesh() { this.geometry = new THREE.PlaneBufferGeometry(1, 1, size, size); this.material = new THREE.MeshBasicMaterial({ map: this.image }); this.mesh = new THREE.Mesh(this.geometry, this.material); this.mesh.position.set(this.offset.x, this.offset.y, 0); this.mesh.scale.set(this.sizes.x, this.sizes.y, 1); this.scene.add(this.mesh); } createStitches() { const particleShape = new C.Particle(); const { position } = this.geometry.attributes; const { x: width, y: height } = this.sizes; this.stitches = []; for (let i = 0; i < position.count; i++) { const row = Math.floor(i / (size + 1)); const pos = new C.Vec3( position.getX(i) * width, position.getY(i) * height, position.getZ(i) ); const stitch = new C.Body({ mass: row === 0 ? 0 : mass / position.count, linearDamping: 0.8, position: pos, shape: particleShape }); this.stitches.push(stitch); this.world.addBody(stitch); } for (let i = 0; i < position.count; i++) { const col = i % (size + 1); const row = Math.floor(i / (size + 1)); if (col < size) this.connect(i, i + 1); if (row < size) this.connect(i, i + size + 1); } } connect(i, j) { const c = new C.DistanceConstraint(this.stitches[i], this.stitches[j]); this.world.addConstraint(c); } applyWind(wind) { const { position } = this.geometry.attributes; for (let i = 0; i < position.count; i++) { const stitch = this.stitches[i]; const windNoise = wind.flowfield[i]; const tempPosPhysic = this.bufferV2.set( windNoise.x, windNoise.y, windNoise.z ); stitch.applyForce(tempPosPhysic, C.Vec3.ZERO); } } update() { const { position } = this.geometry.attributes; const { x: width, y: height } = this.sizes; for (let i = 0; i < position.count; i++) { const p = this.bufferV.copy(this.stitches[i].position); position.setXYZ(i, p.x / width, p.y / height, p.z); } position.needsUpdate = true; } } <—— scene.js——>
import * as THREE from "three"; import Figure from "./Figure"; import Wind from "./Wind"; import C from "cannon"; const perspective = 800; export default class Scene { constructor() { this.container = document.getElementById("stage"); this.scene = new THREE.Scene(); this.world = new C.World(); this.world.gravity.set(0, -1000, 0); this.renderer = new THREE.WebGLRenderer({ canvas: this.container, alpha: true }); this.renderer.setSize(window.innerWidth, window.innerHeight); this.renderer.setPixelRatio(window.devicePixelRatio); this.initLights(); this.initCamera(); this.figure = new Figure(this.scene, this.world); this.wind = new Wind(this.figure.mesh); this.update(); } initLights() { const ambientlight = new THREE.AmbientLight(0xffffff, 2); this.scene.add(ambientlight); } initCamera() { const fov = (180 * (2 * Math.atan(window.innerHeight / 2 / perspective))) / Math.PI; this.camera = new THREE.PerspectiveCamera( fov, window.innerWidth / window.innerHeight, 1, 5000 ); this.camera.position.set(0, 0, perspective); } update() { if ( this.renderer === undefined || this.scene === undefined || this.camera === undefined ) return; requestAnimationFrame(this.update.bind(this)); this.wind.update(); this.figure.update(); this.figure.applyWind(this.wind); this.world.step(1 / 60); this.renderer.render(this.scene, this.camera); } } <—— wind.js——>
import SimplexNoise from "simplex-noise"; import { Clock, Vector3 } from "three"; import gsap from "gsap"; const noise = new SimplexNoise(); const baseForce = 2000; const off = 0.05; export default class Wind { constructor(figure) { const { count } = figure.geometry.attributes.position; this.figure = figure; this.force = baseForce / count; this.clock = new Clock(); this.direction = new Vector3(0.5, 0, -1); this.flowfield = new Array(count); this.update(); this.bindEvents(); } bindEvents() { window.addEventListener("mousemove", this.onMouseMove.bind(this)); } onMouseMove({ clientX: x, clientY: y }) { const { innerWidth: W, innerHeight: H } = window; gsap.to(this.direction, { duration: 0.8, x: x / W - 0.5, y: -(y / H) + 0.5 }); } update() { const time = this.clock.getElapsedTime(); const { position } = this.figure.geometry.attributes; const size = this.figure.geometry.parameters.widthSegments; for (let i = 0; i < position.count; i++) { const col = i % (size + 1); const row = Math.floor(i / (size + 1)); const force = (noise.noise3D(row * off, col * off, time) * 0.5 + 0.5) * this.force; this.flowfield[i] = this.direction.clone().multiplyScalar(force); } } } <—— index.js——>
import "./styles.css"; import Scene from "./Scene"; const initApp = () => { window.scene = new Scene(); }; if ( document.readyState === "complete" || (document.readyState !== "loading" && !document.documentElement.doScroll) ) { initApp(); } else { document.addEventListener("DOMContentLoaded", initApp); } <—— styles.css ——>
body { margin: 0; background-color: #e4e0dd; } .container { display: flex; align-items: center; justify-content: center; width: 100%; height: 100vh; z-index: 10; } .tile { width: 50vmin; flex: 0 0 auto; } .tile__figure { margin: 0; padding: 0; } .tile__image { width: 100%; height: 100%; object-fit: cover; object-position: center; } canvas { position: fixed; left: 0; top: 0; width: 100%; height: 100vh; z-index: 9; }
"Uncaught SyntaxError: Cannot use import statement outside a module"Any reason you don't say that in your question?, as that's not saying there are missing modules.<script src="mystuff.js"/>you have forgot to say it's a module..<script src="mystuff.js" type="module"/>