three.jsを使用してcanvasでクリック処理を実装しています。
const camera_controls = new OrbitControls(camera, canvasElement)で検知しています
やりたいこと
ipone(ios)でもcanvas要素のクリックイベントを取得したいと思っています
現状
・PCではクリックイベントが発火しますが、ipone(ios14.3)になるとクリックイベントが発火しません
・iphoneでも発火させるにはnew OrbitControlsを削除すると発火することができますが、本来の挙動が出来なくなってしまいます。
仮説
new OrbitControlsが原因、引数が怪しい?
component
1<template> 2 <div class="container"> 3 <canvas id="myCanvas"></canvas> 4 </div> 5</template> 6<script lang="ts"> 7import { Component, Vue } from 'vue-property-decorator'; 8import * as THREE from 'three'; 9import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; 10import VueRouter from "vue-router"; 11Vue.use(VueRouter); 12 13@Component 14export default class EarthMap extends Vue { 15 mounted(): void { 16 this.init() 17 } 18 init(){ 19 // サイズを指定 20 const width = 960; 21 const height = 540; 22 23 // マウス座標管理用のベクトルを作成 24 const mouse = new THREE.Vector2(); 25 26 // レンダラーを作成 27 const canvasElement: HTMLCanvasElement = <HTMLCanvasElement>document.querySelector('#myCanvas') 28 29 const renderer = new THREE.WebGLRenderer({ 30 canvas: canvasElement 31 }); 32 renderer.setPixelRatio(window.devicePixelRatio); 33 renderer.setSize(width, height); 34 35 // シーンを作成 36 const scene = new THREE.Scene(); 37 38 // 背景色を追加 39 scene.background = new THREE.Color( 0xbfd1e5 ); 40 41 // カメラを作成 42 const camera = new THREE.PerspectiveCamera(45, width / height, 10, 20000); 43 camera.position.set(0, 0, +1500); 44 45 // カメラコントローラーを作成 46 const camera_controls = new OrbitControls(camera, canvasElement) 47 camera_controls.minDistance = 800; 48 camera_controls.maxDistance = 2500; 49 camera_controls.enableDamping = true; 50 camera_controls.dampingFactor = 0.2; 51 52 // 箱を作成 53 const sm_geometry = new THREE.BoxGeometry(40, 40, 40); 54 const meshList: any[] = []; 55 for (let i = 0; i < 10; i++) { 56 const material = new THREE.MeshStandardMaterial({ color: 0xffffff }); 57 const mesh = new THREE.Mesh(sm_geometry, material); 58 mesh.name = "pin-" + i 59 mesh.position.x = (Math.random() - 0.5) * 800; 60 mesh.position.y = (Math.random() - 0.5) * 800; 61 mesh.position.z = (Math.random() - 0.5) * 800; 62 mesh.rotation.x = Math.random() * 2 * Math.PI; 63 mesh.rotation.y = Math.random() * 2 * Math.PI; 64 mesh.rotation.z = Math.random() * 2 * Math.PI; 65 66 // 光を追加する 67 var directionalLight = new THREE.AmbientLight(0xffffff); 68 scene.add(mesh, directionalLight); 69 70 // 配列に保存 71 meshList.push(mesh); 72 } 73 74 75 const raycaster = new THREE.Raycaster(); 76 77 // 発火検知 78 canvasElement.addEventListener('click', handleMouseMove); 79 tick(); 80 81 function handleMouseMove(event: any) { 82 83 const element = event.currentTarget; 84 // canvas要素上のXY座標 85 const x = event.clientX - element.offsetLeft; 86 const y = event.clientY - element.offsetTop; 87 // canvas要素の幅・高さ 88 const w = element.offsetWidth; 89 const h = element.offsetHeight; 90 91 // -1〜+1の範囲で現在のマウス座標を登録する 92 mouse.x = (x / w) * 2 - 1; 93 mouse.y = -(y / h) * 2 + 1; 94 95 click_pin() 96 } 97 98 const click_pin = () => { 99 raycaster.setFromCamera(mouse, camera); 100 101 const intersects = raycaster.intersectObjects(meshList); 102 103 meshList.map((mesh) => { 104 // 交差しているオブジェクトが1つ以上存在し、 105 // 交差しているオブジェクトの1番目(最前面)のものだったら 106 if (intersects.length > 0 && mesh === intersects[0].object) { 107 console.log('要素クリック', mesh) 108 } else { 109 return false; 110 } 111 }); 112 } 113 114 // 毎フレーム時に実行されるループイベント 115 function tick(): void { 116 camera_controls.update(); 117 renderer.render(scene, camera); // レンダリング 118 requestAnimationFrame(tick) 119 } 120 } 121} 122</script>
調べたサイト
調べたサイト2
引数が怪しいと書いてありますが、コードには与えているので特に問題ないのかと。
やったこと
renderer.domElementに変更
const camera_controls = new OrbitControls(camera, renderer.domElement)
どなたか詳しい方いましたら、ご教授いただきたいです。
よろしくお願いします。
vue.js 2.6.11
ios 14.3
あなたの回答
tips
プレビュー