来说一个这个里面遇到的问题:
当封面加载完成的时候,本地测试是正常的,不过在测试环境就报错:
Mixed Content: The page at 'https的这是一个url地址' was loaded over HTTPS, but requested an insecure resource '这是一个http的url'. This request has been blocked; the content must be served over HTTPS.
最后的解决办法:
在index.html加一个标签就解决了
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests"/>
好了,,接下来就看代码吧!(模型转图片)
import * as THREE from 'three'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
const loader = new GLTFLoader()
const dirLight = new THREE.DirectionalLight(0xffffff, 1)
loader.load(‘模型的下载地址(我得是https地址)’, function(gltf) {
// 灯光
dirLight.color.setHSL(55, 95, 57)
// eslint-disable-next-line no-undef
dirLight.position.set(0, 1.75, 0.5)
dirLight.position.multiplyScalar(20)
gltf.scene.add(dirLight)
const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444)
hemiLight.position.set(0, 100, 0)
gltf.scene.add(hemiLight)
const mixer = new THREE.AnimationMixer(gltf.scene)
for (var i = 0; i < gltf.animations.length; i++) {
mixer.clipAction(gltf.animations[i]).play()
}
const mesh = gltf.scene.children[0]
// 创建材质对象
const material = new THREE.MeshStandardMaterial({ color: 0x7777ff })
// 将材质应用到网格对象上
mesh.material = material
// 创建渲染器
const renderer = new THREE.WebGLRenderer({
antialias: true,
preserveDrawingBuffer: true,
alpha: true
})
renderer.setSize(800, 700)
renderer.shadowMap.enabled = true
renderer.setPixelRatio(devicePixelRatio)
renderer.toneMapping = THREE.LinearToneMapping
renderer.toneMappingExposure = 0.9 // 曝光系数
// 创建相机
const camera = new THREE.PerspectiveCamera(60, 4 / 3, 0.01, 20000)
camera.position.set(10, 0, 30)
camera.lookAt(0, 0, 0)
camera.updateProjectionMatrix()
// 创建场景
const scene = new THREE.Scene()
// const loaders = new THREE.TextureLoader()
// 设置背景图--不好使
// scene.background = loaders.load('textures/bg.png')
// console.log(scene)
// // 有背景色,但是图片不可以
// scene.background = new THREE.Color(0xd3d3d3)
const group = new THREE.Group()
group.add(gltf.scene)
// 设置大模型小
const bbox = new THREE.Box3().setFromObject(group)
const mdlen = bbox.max.x - bbox.min.x // 边界的最小坐标值 边界的最大坐标值
const mdhei = bbox.max.y - bbox.min.y
const mdwid = bbox.max.z - bbox.min.z
const dist = Math.abs(
camera.position.z - group.position.z - mdwid / 2
)
const vFov = (camera.fov * Math.PI) / 180
const vheight = 2 * Math.tan(vFov * 0.5) * dist
const fraction = mdhei / vheight
const finalHeight = 1000 * fraction
const finalWidth = (finalHeight * mdhei) / mdlen // 这个地方不对
const value1 = 600 / finalWidth
const value2 = 400 / finalHeight
if (value1 >= value2) {
scene.scale.set(value2, value2, value2)
} else {
scene.scale.set(value1, value1, value1)
}
function animate() {
requestAnimationFrame(animate)
renderer.render(scene, camera)
}
animate()
scene.add(gltf.scene)
// 渲染场景
renderer.render(scene, camera)
// 将渲染结果转换成图片
const imgData = renderer.domElement.toDataURL()
// 将背景图和模型合并一张图片(直接在模型上设置背景图不生效)
var canvas = document.createElement('canvas')
canvas.width = 700
canvas.height = 700
var context = canvas.getContext('2d')
context.rect(0, 0, canvas.width, canvas.height)
context.fill()
var myImage = new Image()
myImage.src = 'textures/bg.png'// 背景图片 你自己本地的图片或者在线图片
myImage.crossOrigin = 'Anonymous'
myImage.onload = function() {
context.drawImage(myImage, 0, 0, 700, 700)
var myImage2 = new Image()
myImage2.src = imgData // 这是模型图片
myImage2.crossOrigin = 'Anonymous'
myImage2.onload = function() {
context.drawImage(myImage2, 175, 175, 400, 400)
// base64 就是最后的模型加背景图的base64图片,后续可以根据需求将其转换成https的形式
var base64 = canvas.toDataURL('image/png')
//这是我又通过上传接口将其转为https的图片
const imageData = new FormData()
imageData.append('file', blobToFile(base64ToBlob(base64), 'thumbnail.png'))
dispatch('uploadFile', {
data: imageData
}).then((uploadImageResult) => {
resource.thumbnail = uploadImageResult.file.downloadUrl
}).catch(() => {
resolve()
})
}
}
})