diff --git a/LICENSE b/LICENSE index 53272a9b3..b037264c4 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ The MIT License (MIT) Copyright (c) 2014-2015 Jérémy Heleine -Copyright (c) 2016-2022 Damien Sorel +Copyright (c) 2016-2023 Damien Sorel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/build/tsup.config.js b/build/tsup.config.js index 177b77f9c..72abb29b2 100644 --- a/build/tsup.config.js +++ b/build/tsup.config.js @@ -18,7 +18,7 @@ const externals = { '@photo-sphere-viewer/settings-plugin': 'PhotoSphereViewer.SettingsPlugin', }; -export default function createConfig(pkg, entry = 'src/index.ts') { +export default function createConfig(pkg) { const banner = `/*! * ${pkg.psv.globalName} ${pkg.version} ${ @@ -32,7 +32,7 @@ ${ const dts = !dev && options.define?.['dts'] !== 'off'; return { - entryPoints: [entry], + entryPoints: [pkg.main], outDir: 'dist', format: dev ? ['esm'] : ['iife', 'esm'], globalName: pkg.psv.globalName, diff --git a/docs/guide/adapters/equirectangular-tiles.md b/docs/guide/adapters/equirectangular-tiles.md index d1fb4a8b8..f129dc289 100644 --- a/docs/guide/adapters/equirectangular-tiles.md +++ b/docs/guide/adapters/equirectangular-tiles.md @@ -82,11 +82,9 @@ Shows a warning sign on tiles that cannot be loaded. Applies antialiasing to high resolutions tiles. -#### `canvasBackround` +#### `backgroundColor` -See the [equirectangular adapter configuration](./equirectangular.md#canvasbackround). - -_Note:_ `'auto'` is only applicable if a `baseUrl` is provided on the panorama. +See the [equirectangular adapter configuration](./equirectangular.md#backgroundcolor). #### `resolution` diff --git a/docs/guide/adapters/equirectangular.md b/docs/guide/adapters/equirectangular.md index f5c30c37d..a273845a5 100644 --- a/docs/guide/adapters/equirectangular.md +++ b/docs/guide/adapters/equirectangular.md @@ -26,12 +26,23 @@ const viewer = new PhotoSphereViewer.Viewer({ Read real image size from XMP data, must be kept `true` if the panorama has been cropped after shot. This is used for [cropped panorama](#cropped-panorama). -#### `canvasBackground` +#### `backgroundColor` -- type: `'auto' | string` +- type: `string` - default: `#000` -Background color of the canvas, which will be visible when using cropped panoramas. When set to `auto`, a blurry background will be generated from the panorama image. +Background color of the viewer, which will be visible when using cropped panoramas. + +#### `interpolateBackground` + +- type: `boolean` +- default: `false` + +Interpolate the missing parts of cropped panorama with a blur effect. + +::: warning +The interpolation is done asynchronously in a web worker, as such the panorama will be first be displayed without interpolation with only `canvasBackground` applied, then the interpolated image will be shown (takes about 1-3 seconds depending on the hardware). +::: #### `resolution` diff --git a/docs/guide/config.md b/docs/guide/config.md index e0ac2459d..3fbf938b3 100644 --- a/docs/guide/config.md +++ b/docs/guide/config.md @@ -312,7 +312,7 @@ requestHeaders: (url) => ({ #### ~~`canvasBackground`~~ -Deprecated : must be configured [on the adapter](./adapters/equirectangular.md#canvasbackround). +Deprecated : must be configured [on the adapter](./adapters/equirectangular.md#backgroundcolor). #### `moveInertia` diff --git a/examples/misc-equirectangular-cropped.html b/examples/misc-equirectangular-cropped.html index 8c825ce35..8ea4d0e02 100644 --- a/examples/misc-equirectangular-cropped.html +++ b/examples/misc-equirectangular-cropped.html @@ -31,7 +31,8 @@ caption: 'Parc national du Mercantour © Damien Sorel', loadingImg: baseUrl + 'loader.gif', adapter: [EquirectangularAdapter, { - canvasBackground: 'auto', + backgroundColor: '#77addb', + interpolateBackground: true, }], }); diff --git a/packages/core/src/adapters/EquirectangularAdapter.ts b/packages/core/src/adapters/EquirectangularAdapter.ts index f3e2acb5d..fca0df916 100644 --- a/packages/core/src/adapters/EquirectangularAdapter.ts +++ b/packages/core/src/adapters/EquirectangularAdapter.ts @@ -5,18 +5,15 @@ import { SPHERE_RADIUS } from '../data/constants'; import { SYSTEM } from '../data/system'; import { PanoData, PanoDataProvider, TextureData } from '../model'; import { - averageRgb, - createHorizontalGradient, createTexture, firstNonNull, - getAverageColor, getConfigParser, getXMPValue, isNil, - logWarn, - rgbCss, + logWarn } from '../utils'; import { AbstractAdapter } from './AbstractAdapter'; +import { interpolationWorkerSrc } from './interpolationWorker'; /** * Configuration for {@link EquirectangularAdapter} @@ -26,7 +23,11 @@ export type EquirectangularAdapterConfig = { * Background color of the canvas, which will be visible when using cropped panoramas * @default '#000' */ - canvasBackground?: 'auto' | string; + backgroundColor?: string; + /** + * Interpolate the missing parts of cropped panoramas (async) + */ + interpolateBackground?: boolean; /** * number of faces of the sphere geometry, higher values may decrease performances * @default 64 @@ -49,7 +50,8 @@ type EquirectangularTexture = TextureData; const getConfig = getConfigParser( { - canvasBackground: '#000', + backgroundColor: '#000', + interpolateBackground: false, resolution: 64, useXmpData: true, blur: false, @@ -74,6 +76,8 @@ export class EquirectangularAdapter extends AbstractAdapter { private readonly config: EquirectangularAdapterConfig; + private interpolationWorker: Worker; + private readonly SPHERE_SEGMENTS: number; private readonly SPHERE_HORIZONTAL_SEGMENTS: number; @@ -85,7 +89,11 @@ export class EquirectangularAdapter extends AbstractAdapter { this.config.useXmpData = this.viewer.config.useXmpData; } if (!isNil(this.viewer.config.canvasBackground)) { - this.config.canvasBackground = this.viewer.config.canvasBackground; + this.config.backgroundColor = this.viewer.config.canvasBackground; + } + + if (this.config.interpolateBackground) { + this.interpolationWorker = new Worker(interpolationWorkerSrc); } this.SPHERE_SEGMENTS = this.config.resolution; @@ -100,6 +108,12 @@ export class EquirectangularAdapter extends AbstractAdapter { return true; } + override destroy(): void { + this.interpolationWorker?.terminate(); + + super.destroy(); + } + async loadTexture( panorama: string, newPanoData: PanoData | PanoDataProvider, @@ -220,16 +234,15 @@ export class EquirectangularAdapter extends AbstractAdapter { const ctx = buffer.getContext('2d'); - if (this.config.canvasBackground === 'auto') { - this.__autoBackground(buffer, img, resizedPanoData); - } else { - ctx.fillStyle = this.config.canvasBackground ?? '#000'; + if (this.config.backgroundColor) { + ctx.fillStyle = this.config.backgroundColor; ctx.fillRect(0, 0, buffer.width, buffer.height); } - ctx.filter = this.config.blur ? `blur(${buffer.width / 2048}px)` : 'none'; + if (this.config.blur) { + ctx.filter = `blur(${buffer.width / 2048}px)`; + } - // final draw ctx.drawImage( img, resizedPanoData.croppedX, @@ -238,7 +251,30 @@ export class EquirectangularAdapter extends AbstractAdapter { resizedPanoData.croppedHeight ); - return createTexture(buffer); + const t = createTexture(buffer); + + if (this.config.interpolateBackground && ( + panoData.croppedWidth !== panoData.fullWidth + || panoData.croppedHeight !== panoData.fullHeight + )) { + this.interpolationWorker.postMessage({ + image: ctx.getImageData( + resizedPanoData.croppedX, + resizedPanoData.croppedY, + resizedPanoData.croppedWidth, + resizedPanoData.croppedHeight + ), + panoData: resizedPanoData, + }); + + this.interpolationWorker.onmessage = (e) => { + ctx.putImageData(e.data, 0, 0); + t.needsUpdate = true; + this.viewer.needsUpdate(); + }; + } + + return t; } return createTexture(img); @@ -304,150 +340,4 @@ export class EquirectangularAdapter extends AbstractAdapter { }; } - /** - * Many operations draw outside the canvas in order to have a correct blur filter - */ - private __autoBackground(buffer: HTMLCanvasElement, img: HTMLImageElement, panoData: PanoData) { - const croppedY2 = panoData.fullHeight - panoData.croppedHeight - panoData.croppedY; - const croppedX2 = panoData.fullWidth - panoData.croppedWidth - panoData.croppedX; - const middleY = panoData.croppedY + panoData.croppedHeight / 2; - - if (panoData.croppedX <= 0 && panoData.croppedY <= 0 && croppedX2 <= 0 && croppedY2 <= 0) { - return; - } - - const blurSize = buffer.width / 32; - const padding = blurSize; - const edge = 10; - const filter = `blur(${blurSize}px)`; - - const ctx = buffer.getContext('2d'); - - // first draw to get the colors - ctx.drawImage( - img, - panoData.croppedX, - panoData.croppedY, - panoData.croppedWidth, - panoData.croppedHeight - ); - - // top section - if (panoData.croppedY > 0) { - if (panoData.croppedX > 0 || croppedX2 > 0) { - ctx.filter = 'none'; - - const colorLeft = getAverageColor(ctx, panoData.croppedX, panoData.croppedY, edge, edge, 2); - const colorRight = getAverageColor(ctx, buffer.width - croppedX2 - 11, panoData.croppedY, edge, edge, 2); - const colorCenter = averageRgb(colorLeft, colorRight); - - // top-left corner - if (panoData.croppedX > 0) { - ctx.fillStyle = createHorizontalGradient(ctx, 0, panoData.croppedX, colorCenter, colorLeft); - ctx.fillRect(-padding, -padding, panoData.croppedX + padding * 2, middleY + padding); - } - - // top right corner - if (croppedX2 > 0) { - ctx.fillStyle = createHorizontalGradient(ctx, buffer.width - croppedX2, buffer.width, colorRight, colorCenter); - ctx.fillRect(buffer.width - croppedX2 - padding, -padding, croppedX2 + padding * 2, middleY + padding); - } - } - - ctx.filter = filter; - - // top - ctx.drawImage( - img, - 0, 0, - img.width, edge, - panoData.croppedX, -padding, - panoData.croppedWidth, panoData.croppedY + padding * 2 - ); - - // hide to top seam - ctx.fillStyle = rgbCss(getAverageColor(ctx, 0, 0, buffer.width, edge, edge)); - ctx.fillRect(-padding, -padding, buffer.width + padding * 2, padding * 2); - } - - // bottom section - if (croppedY2 > 0) { - if (panoData.croppedX > 0 || croppedX2 > 0) { - ctx.filter = 'none'; - - const colorLeft = getAverageColor(ctx, panoData.croppedX, buffer.height - croppedY2 - 1 - edge, edge, edge, 2); - const colorRight = getAverageColor(ctx, buffer.width - croppedX2 - 1 - edge, buffer.height - croppedY2 - 1 - edge, edge, edge, 2); - const colorCenter = averageRgb(colorLeft, colorRight); - - // bottom-left corner - if (panoData.croppedX > 0) { - ctx.fillStyle = createHorizontalGradient(ctx, 0, panoData.croppedX, colorCenter, colorLeft); - ctx.fillRect(-padding, middleY, panoData.croppedX + padding * 2, buffer.height - middleY + padding); - } - - // bottom-right corner - if (croppedX2 > 0) { - ctx.fillStyle = createHorizontalGradient(ctx, buffer.width - croppedX2, buffer.width, colorRight, colorCenter); - ctx.fillRect(buffer.width - croppedX2 - padding, middleY, croppedX2 + padding * 2, buffer.height - middleY + padding); - } - } - - ctx.filter = filter; - - // bottom - ctx.drawImage( - img, - 0, img.height - edge, - img.width, edge, - panoData.croppedX, buffer.height - croppedY2 - padding, - panoData.croppedWidth, croppedY2 + padding * 2 - ); - - // hide the bottom seam - ctx.fillStyle = rgbCss(getAverageColor(ctx, 0, buffer.height - 1 - edge, buffer.width, edge, edge)); - ctx.fillRect(-padding, buffer.height - padding, buffer.width + padding * 2, padding * 2); - } - - // left section - if (panoData.croppedX > 0) { - ctx.filter = filter; - - ctx.drawImage( - img, - img.width - edge, 0, - edge, img.height, - -padding, panoData.croppedY, - padding * 2, panoData.croppedHeight - ); - - ctx.drawImage( - img, - 0, 0, - edge, img.height, - 0, panoData.croppedY, - panoData.croppedX + padding, panoData.croppedHeight - ); - } - - // right section - if (croppedX2 > 0) { - ctx.filter = filter; - - ctx.drawImage( - img, - 0, 0, - edge, img.height, - buffer.width - padding, panoData.croppedY, - padding * 2, panoData.croppedHeight - ); - - ctx.drawImage( - img, - img.width - edge, 0, - edge, img.height, - buffer.width - croppedX2 - padding, panoData.croppedY, - croppedX2 + padding, panoData.croppedHeight - ); - } - } } diff --git a/packages/core/src/adapters/interpolationWorker.ts b/packages/core/src/adapters/interpolationWorker.ts new file mode 100644 index 000000000..80ca2d50b --- /dev/null +++ b/packages/core/src/adapters/interpolationWorker.ts @@ -0,0 +1,250 @@ +import type { RGB } from 'three'; +import type { PanoData } from '../model'; + +/** + * Web Worker function to interpolate missing parts of cropped panoramas + * WARNING : this function must be autonomous + */ +function interpolationWorker() { + self.onmessage = (e: MessageEvent) => { + const panoData: PanoData = e.data.panoData; + + const buffer = new OffscreenCanvas(panoData.fullWidth, panoData.fullHeight); + const ctx = buffer.getContext('2d'); + + const img = new OffscreenCanvas(panoData.croppedWidth, panoData.croppedHeight); + const ctxImg = img.getContext('2d'); + ctxImg.putImageData(e.data.image, 0, 0); + + autoBackground(buffer, img, panoData); + + postMessage(ctx.getImageData(0, 0, buffer.width, buffer.height)); + }; + + function autoBackground(buffer: OffscreenCanvas, img: OffscreenCanvas, panoData: PanoData) { + const croppedY2 = panoData.fullHeight - panoData.croppedHeight - panoData.croppedY; + const croppedX2 = panoData.fullWidth - panoData.croppedWidth - panoData.croppedX; + const middleY = panoData.croppedY + panoData.croppedHeight / 2; + + const blurSize = buffer.width / 32; + const padding = blurSize; + const edge = 10; + const filter = `blur(${blurSize}px)`; + + const ctx = buffer.getContext('2d'); + + // first draw to get the colors + ctx.drawImage( + img, + panoData.croppedX, + panoData.croppedY, + panoData.croppedWidth, + panoData.croppedHeight + ); + + // top section + if (panoData.croppedY > 0) { + if (panoData.croppedX > 0 || croppedX2 > 0) { + ctx.filter = 'none'; + + const colorLeft = getAverageColor(ctx, panoData.croppedX, panoData.croppedY, edge, edge, 2); + const colorRight = getAverageColor(ctx, buffer.width - croppedX2 - 11, panoData.croppedY, edge, edge, 2); + const colorCenter = averageRgb(colorLeft, colorRight); + + // top-left corner + if (panoData.croppedX > 0) { + ctx.fillStyle = createHorizontalGradient(ctx, 0, panoData.croppedX, colorCenter, colorLeft); + ctx.fillRect(-padding, -padding, panoData.croppedX + padding * 2, middleY + padding); + } + + // top right corner + if (croppedX2 > 0) { + ctx.fillStyle = createHorizontalGradient(ctx, buffer.width - croppedX2, buffer.width, colorRight, colorCenter); + ctx.fillRect(buffer.width - croppedX2 - padding, -padding, croppedX2 + padding * 2, middleY + padding); + } + } + + ctx.filter = filter; + + // top + ctx.drawImage( + img, + 0, 0, + img.width, edge, + panoData.croppedX, -padding, + panoData.croppedWidth, panoData.croppedY + padding * 2 + ); + + // hide to top seam + ctx.fillStyle = rgbCss(getAverageColor(ctx, 0, 0, buffer.width, edge, edge)); + ctx.fillRect(-padding, -padding, buffer.width + padding * 2, padding * 2); + } + + // bottom section + if (croppedY2 > 0) { + if (panoData.croppedX > 0 || croppedX2 > 0) { + ctx.filter = 'none'; + + const colorLeft = getAverageColor(ctx, panoData.croppedX, buffer.height - croppedY2 - 1 - edge, edge, edge, 2); + const colorRight = getAverageColor(ctx, buffer.width - croppedX2 - 1 - edge, buffer.height - croppedY2 - 1 - edge, edge, edge, 2); + const colorCenter = averageRgb(colorLeft, colorRight); + + // bottom-left corner + if (panoData.croppedX > 0) { + ctx.fillStyle = createHorizontalGradient(ctx, 0, panoData.croppedX, colorCenter, colorLeft); + ctx.fillRect(-padding, middleY, panoData.croppedX + padding * 2, buffer.height - middleY + padding); + } + + // bottom-right corner + if (croppedX2 > 0) { + ctx.fillStyle = createHorizontalGradient(ctx, buffer.width - croppedX2, buffer.width, colorRight, colorCenter); + ctx.fillRect(buffer.width - croppedX2 - padding, middleY, croppedX2 + padding * 2, buffer.height - middleY + padding); + } + } + + ctx.filter = filter; + + // bottom + ctx.drawImage( + img, + 0, img.height - edge, + img.width, edge, + panoData.croppedX, buffer.height - croppedY2 - padding, + panoData.croppedWidth, croppedY2 + padding * 2 + ); + + // hide the bottom seam + ctx.fillStyle = rgbCss(getAverageColor(ctx, 0, buffer.height - 1 - edge, buffer.width, edge, edge)); + ctx.fillRect(-padding, buffer.height - padding, buffer.width + padding * 2, padding * 2); + } + + // left section + if (panoData.croppedX > 0) { + ctx.filter = filter; + + ctx.drawImage( + img, + img.width - edge, 0, + edge, img.height, + -padding, panoData.croppedY, + padding * 2, panoData.croppedHeight + ); + + ctx.drawImage( + img, + 0, 0, + edge, img.height, + 0, panoData.croppedY, + panoData.croppedX + padding, panoData.croppedHeight + ); + } + + // right section + if (croppedX2 > 0) { + ctx.filter = filter; + + ctx.drawImage( + img, + 0, 0, + edge, img.height, + buffer.width - padding, panoData.croppedY, + padding * 2, panoData.croppedHeight + ); + + ctx.drawImage( + img, + img.width - edge, 0, + edge, img.height, + buffer.width - croppedX2 - padding, panoData.croppedY, + croppedX2 + padding, panoData.croppedHeight + ); + } + + ctx.filter = 'none'; + + // final draw + ctx.drawImage( + img, + panoData.croppedX, + panoData.croppedY, + panoData.croppedWidth, + panoData.croppedHeight + ); + } + + /** + * Returns the CSS string for RGB color + */ + function rgbCss(color: RGB): string { + return `rgb(${color.r}, ${color.g}, ${color.b})`; + } + + /** + * Returns the average of two RGB colors + */ + function averageRgb(c1: RGB, c2: RGB): RGB { + return { + r: Math.round(c1.r / 2 + c2.r / 2), + g: Math.round(c1.g / 2 + c2.g / 2), + b: Math.round(c1.b / 2 + c2.b / 2), + }; + } + + /** + * Creates a simple horizontal gradient + */ + function createHorizontalGradient( + ctx: OffscreenCanvasRenderingContext2D, + x1: number, + x2: number, + c1: RGB, + c2: RGB + ) { + const grad = ctx.createLinearGradient(x1, 0, x2, 0); + grad.addColorStop(0, rgbCss(c1)); + grad.addColorStop(1, rgbCss(c2)); + return grad; + } + + /** + * Gets the average RGB color of a portion from a canvas element + */ + function getAverageColor( + ctx: OffscreenCanvasRenderingContext2D, + x: number, + y: number, + w: number, + h: number, + every: number + ): RGB { + every = Math.round(every); + + let r = 0; + let g = 0; + let b = 0; + let count = 0; + + const data = ctx.getImageData(x, y, w, h); + + for (let row = 0; row < h; row += every) { + for (let col = 0; col < w; col += every) { + const i = 4 * (row * w + col); + r += data.data[i]; + g += data.data[i + 1]; + b += data.data[i + 2]; + count++; + } + } + + r = Math.round(r / count); + g = Math.round(g / count); + b = Math.round(b / count); + + return { r, g, b }; + } +} + +export const interpolationWorkerSrc = URL.createObjectURL( + new Blob(['(', interpolationWorker.toString(), ')()'], + { type: 'application/javascript' }) +); diff --git a/packages/core/src/model.ts b/packages/core/src/model.ts index 18c765654..f23e412a5 100644 --- a/packages/core/src/model.ts +++ b/packages/core/src/model.ts @@ -313,12 +313,12 @@ export type ViewerConfig = { mousewheelCtrlKey?: boolean; /** @default false */ touchmoveTwoFingers?: boolean; - /** @deprecated configure on EquirectangularAdapter */ + /** @deprecated configure `useXmpData` on EquirectangularAdapter */ useXmpData?: boolean; panoData?: PanoData | PanoDataProvider; requestHeaders?: Record | ((url: string) => Record); - /** @deprecated configure on EquirectangularAdapter */ - canvasBackground?: 'auto' | string; + /** @deprecated configure `backgroundColor` on EquirectangularAdapter */ + canvasBackground?: string; /** @default '{ alpha: true, antialias: true }' */ rendererParameters?: WebGLRendererParameters; /** @default false */ diff --git a/packages/core/src/utils/canvas.ts b/packages/core/src/utils/canvas.ts deleted file mode 100644 index 823a8cdd1..000000000 --- a/packages/core/src/utils/canvas.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { RGB } from 'three'; -import { rgbCss } from './misc'; - -/** - * Creates a simple horizontal gradient - */ -export function createHorizontalGradient(ctx: CanvasRenderingContext2D, x1: number, x2: number, c1: RGB, c2: RGB) { - const grad = ctx.createLinearGradient(x1, 0, x2, 0); - grad.addColorStop(0, rgbCss(c1)); - grad.addColorStop(1, rgbCss(c2)); - return grad; -} - -/** - * Gets the average RGB color of a portion from a canvas element - */ -export function getAverageColor( - ctx: CanvasRenderingContext2D, - x: number, - y: number, - w: number, - h: number, - every: number -): RGB { - every = Math.round(every); - - let r = 0; - let g = 0; - let b = 0; - let count = 0; - - const data = ctx.getImageData(x, y, w, h); - - for (let row = 0; row < h; row += every) { - for (let col = 0; col < w; col += every) { - const i = 4 * (row * w + col); - r += data.data[i]; - g += data.data[i + 1]; - b += data.data[i + 2]; - count++; - } - } - - r = Math.round(r / count); - g = Math.round(g / count); - b = Math.round(b / count); - - return { r, g, b }; -} diff --git a/packages/core/src/utils/index.ts b/packages/core/src/utils/index.ts index 7d46269fc..9fa960c0a 100644 --- a/packages/core/src/utils/index.ts +++ b/packages/core/src/utils/index.ts @@ -1,5 +1,4 @@ export * from './browser'; -export * from './canvas'; export * from './math'; export * from './misc'; export * from './psv'; diff --git a/packages/core/src/utils/misc.ts b/packages/core/src/utils/misc.ts index 6f21da348..e5680c5f7 100644 --- a/packages/core/src/utils/misc.ts +++ b/packages/core/src/utils/misc.ts @@ -1,5 +1,3 @@ -import { RGB } from 'three'; - /** * Transforms a string to dash-case * @link https://github.com/shahata/dasherize @@ -148,21 +146,3 @@ export function deepEqual(obj1: any, obj2: any): boolean { function isObject(obj: any): boolean { return typeof obj === 'object' && obj !== null; } - -/** - * Returns the CSS string for RGB color - */ -export function rgbCss(color: RGB): string { - return `rgb(${color.r}, ${color.g}, ${color.b})`; -} - -/** - * Returns the average of two RGB colors - */ -export function averageRgb(c1: RGB, c2: RGB): RGB { - return { - r: Math.round(c1.r / 2 + c2.r / 2), - g: Math.round(c1.g / 2 + c2.g / 2), - b: Math.round(c1.b / 2 + c2.b / 2), - }; -} diff --git a/packages/equirectangular-tiles-adapter/src/EquirectangularTilesAdapter.ts b/packages/equirectangular-tiles-adapter/src/EquirectangularTilesAdapter.ts index e0bca04d6..3239fd208 100644 --- a/packages/equirectangular-tiles-adapter/src/EquirectangularTilesAdapter.ts +++ b/packages/equirectangular-tiles-adapter/src/EquirectangularTilesAdapter.ts @@ -78,13 +78,12 @@ function tileId(tile: EquirectangularTile): string { const getConfig = utils.getConfigParser( { - canvasBackground: '#000', + backgroundColor: '#000', resolution: 64, showErrorTile: true, baseBlur: true, antialias: true, debug: false, - blur: false, useXmpData: false, }, { @@ -220,7 +219,8 @@ export class EquirectangularTilesAdapter extends AbstractAdapter< if (panorama.baseUrl) { if (!this.adapter) { this.adapter = new EquirectangularAdapter(this.viewer, { - canvasBackground: this.config.canvasBackground, + backgroundColor: this.config.backgroundColor, + interpolateBackground: false, blur: this.config.baseBlur, useXmpData: false, }); @@ -300,9 +300,7 @@ export class EquirectangularTilesAdapter extends AbstractAdapter< if (texture) { material = new MeshBasicMaterial({ map: texture }); } else { - material = new MeshBasicMaterial({ - color: this.config.canvasBackground === 'auto' ? '#000' : this.config.canvasBackground, - }); + material = new MeshBasicMaterial({ color: this.config.backgroundColor }); } for (let i = 0; i < this.NB_GROUPS; i++) { diff --git a/packages/equirectangular-tiles-adapter/src/model.ts b/packages/equirectangular-tiles-adapter/src/model.ts index a986e1786..4d9861bc3 100644 --- a/packages/equirectangular-tiles-adapter/src/model.ts +++ b/packages/equirectangular-tiles-adapter/src/model.ts @@ -71,7 +71,7 @@ export type EquirectangularMultiTilesPanorama = { tileUrl: (col: number, row: number, level: number) => string | null; }; -export type EquirectangularTilesAdapterConfig = EquirectangularAdapterConfig & { +export type EquirectangularTilesAdapterConfig = Omit & { /** * shows a warning sign on tiles that cannot be loaded * @default true diff --git a/packages/equirectangular-video-adapter/src/EquirectangularVideoAdapter.ts b/packages/equirectangular-video-adapter/src/EquirectangularVideoAdapter.ts index 1f52bfe3e..d6e02beb2 100644 --- a/packages/equirectangular-video-adapter/src/EquirectangularVideoAdapter.ts +++ b/packages/equirectangular-video-adapter/src/EquirectangularVideoAdapter.ts @@ -12,7 +12,6 @@ const getConfig = utils.getConfigParser( resolution: 64, autoplay: false, muted: false, - blur: false, }, { resolution: (resolution) => { diff --git a/packages/equirectangular-video-adapter/src/model.ts b/packages/equirectangular-video-adapter/src/model.ts index a0cdb8bf6..24a24be70 100644 --- a/packages/equirectangular-video-adapter/src/model.ts +++ b/packages/equirectangular-video-adapter/src/model.ts @@ -6,4 +6,4 @@ import type { AbstractVideoAdapterConfig, AbstractVideoPanorama } from '../../sh */ export type EquirectangularVideoPanorama = AbstractVideoPanorama; -export type EquirectangularVideoAdapterConfig = Omit & AbstractVideoAdapterConfig; +export type EquirectangularVideoAdapterConfig = Omit & AbstractVideoAdapterConfig; diff --git a/packages/shared/package.json b/packages/shared/package.json index e3820ce60..e200315e4 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -2,8 +2,8 @@ "name": "@photo-sphere-viewer/shared", "version": "0.0.0", "private": true, - "main": "./src/index.ts", - "types": "./src/index.ts", + "main": "./index.ts", + "types": "./index.ts", "dependencies": { "@photo-sphere-viewer/core": "0.0.0" }, diff --git a/packages/shared/tsup.config.js b/packages/shared/tsup.config.js index 0af0c0f6c..a1aaf53f1 100644 --- a/packages/shared/tsup.config.js +++ b/packages/shared/tsup.config.js @@ -1,4 +1,4 @@ import createConfig from '../../build/tsup.config'; import pkg from './package.json' assert { type: 'json' }; -export default createConfig(pkg, 'index.ts'); +export default createConfig(pkg);