From c619257aab4a21b101a492496a4c11e99c7c69de Mon Sep 17 00:00:00 2001 From: mistic100 Date: Sun, 4 Mar 2018 12:12:38 +0100 Subject: [PATCH] Close #76 Add "scale" option to markers --- example/index.htm | 149 +++++++++++++++++++++++++----------- src/js/PSVMarker.js | 23 ++++++ src/js/components/PSVHUD.js | 22 ++++-- 3 files changed, 146 insertions(+), 48 deletions(-) diff --git a/example/index.htm b/example/index.htm index 1f9c21142..0678e0e3f 100644 --- a/example/index.htm +++ b/example/index.htm @@ -24,6 +24,16 @@ font-size: 22px; line-height: 20px; } + + .demo-label { + color: white; + font-size: 20px; + font-family: Helvetica, sans-serif; + text-align: center; + padding: 5px; + border: 1px solid white; + background: rgba(0,0,0,0.4); + } @@ -68,6 +78,8 @@

Header Level 3

  • Aliquam tincidunt mauris eu risus.
  • + +
    
     #header h1 a {
     	display: block;
    @@ -180,18 +192,6 @@ 

    Header Level 3

    } } - a.push({ - id: 'the-path', - name: 'The path', - content: '', - x: 3900, - y: 1650, - image: 'pin2.png', - width: 32, - height: 32, - anchor: 'bottom center' - }); - a.push({ id: 'lorem', tooltip: { @@ -207,29 +207,6 @@

    Header Level 3

    anchor: 'bottom center' }); - a.push({ - id: 'gif', - image: 'http://strangeplanet.fr/files/avatars/sleep-round.gif', - width: 100, - height: 100, - x: 2060, - y: 960 - }); - - a.push({ - id: 'text', - html: 'This is text ', - anchor: 'bottom right', - style: { - color: 'white', - fontSize: '20px', - fontFamily: 'Helvetica, sans-serif', - textAlign: 'center' - }, - latitude: -0.2, - longitude: 0.5 - }); - a.push({ id: 'polygon-sky', svgStyle: { @@ -274,6 +251,47 @@

    Header Level 3

    tooltip: 'This is a track' }); + a.push({ + id: 'html-img-demo', + html: 'HTML & Image', + scale: [0.5, 1.5], + className: 'demo-label', + longitude: 0.5, + latitude: -0.48 + }); + + a.push({ + id: 'gif', + image: 'http://strangeplanet.fr/files/avatars/sleep-round.gif', + width: 100, + height: 100, + longitude: 0.60, + latitude: -0.35 + }); + + a.push({ + id: 'text', + html: 'This is text ', + anchor: 'bottom right', + style: { + color: 'white', + fontSize: '20px', + fontFamily: 'Helvetica, sans-serif', + textAlign: 'center' + }, + longitude: 0.45, + latitude: -0.4 + }); + + a.push({ + id: 'svg-demo', + html: 'SVG marker demo', + scale: [0.5, 1.5], + className: 'demo-label', + longitude: -0.5, + latitude: -0.48 + }); + a.push({ id: 'circle', tooltip: 'A circle of radius 30', @@ -283,8 +301,8 @@

    Header Level 3

    stroke: 'yellow', 'stroke-width': '2px' }, - longitude: 0, - latitude: -0.1, + longitude: -0.5, + latitude: -0.28, anchor: 'center right' }); @@ -297,8 +315,8 @@

    Header Level 3

    stroke: 'yellow', 'stroke-width': '2px' }, - longitude: 0, - latitude: -0.1, + longitude: -0.5, + latitude: -0.28, anchor: 'center left' }); @@ -311,8 +329,8 @@

    Header Level 3

    stroke: 'yellow', 'stroke-width': '2px' }, - longitude: 0, - latitude: -0.2, + longitude: -0.5, + latitude: -0.38, anchor: 'center right' }); @@ -325,11 +343,56 @@

    Header Level 3

    stroke: 'yellow', 'stroke-width': '2px' }, - longitude: 0, - latitude: -0.2, + longitude: -0.5, + latitude: -0.38, anchor: 'center left' }); + a.push({ + id: 'scale-demo', + html: 'Marker scale demo', + scale: [0.5, 1.5], + className: 'demo-label', + longitude: 0, + latitude: -0.48 + }); + + a.push({ + id: 'scale-0', + tooltip: 'No scale', + scale: false, + circle: 20, + svgStyle: { + fill: 'rgba(0, 0, 0, 0.5)' + }, + longitude: -0.1, + latitude: -0.4 + }); + + a.push({ + id: 'scale-1', + tooltip: 'zoom x2', + scale: 2, + circle: 20, + svgStyle: { + fill: 'rgba(0, 0, 0, 0.5)' + }, + longitude: 0, + latitude: -0.4 + }); + + a.push({ + id: 'scale-2', + tooltip: 'zoom x0.5 ; zoom x1.5', + scale: [0.5, 1.5], + circle: 20, + svgStyle: { + fill: 'rgba(0, 0, 0, 0.5)' + }, + longitude: 0.1, + latitude: -0.4 + }); + return a; }()) }); diff --git a/src/js/PSVMarker.js b/src/js/PSVMarker.js index be557d9ba..dddfe3cfb 100644 --- a/src/js/PSVMarker.js +++ b/src/js/PSVMarker.js @@ -207,6 +207,26 @@ PSVMarker.prototype.isSvg = function() { return this.type == 'rect' || this.type == 'circle' || this.type == 'ellipse' || this.type == 'path'; }; +/** + * @summary Computes marker scale from zoom level + * @param {float} zoomLevel + * @returns {float} + */ +PSVMarker.prototype.getScale = function(zoomLevel) { + if (Array.isArray(this.scale)) { + return this.scale[0] + (this.scale[1] - this.scale[0]) * PSVUtils.animation.easings.inQuad(zoomLevel / 100); + } + else if (typeof this.scale == 'function') { + return this.scale(zoomLevel); + } + else if (typeof this.scale == 'number') { + return this.scale * PSVUtils.animation.easings.inQuad(zoomLevel / 100); + } + else { + return 1; + } +}; + /** * @summary Updates the marker with new properties * @param {object} [properties] @@ -286,6 +306,9 @@ PSVMarker.prototype._updateNormal = function() { this.$el.innerHTML = this.html; } + // set anchor + this.$el.style.transformOrigin = this.anchor.left * 100 + '% ' + this.anchor.top * 100 + '%'; + // convert texture coordinates to spherical coordinates this.psv.cleanPosition(this); diff --git a/src/js/components/PSVHUD.js b/src/js/components/PSVHUD.js index a4b0d11df..ee2ea212d 100644 --- a/src/js/components/PSVHUD.js +++ b/src/js/components/PSVHUD.js @@ -253,6 +253,7 @@ PSVHUD.prototype.clearMarkers = function(render) { * @summary Rotate the view to face the marker * @param {*} marker * @param {string|int} [duration] - rotates smoothy, see {@link PhotoSphereViewer#animate} + * @fires module:components.PSVHUD.goto-marker-done * @return {Promise} A promise that will be resolved when the animation finishes */ PSVHUD.prototype.gotoMarker = function(marker, duration) { @@ -378,14 +379,19 @@ PSVHUD.prototype.renderMarkers = function() { if (isVisible) { marker.position2D = position; - if (marker.$el instanceof SVGElement) { - marker.$el.setAttribute('transform', 'translate(' + position.x + ' ' + position.y + ')' + - (!marker.lockRotation && rotation ? ' rotate(' + rotation + ' ' + (marker.anchor.left * marker.width) + ' ' + (marker.anchor.top * marker.height) + ')' : '')); + var scale = marker.getScale(this.psv.getZoomLevel()); + + if (marker.isSvg()) { + marker.$el.setAttributeNS(null, 'transform', + 'translate(' + position.x + ', ' + position.y + ')' + + (scale !== 1 ? ' scale(' + scale + ', ' + scale + ')' : '') + + (!marker.lockRotation && rotation ? ' rotate(' + rotation + ')' : '') + ); } else { - marker.$el.style.transform = 'translate3D(' + position.x + 'px, ' + position.y + 'px, ' + '0px)' + + marker.$el.style.transform = 'translate3D(' + position.x + 'px, ' + position.y + 'px, 0px)' + + (scale !== 1 ? ' scale(' + scale + ', ' + scale + ')' : '') + (!marker.lockRotation && rotation ? ' rotateZ(' + rotation + 'deg)' : ''); - marker.$el.style.transformOrigin = marker.anchor.left * 100 + '% ' + marker.anchor.top * 100 + '%'; } } } @@ -420,7 +426,12 @@ PSVHUD.prototype._getMarkerPosition = function(marker) { if (marker._dynamicSize) { // make the marker visible to get it's size PSVUtils.toggleClass(marker.$el, 'psv-marker--transparent', true); + var transform = marker.$el.style.transform; + marker.$el.style.transform = null; + var rect = marker.$el.getBoundingClientRect(); + + marker.$el.style.transform = transform; PSVUtils.toggleClass(marker.$el, 'psv-marker--transparent', false); marker.width = rect.right - rect.left; @@ -704,6 +715,7 @@ PSVHUD.prototype._onClick = function(data, e, dblclick) { /** * @summary Clicks on an item * @param {MouseEvent} e + * @fires module:components.PSVHUD.select-marker-list * @private */ PSVHUD.prototype._onClickItem = function(e) {