2017-11-15 15:13:49 +01:00
|
|
|
import * as THREE from 'three';
|
2017-12-14 11:16:27 +01:00
|
|
|
import { loadImage } from './imageUtils.js';
|
2017-11-15 15:13:49 +01:00
|
|
|
import createDebug from 'debug';
|
|
|
|
const debug = createDebug('d3d:threeUtils');
|
|
|
|
|
|
|
|
export function createTextureFromURL(url, useRGBAFormat = true) {
|
|
|
|
const texture = new THREE.Texture();
|
|
|
|
|
|
|
|
loadImage(url).then(image => {
|
|
|
|
URL.revokeObjectURL(url);
|
|
|
|
texture.format = useRGBAFormat ? THREE.RGBAFormat : THREE.RGBFormat;
|
|
|
|
texture.image = image;
|
|
|
|
texture.needsUpdate = true;
|
|
|
|
}).catch(() => {
|
|
|
|
URL.revokeObjectURL(url);
|
|
|
|
throw new Error(`Unable to load image: '${url}'`);
|
|
|
|
});
|
|
|
|
|
|
|
|
return texture;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function createTextureFromBlob(blob) {
|
|
|
|
const texture = new THREE.Texture();
|
|
|
|
|
|
|
|
const url = URL.createObjectURL(blob);
|
|
|
|
loadImage(url).then(image => {
|
|
|
|
URL.revokeObjectURL(url);
|
|
|
|
|
|
|
|
texture.format = (blob.type === 'image/jpeg' || blob.type === 'image/jpg') ?
|
|
|
|
THREE.RGBFormat :
|
|
|
|
THREE.RGBAFormat;
|
|
|
|
texture.image = image;
|
|
|
|
texture.needsUpdate = true;
|
|
|
|
}).catch(() => {
|
|
|
|
URL.revokeObjectURL(url);
|
|
|
|
|
|
|
|
throw new Error(`Unable to load image: '${url}'`);
|
|
|
|
});
|
|
|
|
|
|
|
|
return texture;
|
|
|
|
}
|
|
|
|
|
|
|
|
export class SpriteHandle extends THREE.Sprite {
|
2017-11-22 13:31:54 +01:00
|
|
|
isUIHandle = true;
|
2017-11-15 15:13:49 +01:00
|
|
|
constructor(texture, scale) {
|
|
|
|
if (!texture.image) {
|
|
|
|
debug('Error: Texture not loaded');
|
|
|
|
super();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const spriteMaterial = new THREE.SpriteMaterial({
|
|
|
|
color: 0xffffff,
|
|
|
|
fog: true,
|
|
|
|
depthTest: false,
|
|
|
|
map: texture
|
|
|
|
});
|
|
|
|
super(spriteMaterial);
|
|
|
|
const { width, height } = texture.image;
|
|
|
|
this.scale.set(width * scale, height * scale, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export class CanvasPlane extends THREE.Mesh {
|
|
|
|
constructor(width = 100, height = 100) {
|
|
|
|
const planeGeometry = new THREE.PlaneBufferGeometry(0, 0, 1, 1);
|
|
|
|
|
|
|
|
const canvas = document.createElement('canvas');
|
|
|
|
const context = canvas.getContext('2d');
|
|
|
|
const texture = new THREE.Texture(canvas);
|
|
|
|
const material = new THREE.MeshBasicMaterial({
|
|
|
|
map: texture,
|
2017-11-23 13:17:44 +01:00
|
|
|
depthTest: false,
|
2017-11-15 15:13:49 +01:00
|
|
|
side: THREE.DoubleSide
|
|
|
|
});
|
|
|
|
|
|
|
|
super(planeGeometry, material);
|
|
|
|
|
|
|
|
this._width = width;
|
|
|
|
this._height = height;
|
|
|
|
|
|
|
|
this._canvas = canvas;
|
|
|
|
this._context = context;
|
|
|
|
this._texture = texture;
|
|
|
|
|
|
|
|
this.updateSize(width, height);
|
|
|
|
}
|
|
|
|
updateSize(width, height) {
|
|
|
|
this._width = width;
|
|
|
|
this._height = height;
|
|
|
|
|
|
|
|
this._canvas.width = Math.round(width);
|
|
|
|
this._canvas.height = Math.round(height);
|
|
|
|
|
|
|
|
const positions = this.geometry.getAttribute('position');
|
|
|
|
const halfWidth = width / 2;
|
|
|
|
const halfHeight = height / 2;
|
|
|
|
positions.array[0] = -halfWidth;
|
|
|
|
positions.array[1] = halfHeight;
|
|
|
|
positions.array[3] = halfWidth;
|
|
|
|
positions.array[4] = halfHeight;
|
|
|
|
positions.array[6] = -halfWidth;
|
|
|
|
positions.array[7] = -halfHeight;
|
|
|
|
positions.array[9] = halfWidth;
|
|
|
|
positions.array[10] = -halfHeight;
|
|
|
|
positions.needsUpdate = true;
|
|
|
|
}
|
|
|
|
draw(draw) {
|
|
|
|
draw(this._context, this._width, this._height);
|
|
|
|
this._texture.needsUpdate = true;
|
|
|
|
}
|
|
|
|
}
|