UNPKG

photo-sphere-viewer

Version:

A JavaScript library to display Photo Sphere panoramas

491 lines (398 loc) 14.9 kB
/*! * Photo Sphere Viewer 4.8.1 * @copyright 2014-2015 Jérémy Heleine * @copyright 2015-2022 Damien "Mistic" Sorel * @licence MIT (https://opensource.org/licenses/MIT) */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('three'), require('photo-sphere-viewer')) : typeof define === 'function' && define.amd ? define(['exports', 'three', 'photo-sphere-viewer'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.PhotoSphereViewer = global.PhotoSphereViewer || {}, global.PhotoSphereViewer.CompassPlugin = {}), global.THREE, global.PhotoSphereViewer)); })(this, (function (exports, three, photoSphereViewer) { 'use strict'; function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } var compass = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 100\"><circle cx=\"50\" cy=\"50\" r=\"50\" fill=\"rgba(61, 61, 61, .5)\"/><path fill=\"rgba(255, 255, 255, .7)\" d=\"M50 97.1A47 47 0 0 1 32.5 6.5l.8 1.8a45 45 0 1 0 33.4 0l.8-1.8A47 47 0 0 1 50 97Zm0-42a5 5 0 1 1 5-5 5 5 0 0 1-5 5Zm4-41.7h-1.6a.4.4 0 0 1-.4-.2l-4.6-7.7V13a.3.3 0 0 1-.3.3h-1.6a.3.3 0 0 1-.3-.3V1.8a.3.3 0 0 1 .3-.3h1.6a.3.3 0 0 1 .4.2L52 9.4V1.8a.3.3 0 0 1 .3-.3H54c.2 0 .3 0 .3.3V13c0 .2-.1.3-.3.3Z\"/></svg>\n"; /** * @typedef {Object} PSV.plugins.CompassPlugin.Options * @property {string} [size='120px'] - size of the compass * @property {string} [position='top left'] - position of the compass * @property {string} [backgroundSvg] - SVG used as background of the compass * @property {string} [coneColor='rgba(255, 255, 255, 0.5)'] - color of the cone of the compass * @property {boolean} [navigation=true] - allows to click on the compass to rotate the viewer * @property {string} [navigationColor='rgba(255, 0, 0, 0.2)'] - color of the navigation cone * @property {PSV.plugins.CompassPlugin.Hotspot[]} [hotspots] - small dots visible on the compass (will contain every marker with the "compass" data) * @property {string} [hotspotColor='rgba(0, 0, 0, 0.5)'] - default color of hotspots */ /** * @typedef {PSV.ExtendedPosition} PSV.plugins.CompassPlugin.Hotspot * @type {string} [color] - override the global "hotspotColor" */ var HOTSPOT_SIZE_RATIO = 1 / 40; /** * @summary Adds a compass on the viewer * @extends PSV.plugins.AbstractPlugin * @memberof PSV.plugins */ var CompassPlugin = /*#__PURE__*/function (_AbstractPlugin) { _inheritsLoose(CompassPlugin, _AbstractPlugin); /** * @param {PSV.Viewer} psv * @param {PSV.plugins.CompassPlugin.Options} options */ function CompassPlugin(psv, options) { var _this; _this = _AbstractPlugin.call(this, psv) || this; /** * @member {PSV.plugins.CompassPlugin.Options} * @private */ _this.config = _extends({ size: '120px', backgroundSvg: compass, coneColor: 'rgba(255, 255, 255, 0.5)', navigation: true, navigationColor: 'rgba(255, 0, 0, 0.2)', hotspotColor: 'rgba(0, 0, 0, 0.5)' }, options, { position: photoSphereViewer.utils.cleanPosition(options.position, { allowCenter: true, cssOrder: true }) || ['top', 'left'] }); /** * @private */ _this.prop = { visible: true, mouse: null, mouseDown: false, markers: [] }; /** * @type {PSV.plugins.MarkersPlugin} * @private */ _this.markers = null; /** * @member {HTMLElement} * @readonly * @private */ _this.container = document.createElement('div'); _this.container.className = "psv-compass psv-compass--" + _this.config.position.join('-'); _this.container.innerHTML = _this.config.backgroundSvg; _this.container.style.width = _this.config.size; _this.container.style.height = _this.config.size; if (_this.config.position[0] === 'center') { _this.container.style.marginTop = "calc(-" + _this.config.size + " / 2)"; } if (_this.config.position[1] === 'center') { _this.container.style.marginLeft = "calc(-" + _this.config.size + " / 2)"; } /** * @member {HTMLCanvasElement} * @readonly * @private */ _this.canvas = document.createElement('canvas'); _this.container.appendChild(_this.canvas); if (_this.config.navigation) { _this.container.addEventListener('mouseenter', _assertThisInitialized(_this)); _this.container.addEventListener('mouseleave', _assertThisInitialized(_this)); _this.container.addEventListener('mousemove', _assertThisInitialized(_this)); _this.container.addEventListener('mousedown', _assertThisInitialized(_this)); _this.container.addEventListener('mouseup', _assertThisInitialized(_this)); _this.container.addEventListener('touchstart', _assertThisInitialized(_this)); _this.container.addEventListener('touchmove', _assertThisInitialized(_this)); _this.container.addEventListener('touchend', _assertThisInitialized(_this)); } return _this; } /** * @package */ var _proto = CompassPlugin.prototype; _proto.init = function init() { _AbstractPlugin.prototype.init.call(this); this.markers = this.psv.getPlugin('markers'); this.psv.container.appendChild(this.container); this.canvas.width = this.container.clientWidth * photoSphereViewer.SYSTEM.pixelRatio; this.canvas.height = this.container.clientWidth * photoSphereViewer.SYSTEM.pixelRatio; this.psv.on(photoSphereViewer.CONSTANTS.EVENTS.RENDER, this); if (this.markers) { this.markers.on('set-markers', this); } } /** * @package */ ; _proto.destroy = function destroy() { this.psv.off(photoSphereViewer.CONSTANTS.EVENTS.RENDER, this); if (this.markers) { this.markers.off('set-markers', this); } this.psv.container.removeChild(this.container); delete this.canvas; delete this.container; _AbstractPlugin.prototype.destroy.call(this); } /** * @private */ ; _proto.handleEvent = function handleEvent(e) { var _e$changedTouches, _e$changedTouches2; switch (e.type) { case photoSphereViewer.CONSTANTS.EVENTS.RENDER: this.__update(); break; case 'set-markers': this.prop.markers = e.args[0].filter(function (m) { var _m$data; return (_m$data = m.data) == null ? void 0 : _m$data.compass; }); this.__update(); break; case 'mouseenter': case 'mousemove': case 'touchmove': this.prop.mouse = ((_e$changedTouches = e.changedTouches) == null ? void 0 : _e$changedTouches[0]) || e; if (this.prop.mouseDown) { this.__click(); } else { this.__update(); } e.stopPropagation(); e.preventDefault(); break; case 'mousedown': case 'touchstart': this.prop.mouseDown = true; e.stopPropagation(); e.preventDefault(); break; case 'mouseup': case 'touchend': this.prop.mouse = ((_e$changedTouches2 = e.changedTouches) == null ? void 0 : _e$changedTouches2[0]) || e; this.prop.mouseDown = false; this.__click(); if (e.changedTouches) { this.prop.mouse = null; this.__update(); } e.stopPropagation(); e.preventDefault(); break; case 'mouseleave': this.prop.mouse = null; this.prop.mouseDown = false; this.__update(); break; } } /** * @summary Hides the compass */ ; _proto.hide = function hide() { this.container.style.display = 'none'; this.prop.visible = false; } /** * @summary Shows the compass */ ; _proto.show = function show() { this.container.style.display = ''; this.prop.visible = true; } /** * @summary Changes the hotspots on the compass * @param {PSV.plugins.CompassPlugin.Hotspot[]} hotspots */ ; _proto.setHotspots = function setHotspots(hotspots) { this.config.hotspots = hotspots; this.__update(); } /** * @summary Removes all hotspots */ ; _proto.clearHotspots = function clearHotspots() { this.setHotspots(null); } /** * @summary Updates the compass for current zoom and position * @private */ ; _proto.__update = function __update() { var _this2 = this, _this$config$hotspots; var context = this.canvas.getContext('2d'); context.clearRect(0, 0, this.canvas.width, this.canvas.height); var longitude = this.psv.getPosition().longitude; var fov = three.MathUtils.degToRad(this.psv.prop.hFov); this.__drawCone(context, this.config.coneColor, longitude, fov); var mouseAngle = this.__getMouseAngle(); if (mouseAngle !== null) { this.__drawCone(context, this.config.navigationColor, mouseAngle, fov); } this.prop.markers.forEach(function (marker) { _this2.__drawMarker(context, marker); }); (_this$config$hotspots = this.config.hotspots) == null ? void 0 : _this$config$hotspots.forEach(function (spot) { if ('longitude' in spot && !('latitude' in spot)) { spot.latitude = 0; } var pos = _this2.psv.dataHelper.cleanPosition(spot); _this2.__drawPoint(context, spot.color || _this2.config.hotspotColor, pos.longitude, pos.latitude); }); } /** * @summary Rotates the viewer depending on the position of the mouse on the compass * @private */ ; _proto.__click = function __click() { var mouseAngle = this.__getMouseAngle(); if (mouseAngle !== null) { this.psv.rotate({ longitude: mouseAngle, latitude: 0 }); } } /** * @summary Draw a cone * @param {CanvasRenderingContext2D} context * @param {string} color * @param {number} longitude - in viewer reference * @param {number} fov * @private */ ; _proto.__drawCone = function __drawCone(context, color, longitude, fov) { var a1 = longitude - Math.PI / 2 - fov / 2; var a2 = a1 + fov; var c = this.canvas.width / 2; context.beginPath(); context.moveTo(c, c); context.lineTo(c + Math.cos(a1) * c, c + Math.sin(a1) * c); context.arc(c, c, c, a1, a2, false); context.lineTo(c, c); context.fillStyle = color; context.fill(); } /** * @summary Draw a Marker * @param {CanvasRenderingContext2D} context * @param {PSV.plugins.MarkersPlugin.Marker} marker * @private */ ; _proto.__drawMarker = function __drawMarker(context, marker) { var _this3 = this; var color = this.config.hotspotColor; if (typeof marker.data.compass === 'string') { color = marker.data.compass; } if (marker.isPoly()) { context.beginPath(); marker.props.def.forEach(function (_ref, i) { var longitude = _ref[0], latitude = _ref[1]; var a = longitude - Math.PI / 2; var d = (latitude + Math.PI / 2) / Math.PI; var c = _this3.canvas.width / 2; context[i === 0 ? 'moveTo' : 'lineTo'](c + Math.cos(a) * c * d, c + Math.sin(a) * c * d); }); if (marker.isPolygon()) { context.fillStyle = color; context.fill(); } else { context.strokeStyle = color; context.lineWidth = Math.max(1, this.canvas.width * HOTSPOT_SIZE_RATIO / 2); context.stroke(); } } else { var pos = marker.props.position; this.__drawPoint(context, color, pos.longitude, pos.latitude); } } /** * @summary Draw a point * @param {CanvasRenderingContext2D} context * @param {string} color * @param {number} longitude - in viewer reference * @param {number} latitude - in viewer reference * @private */ ; _proto.__drawPoint = function __drawPoint(context, color, longitude, latitude) { var a = longitude - Math.PI / 2; var d = (latitude + Math.PI / 2) / Math.PI; var c = this.canvas.width / 2; var r = Math.max(2, this.canvas.width * HOTSPOT_SIZE_RATIO); context.beginPath(); context.ellipse(c + Math.cos(a) * c * d, c + Math.sin(a) * c * d, r, r, 0, 0, Math.PI * 2); context.fillStyle = color; context.fill(); } /** * @summary Gets the longitude corresponding to the mouse position on the compass * @return {number | null} * @private */ ; _proto.__getMouseAngle = function __getMouseAngle() { if (!this.prop.mouse) { return null; } var boundingRect = this.container.getBoundingClientRect(); var mouseX = this.prop.mouse.clientX - boundingRect.left - boundingRect.width / 2; var mouseY = this.prop.mouse.clientY - boundingRect.top - boundingRect.width / 2; if (Math.sqrt(mouseX * mouseX + mouseY * mouseY) > boundingRect.width / 2) { return null; } return Math.atan2(mouseY, mouseX) + Math.PI / 2; }; return CompassPlugin; }(photoSphereViewer.AbstractPlugin); CompassPlugin.id = 'compass'; exports.CompassPlugin = CompassPlugin; Object.defineProperty(exports, '__esModule', { value: true }); })); //# sourceMappingURL=compass.js.map