묻고 답해요
167만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결몇 줄로 끝내는 인터랙티브 웹 개발 노하우 [초급편]
mousemove 시 따라 다니는 커서 이미지 wheel 할 경우
커서를 따라다니는 나비 화면에서 mousemove 이벤트에만 커서가 움직이고,마우스휠(wheel 이벤트)을 할 경우에는 나비 이미지가 움지이지 않아대략 아래와 같이 패턴으로 마우스 휠의 경우에도 움직임을 추가해 봤습니다.그런데 wheel 이벤트의 경우에는 나비가 커서 위치에 제대로 붙지 않고, 마우스를 조금이라도 움직여야 제대로 위치를 잡더라고요.마우스 휠 이벤트일 때 어떻게 보완하면 좋은지 조언 부탁드립니다. const cursor = document.querySelector('.box'); let x = 0; let y = 0; window.addEventListener('mousemove', function(e){ x = e.pageX; y = e.pageY; cursorMove(); }); window.addEventListener('wheel', function(e){ x = e.pageX; y = e.pageY; cursorMove(); }); function cursorMove() { cursor.style.transform = `translate(${x}px , ${y}px)`; }
-
미해결기초부터 배우는 Next YTMusic 클론 코딩 (with next.js 14, UI 마스터)
3.2, 3.3 화면에 아무것도 나오지 않고 있습니다!
-
미해결Three.js로 시작하는 3D 인터랙티브 웹
그림자가 다르게 표현됩니다
강의 코드를 그대로 따라하면 mesh 색이 어두운 회색으로 표현되고 그림자가 생기지 않는 문제가 있습니다. 그래서 SpotLight의 위치와 강도를 조정했더니 그림자는 나타나는데 강의영상처럼 모든 집에대한 그림자가 동일하게 나오는 것이 아니라 맨 처음 집에 대한 그림자만 선명히 나타납니다! 빛을 한방향에서만 쏘기 때문에 저 처럼 표현되는게 맞는 것 같은데, 강의영상처럼 모두 동일한 그림자를 표현하려면 어떻게 해야할까요..? import * as THREE from 'three'; import { GLTFLoader } from 'three/examples/jsm/Addons.js'; import { House } from './House'; import gsap from 'gsap'; // ----- 주제: 스크롤에 따라 움직이는 3D 페이지 // Renderer const canvas = document.querySelector('#three-canvas'); const renderer = new THREE.WebGLRenderer({ canvas, antialias: true, }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setPixelRatio(window.devicePixelRatio > 1 ? 2 : 1); renderer.shadowMap.enabled = true; // 그림자 설정, mesh도 함께 설정해야함 renderer.shadowMap.type = THREE.PCFSoftShadowMap; // 그림자 부드럽게 // Scene const scene = new THREE.Scene(); scene.background = new THREE.Color('white'); // 백그라운드 하얀색 // Camera const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); camera.position.set(-5, 2, 25); scene.add(camera); // Light const ambientLight = new THREE.AmbientLight('white', 2); scene.add(ambientLight); const spotLight = new THREE.SpotLight('white', 500); spotLight.position.set(-5, 10, 30); // 그림자 설정 spotLight.castShadow = true; spotLight.shadow.mapSize.width = 1024; // 그림자 퀄리티 조정(성능에 크게 영향을 미치지 않는 정도) spotLight.shadow.mapSize.height = 1024; // 그림자 퀄리티 조정(성능에 크게 영향을 미치지 않는 정도) spotLight.shadow.camera.near = 1; spotLight.shadow.camera.far = 1000; scene.add(spotLight); const spotLightHelper = new THREE.SpotLightHelper(spotLight, 'red'); scene.add(spotLightHelper); // --- (2) HemisphereLight 추가 --- // const hemiLight = new THREE.HemisphereLight('white', 'white', 2); // scene.add(hemiLight); const gltfLoader = new GLTFLoader(); // Mesh const floorMesh = new THREE.Mesh( new THREE.PlaneGeometry(100, 100), new THREE.MeshStandardMaterial({ color: 'white', roughness: 0.4, // 필요에 따라 조절 metalness: 0.2, // 필요에 따라 조절 toneMapped: false, }) // 강의에는 MeshStandartMaterial 사용했는데, 이거 사용시 floorMesh가 하얀색이 아닌 회색으로 보여서 변경 ); floorMesh.rotation.x = -Math.PI / 2; // 180//2 = 90도 floorMesh.receiveShadow = true; // floorMesh에 그림자가 그려지기 때문에 recieveShadow 사용 scene.add(floorMesh); // 하우스를 통해 그림자가 만들어져야 하므로 -> castShadow const houses = []; houses.push( new House({ gltfLoader, scene, modelSrc: '/models/house.glb', x: -5, z: 20, height: 2, }) ); houses.push( new House({ gltfLoader, scene, modelSrc: '/models/house.glb', x: 7, z: 10, height: 2, }) ); houses.push( new House({ gltfLoader, scene, modelSrc: '/models/house.glb', x: -10, z: 0, height: 2, }) ); houses.push( new House({ gltfLoader, scene, modelSrc: '/models/house.glb', x: 10, z: -10, height: 2, }) ); houses.push( new House({ gltfLoader, scene, modelSrc: '/models/house.glb', x: -5, z: -20, height: 2, }) ); // 그리기 const clock = new THREE.Clock(); function draw() { const delta = clock.getDelta(); renderer.render(scene, camera); renderer.setAnimationLoop(draw); spotLightHelper.update(); } let currentSection = 0; function setSection() { // console.log('setSection 실행!'); // setSection 스크롤할때마다 실행됨 const newSection = Math.round(window.scrollY / window.innerHeight); // 0,1,2,3,4 if (currentSection !== newSection) { console.log('animation!'); // section값이 바뀔때만 애니메이션이 동작하도록 gsap.to(camera.position, { duration: 1, x: houses[newSection].x, z: houses[newSection].z + 5, }); currentSection = newSection; } } function setSize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); renderer.render(scene, camera); } // 이벤트 window.addEventListener('scroll', setSection); window.addEventListener('resize', setSize); draw();
-
미해결Three.js로 시작하는 3D 인터랙티브 웹
setAnimationLoop 위치가...
현재 애니메이션 기본 수업부터 scale까지 봤는데,setAnimationLoop 가 draw 안에 등록되서 매번 반복으로 실행되는것 같은데,화면갱신에 관련된 render만 반복시키고setAnimationLoop는 바깥에서 한번만 등록하는게 옳은 방법이 아닌가 하고 의문이 드는데 어떤게 맞는건가요?동작은 둘다 똑같이 되긴 합니다. const draw = () => { /* 메쉬 애니메이션 처리 코드 들어갈 위치 ... */ renderer.render(scene, camera); } renderer.setAnimationLoop(draw);
-
미해결Three.js 3D 인터랙티브 바로 시작하기
코드에 대해 질문있습니다.
안녕하세요 Three.js 강의 열심히 듣고 있습니다. 강의를 듣다가 궁금한점이 일반적으로 Three.js 를 사용할때 z좌표의 이해강의부분에 있는 JS 코드처럼 저 코드를 전부다 해석이 가능할정도로 알아야 되는지 아니면 보통은 복붙을 하고 자주 쓰이는 부분의 코드만 만지는것인지 궁금합니다.
-
해결됨인터랙티브 웹 개발 제대로 시작하기
변수 범위 관련 질문
let currentItem; function activate(elem){ // 활성화 : 문열기 elem.classList.add('door-open'); currentItem = elem; } function inactivate(elem){ // 비활성화 : 문닫기 elem.classList.remove('door-open'); }이 부분에서요, let, const 변수는 범위가 {} 기준이라고알고있습니다.그런데, activate()에서 currentItem에 elem값을 넣어주면서 {} 범위가 끝났는데, inactivate()에서 currentItem의 값을 확인하고 실행한다는게 이해가 잘 안됩니다.
-
미해결인터랙티브 웹 개발 제대로 시작하기
perspective 문의
perspective : 800px을 .stage에 넣으면, 다르게 회전이 되어야 하는데저는 .door에 넣은 것처럼 똑같이 일정하게 회전 됩니다.이유를 모르겠어요~
-
미해결애플 웹사이트 인터랙션 클론!
선생님 캔버스 width 크기는 이미지 크기에맞게 해줘야하나요?
선생님 캔버스 width 크기는 이미지 크기에맞게 해줘야하나요?선생님은 <div class="sticky-elem sticky-elem-canvas"> <canvas id="video-canvas-0" width="1920" height="1080"></canvas> </div> 이렇게 주셨는데만약 제가 따로 실습할때의 이미지 최대크기가 1280x720 이라면캔버스 width 크기를 1280으로 해줘야하는게 맞나요? 예제 코드 그대로 쓰고 캔버스 width값 1920하니까 이미지가 왼쪽으로 좀 치우쳐져 있어서어제오늘 계속 애쓰다가 캔버스 width값을 이미지 최대크기값만큼 1280으로 주니까 해결이됬어요.. 그러면 이제 궁금한게 모바일일때 화면에 꽉 채우게하고싶은데 어떻게 줘야할지 감이안잡힙니다 ㅠ-ㅠ
-
해결됨React Three fiber(R3F)로 배우는 인터렉티브 3D 웹 개발
onClick 이벤트함수로 raycaster 방향이 자동으로 set되나요?
const shoesClick = () => { const intersects = raycaster.intersectObjects( gltf.scene.children, true ); };강의에서는 위와 같이 raycaster.intersectObject 메서드 호출시에 scene에 children을 넘겨주시는데 클릭 이벤트의 eventObject 를 넘겨주지 않았는데도 raycaster에 마우스 방향을 set 가능한가요?
-
해결됨웹 애니메이션을 위한 GSAP 가이드 Part.03
scroll Draw SVG에서 실선이 아닌 점선으로 그리고 싶어요
안녕하세요.강의를 통해 gsap을 입문한 학생입니다. 현재 강의는 스크롤 시 실선이 나타나는데점선으로 나타내고 싶습니다.현재 강의에서의 설정부분인데 pathLength = document.querySelector(element).getTotalLength(); gsap.set(element,{ strokeDasharray:pathLength, strokeDashoffset:pathLength, })strokeDasharray 설정 부분에 dashArray 간격이 16을 넣었더니 이미 실선이 그려진채로 나오더라구요.드래그하면서 실선이 그려져야하는데...실선이 아닌 점선으로도 구현할 수 있는지 궁금합니다
-
미해결실전! 웹사이트제작! Step by Step! ('크루알라모드'_반응형웹 제작)
완성헸는데 javascript부분이 안되어 메일로 코드보내드려요
완성된 부분까지 코드를 메일로 첨부하였어요.javascript부분에서 scrollPos가 동작하지 않는 거 같아요~
-
미해결3D리플릿 만들기 - 인터랙티브 웹 프로젝트
페이지 클래스리스트 제거 해줬을때
(() => { const leaflet = document.querySelector('.leaflet'); const pagesElem = document.querySelector('.page'); let pageCount = 0; function getTarget(target,className) { while (!target.classList.contains(className)) { target = target.parentNode; if (target.nodeName === 'BODY') { return; } } return target; } leaflet.addEventListener('click', (e) => { let pageElem = getTarget(e.target, 'page'); pageElem.classList.add('page-flipped'); pageCount++; if (pageCount === 2) { document.body.classList.add('leaflet-opened'); } let closeElem = getTarget(e.target, 'close-btn'); if (closeElem) { console.log(pagesElem); closeElem.classList.remove('leaflet-opened'); pageElem.classList.remove('page-flipped'); pageCount = 0; } }); })(); page 첫번째를 선택을 해줘도 close 버튼을 클릭했을때 3번째 페이지의 page-flipped가 제거 되면서 세번째 페이지가 접어 지는데 이유가 뭔가요?
-
미해결몇 줄로 끝내는 인터랙티브 웹 개발 노하우 [초급편]
부드러운 움직임 구현1 강의 부분 질문있습니다.
안녕하세요 현재 강의에서 let x = 0; let y = 0; let targetX = 0; let targetY = 0; let speed = 0.03;이 부분과x = e.pageX; y = e.pageY;이 부분 그리고targetX += (x - targetX) * speed; targetY += (y - targetY) * speed;이 부분이 왜 작성이 된 것인지 이해가 잘 되지 않습니다.
-
미해결Three.js로 시작하는 3D 인터랙티브 웹
얼굴 그릴 때 붓이 깔끔하게 칠해지지 않고 얼룩덜룩해요
-
미해결Three.js로 시작하는 3D 인터랙티브 웹
블렌더 texture paint 시 미러모드
눈을 하나씩 그리고 싶은데 그릴 때 마다 미러모드가 작동하는 것 처럼 그려져요
-
해결됨웹 애니메이션을 위한 GSAP 가이드 Part.03
파트 4 오픈 일정 문의
안녕하세요! 1~3 파트 까지 완강했고..다른 강의자보다 범쌤 강의가 저에게 너무 잘 맞아서..범쌤 다음 강의만 기다리고 있습니다 ㅠ ㅅ ㅠ 다음 강의 오픈 일정 예정이 언제쯤 일까요?! ㅠ
-
미해결인터랙티브 웹 개발 제대로 시작하기
생성자 함수를 클래스 함수로 변경 하고 this 오류 관련
init() { window.addEventListener('scroll', () => { this.scrollRunHandler(); this.scrollPosition(this.mainElem); }); } scrollRunHandler() { clearTimeout(this.scrollState); if (!this.scrollState) { this.mainElem.classList.add('running'); } this.scrollState = setTimeout(() => { this.scrollState = false; this.mainElem.classList.remove('running'); }, 500); } scrollPosition = (elem) => { if (elem.lastScrollTop > window.scrollY) { // 스크롤을 아래로 this.mainElem.dataset.direction = 'backward'; } else { // 스크롤 위로 this.mainElem.dataset.direction = 'forward'; } elem.lastScrollTop = window.scrollY; } 생성자 함수를 클래스 함수로 변경하면서 this가 character를 가리켜야 되는데 window를 가리키는 문제가 생겨서 변수를 그냥 넣어줘서 작동은 하는데 이렇게 하는게 맞는지 궁금합니다.
-
미해결Three.js로 시작하는 3D 인터랙티브 웹
DragControls의 인자값을 바꾸지 않았는데 에러가 안떠요!
DragControls 1:05초에 인자를 바꾸지 않으면 에러가 나야하는데, 저는 에러가 안뜨는데 이유가 뭘까요??서버도 껐다가 다시 켜도 동작만 안될 뿐이고, 에러는 안납니다!import * as THREE from 'three'; import { DragControls } from 'three/examples/jsm/Addons.js'; // ----- 주제: PointerLockControls 클릭 시 마우스 커서 사라지고, 마인크래프트 스타일로 변경됨 export default function example() { // Renderer const canvas = document.querySelector('#three-canvas'); const renderer = new THREE.WebGLRenderer({ canvas, antialias: true, }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setPixelRatio(window.devicePixelRatio > 1 ? 2 : 1); // Scene const scene = new THREE.Scene(); // Camera const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); camera.position.y = 1.5; camera.position.z = 4; scene.add(camera); // Light const ambientLight = new THREE.AmbientLight('white', 0.5); scene.add(ambientLight); const directionalLight = new THREE.DirectionalLight('white', 1); directionalLight.position.x = 1; directionalLight.position.z = 2; scene.add(directionalLight); // Controls const controls = new DragControls(camera, renderer.domElement); // Mesh const geometry = new THREE.BoxGeometry(1, 1, 1); let mesh; let material; for (let i = 0; i < 20; i++) { material = new THREE.MeshStandardMaterial({ // rgb (0,0,0)~(255,255,255) => (0,0,0)인 경우 검은색에 가까워지므로 최소:50 최대:250-50 color: `rgb( ${50 + Math.floor(Math.random() * 205)}, ${50 + Math.floor(Math.random() * 205)}, ${50 + Math.floor(Math.random() * 205)} )`, }); mesh = new THREE.Mesh(geometry, material); mesh.position.x = (Math.random() - 0.5) * 5; mesh.position.y = (Math.random() - 0.5) * 5; mesh.position.z = (Math.random() - 0.5) * 5; scene.add(mesh); } // 그리기 const clock = new THREE.Clock(); function draw() { const delta = clock.getDelta(); renderer.render(scene, camera); renderer.setAnimationLoop(draw); } function setSize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); renderer.render(scene, camera); } // 이벤트 window.addEventListener('resize', setSize); draw(); }
-
해결됨React Three fiber(R3F)로 배우는 인터렉티브 3D 웹 개발
화면에 렌더링은 되는데 코드에서 빨간줄이 떠요
{ "files": [], "references": [ { "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" } ], "compilerOptions": { "baseUrl": ".", "paths": { "@components/*": ["src/components/*"] } }, "types": ["node"] }import { Canvas } from "@react-three/fiber"; import { OrbitControls } from "@react-three/drei"; import ShowRoom from "@components/three/ShowRoom"; export default function Home() { return ( <> <Canvas> <axesHelper args={[5]} /> <gridHelper /> <OrbitControls /> <directionalLight position={[3, 3, 3]} /> <ShowRoom /> </Canvas> </> ); }//vite.config.ts import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; import path from "path"; // https://vite.dev/config/ export default defineConfig({ plugins: [react()], resolve: { alias: [ { find: "@src", replacement: path.resolve(__dirname, "src"), }, { find: "@components", replacement: path.resolve(__dirname, "src/components"), }, ], }, });vite config, tsconfig.json을 바꿨는데 home.tsx에서 import ShowRoom from "@components/three/ShowRoom"; 불러오는데 Cannot find module '@components/three/ShowRoom' or its corresponding type declarations.ts(2307)못찾는다는 에러가 생깁니다뭐를 잘못했는지 모르겠습니다ㅠㅠㅠ
-
미해결Three.js로 1인칭 3D 웹사이트 만들기
desk 가 밑으로 떨어졌을 때, "y 값이 문자열"에 대한 내용입니다.
우선 원인은...MeshObject 클래스 속성 중 differenceY 의 값에 OR 연산자를 사용., main.js 에서 ground 변수에 '0' 문자열 값을 할당해서 그런데요.ground 는 y 속성값을 할당하지 않았기 때문에 MeshObject 클래스에서 info.y 는 undefined 이고, this.y 는 "this.height / 2 + this.differenceY" 의 계산이 적용되서 " 0.1 / 2 + '0' " 즉, 문자열 '0.20' 이 출력됩니다.산술 연산자 '+' 가 들어가게되면, 그 계산식의 결과값은 반드시 문자열이 나옵니다.x, y, z, differenceY 는 모두 좌표와 연관된 값으로, 모두 숫자 데이터 타입을 할당받아야 하는 일관성이 필요한데 ground, floor 에서만 differenceY 가 문자열을 받아 발생한 이슈입니다.강의를 들어보던 중 강사님께서 처음에 숫자 0 을 사용하셨고, this.differenceY 속성에 값을 할당할때 OR 연산자를 쓰심으로인해 숫자 0 이 null/undefined 로 인식되는 것 때문에 문자열로 바꾸신거 같더라구요.조금 더 정확하게 하자면, OR 연산자가 아닌 ?? 연산자를 사용해 숫자 0을 값 그대로 사용할 수 있도록 바꾸고 ground 에도 문자열 '0' 이 아닌 숫자 0 을 넣어주면 될것같습니다.x, y, z 에 곱하기 1을 하는 추가코드는 필요없어집니다.