HTML test site: https://www.tutorialrepublic.com/codelab.php validator.w3.org/#validate_by_input htmledit.squarefree.com Cheatsheet: https://pbs.twimg.com/media/FDTBjF5XEAkI6ZZ?format=jpg&name=large BlueGriffon (WYSIWYG Editor that doesn't break CSS) https://www.duplichecker.com/domain-age-checker.php [0HTML examples Backup: GDRIVE:/HTML/00_HTML ] =================== https://ry3yr.github.io/OSTR/release/other/Computerstuff/Commands/CSS_Examples.txt *html-unicodecharas *brk-nz *html-knowledge *host-website *java-scriptz PMX Capable MMD Web Renderer (with stage support) -------------------------------- Download: https://ry3yr.github.io/SampleWebMMD-master.zip Src: https://github.com/Momijinn/SampleWebMMD ===/js/main.js ===== let scene, renderer, camera, mesh, helper; let ready = false; const windowWidth = window.innerWidth; const windowHeight = window.innerHeight; const clock = new THREE.Clock(); function getQueryStringValue(key) { const urlParams = new URLSearchParams(window.location.search); return urlParams.get(key);} const pmx = getQueryStringValue('pmx'); const stage = getQueryStringValue('stage'); let Pmx; let Stage; if (pmx) {Pmx = `./pmx/pronama/${pmx.trim()}`; } else {console.log("No PMX selected.");} if (stage) {Stage = `./stages${stage.trim()}`; } else { console.log("No stage selected.");} if (!Pmx) {Pmx = `./pmx/pronama/AoiZaizen/AoiZaizen.pmx`;} if (!Stage) {Stage = "./stages/sorclair/sorclair.pmx";} const MotionObjects = [ {id: "001", pose: "001", VmdClip: null, AudioClip: false }, { id: "002", pose: "002", VmdClip: null, AudioClip: false }, { id: "003", pose: "003", VmdClip: null, AudioClip: false },]; window.onload = () => { Init(); LoadModeler(); Render();}; function Init() { document.getElementById("moveLeftButton").addEventListener("click", moveCameraLeft); document.getElementById("moveRightButton").addEventListener("click", moveCameraRight); document.getElementById("moveUpButton").addEventListener("click", moveCameraUp); document.getElementById("moveDownButton").addEventListener("click", moveCameraDown); document.getElementById("rotaterightButton").addEventListener("click", rotateCameraRight); document.getElementById("rotateleftButton").addEventListener("click", rotateCameraLeft); function moveCameraLeft() {camera.position.x -= 1;} function moveCameraRight() {camera.position.x += 1;} function moveCameraUp() {camera.position.y += 1;} function moveCameraDown() {camera.position.y -= 1;} function rotateCameraRight() {mesh.rotateY(Math.PI / 4);} function rotateCameraLeft() {mesh.rotateY(-Math.PI / 4);} scene = new THREE.Scene(); const ambient = new THREE.AmbientLight(0xeeeeee); scene.add(ambient); renderer = new THREE.WebGLRenderer({ alpha: true }); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setClearColor(0xcccccc, 0); document.body.appendChild(renderer.domElement); camera = new THREE.PerspectiveCamera(100, windowWidth / windowHeight, 1, 1000); //camera.position.set(0, 19, 20); camera.position.set(0, 19, 20);} async function LoadModeler() { const loader = new THREE.MMDLoader(); function LoadPMX() { return new Promise(resolve => { loader.load(Pmx, object => { mesh = object; scene.add(mesh); resolve(true); },);});} function LoadVMD(id) { return new Promise(resolve => { const path = "./vmd/" + id + ".vmd"; const val = MotionObjects.findIndex(MotionObject => MotionObject.id == id); loader.loadAnimation(path, mesh, vmd => { vmd.name = id; MotionObjects[val].VmdClip = vmd; resolve(true); },);});} function LoadAudio(id) { return new Promise(resolve => { const path = "./audio/" + id + ".mp3"; const val = MotionObjects.findIndex(MotionObject => MotionObject.id == id); if (MotionObjects[val].AudioClip) { new THREE.AudioLoader().load(path, buffer => { const listener = new THREE.AudioListener(); const audio = new THREE.Audio(listener).setBuffer(buffer); MotionObjects[val].AudioClip = audio; resolve(true); },); } else { resolve(false);}});} const loadAdditionalPMX = () => { return new Promise(resolve => { loader.load(Stage, object => { const additionalMesh = object; scene.add(additionalMesh); resolve(true); const loadAdditionalPMX = () => { return new Promise(resolve => { loader.load(Stage, object => { const additionalMesh = object; scene.add(additionalMesh); resolve(true); }); }); }; let path; //preperations for 001.vmd and 002.vmd try {path = `./stages${stage.trim()}`;} catch (e) { path = '/default/default';} const lastIndex = path.lastIndexOf("/"); const basePath = path.substring(0, lastIndex); const vmd1 = `${basePath}/001.vmd`; const vmd2 = `${basePath}/002.vmd`; console.log(vmd1); console.log(vmd2); let mixer; //Animate //const queryString = window.location.search; //const urlParams = new URLSearchParams(queryString); //const isAnimated = urlParams.get('animated') === 'yes'; //if (isAnimated) { const url = window.location.href; const isAnimated = url.indexOf('animated') !== -1; if (isAnimated) { // Load Animation function createMixer() { mixer = new THREE.AnimationMixer(object); } function playAnimation(animationClip) { const action = mixer.clipAction(animationClip); action.play(); } loader.loadAnimation(vmd1, object, (animationClip) => { createMixer(); playAnimation(animationClip); }); loader.loadAnimation(vmd2, object, (animationClip) => { playAnimation(animationClip); }); function animate() { requestAnimationFrame(animate); const deltaTime = clock.getDelta(); if (mixer) { mixer.update(deltaTime); } renderer.render(scene, camera); } animate(); } },);});}; await Promise.all([loadAdditionalPMX()]); await LoadPMX(); await Promise.all(MotionObjects.map(async (MotionObject) => {return await LoadVMD(MotionObject.id);})); await Promise.all(MotionObjects.map(async (MotionObject) => {return await LoadAudio(MotionObject.id);})); VmdControl("loop", true);} VmdControl = (id, loop) => {const index = MotionObjects.findIndex(MotionObject => MotionObject.id == id); if (index === -1) {console.log("not Found ID");return;} ready = false; helper = new THREE.MMDAnimationHelper({ afterglow: 2.0, resetPhysicsOnLoop: true }); helper.add(mesh, { animation: MotionObjects[index].VmdClip, physics: false}); if (MotionObjects[index].AudioClip) { MotionObjects[index].AudioClip.play();} const mixer = helper.objects.get(mesh).mixer; if (!loop) { mixer.existingAction(MotionObjects[index].VmdClip).setLoop(THREE.LoopOnce);} mixer.addEventListener("loop", (event) => { console.log("loop");}); mixer.addEventListener("finished", (event) => { console.log("finished"); VmdControl("loop", true);}); ready = true;} onProgress = (xhr) => { if (xhr.lengthComputable) {const percentComplete = xhr.loaded / xhr.total * 100; console.log(Math.round(percentComplete, 2) + '% downloaded');}} onError = (xhr) => {console.log("ERROR");} Render = () => { requestAnimationFrame(Render); renderer.clear(); renderer.render(scene, camera); if (ready) {helper.update(clock.getDelta());}} //Old-hardcoded--Pose-ClickEvent //PoseClickEvent = (id) => { // switch (id) { // case "pose1": // VmdControl("001", true); // break; // case "pose2": // VmdControl("002", false); // break; // case "pose3": // VmdControl("003", false); // break; // default: // VmdControl("001", true); // break;}} //New-autogenerated--from--MotionObject-Array-Pose-ClickEvent const generatePoseClickEvent = (motionObjects) => { const functionBody = motionObjects.map(function (motion) { return "case '" + motion.pose + "':\n" + " VmdControl('" + motion.id + "', " + (motion.pose === "pose1") + ");\n" + " break;\n"; }).join(""); const poseClickEventFunction = new Function("id", "switch (id) { " + functionBody + " default: VmdControl('001', true); break; }"); return poseClickEventFunction; }; const PoseClickEvent = generatePoseClickEvent(MotionObjects); ===/index.html==