feat: add markers (#2386)
Co-authored-by: fengshuo <fengshuo@bilibili.com>
This commit is contained in:
		| @ -65,6 +65,23 @@ import toggleClass from './toggle-class'; | ||||
|         // Prevent Vimeo blocking plyr.io demo site | ||||
|         referrerPolicy: 'no-referrer', | ||||
|       }, | ||||
|       markers: { | ||||
|         enabled: true, | ||||
|         points: [ | ||||
|           { | ||||
|             time: 10, | ||||
|             tip: 'first marker', | ||||
|           }, | ||||
|           { | ||||
|             time: 40, | ||||
|             tip: 'second marker', | ||||
|           }, | ||||
|           { | ||||
|             time: 120, | ||||
|             tipHTML: '<strong>third</strong> marker', | ||||
|           }, | ||||
|         ], | ||||
|       }, | ||||
|     }); | ||||
|  | ||||
|     // Expose for tinkering in the console | ||||
|  | ||||
| @ -391,6 +391,10 @@ const defaults = { | ||||
|       scrubbingContainer: 'plyr__preview-scrubbing', | ||||
|       scrubbingContainerShown: 'plyr__preview-scrubbing--is-shown', | ||||
|     }, | ||||
|     markers: { | ||||
|       points: 'plyr__marker__points', | ||||
|       tip: 'plyr__marker__tip', | ||||
|     }, | ||||
|   }, | ||||
|  | ||||
|   // Embed attributes | ||||
| @ -441,6 +445,12 @@ const defaults = { | ||||
|     customControls: true, | ||||
|     noCookie: false, // Whether to use an alternative version of YouTube without cookies | ||||
|   }, | ||||
|  | ||||
|   // markers | ||||
|   markers: { | ||||
|     enabled: false, | ||||
|     points: [], | ||||
|   }, | ||||
| }; | ||||
|  | ||||
| export default defaults; | ||||
|  | ||||
							
								
								
									
										64
									
								
								src/js/controls.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										64
									
								
								src/js/controls.js
									
									
									
									
										vendored
									
									
								
							| @ -796,6 +796,10 @@ const controls = { | ||||
|       controls.updateTimeDisplay.call(this, this.elements.display.duration, this.duration); | ||||
|     } | ||||
|  | ||||
|     if (this.config.markers.enabled) { | ||||
|       controls.setMarkers.call(this); | ||||
|     } | ||||
|  | ||||
|     // Update the tooltip (if visible) | ||||
|     controls.updateSeekTooltip.call(this); | ||||
|   }, | ||||
| @ -1745,6 +1749,66 @@ const controls = { | ||||
|       }); | ||||
|     } | ||||
|   }, | ||||
|   setMarkers() { | ||||
|     if (this.duration > 0 && !this.elements.markers) { | ||||
|       const { points } = this.config.markers; | ||||
|       const markersContainerFragment = document.createDocumentFragment(); | ||||
|       const markersPointsFragment = document.createDocumentFragment(); | ||||
|       const markerTipElement = createElement( | ||||
|         'span', | ||||
|         { | ||||
|           class: this.config.classNames.markers.tip, | ||||
|         }, | ||||
|         '', | ||||
|       ); | ||||
|  | ||||
|       points.forEach((point) => { | ||||
|         if (point < 0 || point > this.duration) { | ||||
|           return; | ||||
|         } | ||||
|  | ||||
|         const markerPointElement = createElement( | ||||
|           'span', | ||||
|           { | ||||
|             class: this.config.classNames.markers.points, | ||||
|           }, | ||||
|           '', | ||||
|         ); | ||||
|  | ||||
|         const left = `${(point.time / this.duration) * 100}%`; | ||||
|         const tipVisible = `${this.config.classNames.markers.tip}--visible`; | ||||
|         const toggle = (show) => toggleClass(markerTipElement, tipVisible, show); | ||||
|  | ||||
|         markerPointElement.addEventListener('mouseenter', () => { | ||||
|           markerTipElement.style.left = left; | ||||
|           if (point.tipHTML) { | ||||
|             markerTipElement.innerHTML = point.tipHTML; | ||||
|           } else { | ||||
|             markerTipElement.innerText = point.tip; | ||||
|           } | ||||
|           toggle(true); | ||||
|         }); | ||||
|         markerPointElement.addEventListener('mouseleave', () => { | ||||
|           toggle(false); | ||||
|         }); | ||||
|         markerPointElement.addEventListener('click', () => { | ||||
|           this.currentTime = point.time; | ||||
|         }); | ||||
|  | ||||
|         markerPointElement.style.left = left; | ||||
|         markersPointsFragment.appendChild(markerPointElement); | ||||
|       }); | ||||
|  | ||||
|       markersContainerFragment.appendChild(markersPointsFragment); | ||||
|       markersContainerFragment.appendChild(markerTipElement); | ||||
|  | ||||
|       this.elements.markers = { | ||||
|         points: markersPointsFragment, | ||||
|         tip: markerTipElement, | ||||
|       }; | ||||
|       this.elements.progress.appendChild(markersContainerFragment); | ||||
|     } | ||||
|   }, | ||||
| }; | ||||
|  | ||||
| export default controls; | ||||
|  | ||||
							
								
								
									
										57
									
								
								src/sass/components/markers.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/sass/components/markers.scss
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | ||||
| // -------------------------------------------------------------- | ||||
| // Markers | ||||
| // -------------------------------------------------------------- | ||||
| .plyr__marker__points { | ||||
|   width: $plyr-range-track-height; | ||||
|   height: $plyr-range-track-height; | ||||
|   border-radius: $plyr-range-track-height; | ||||
|   background-color: #fff; | ||||
|   position: absolute; | ||||
|   top: 50%; | ||||
|   margin-top: calc((#{$plyr-range-track-height} / 2) * -1); | ||||
|   margin-left: calc((#{$plyr-range-track-height} / 2) * -1); | ||||
|   z-index: 3; | ||||
| } | ||||
|  | ||||
| .plyr__marker__tip { | ||||
|   background: $plyr-markers-background; | ||||
|   border-radius: $plyr-markers-radius; | ||||
|   bottom: 100%; | ||||
|   box-shadow: $plyr-markers-shadow; | ||||
|   color: $plyr-markers-color; | ||||
|   font-size: $plyr-font-size-small; | ||||
|   font-weight: $plyr-font-weight-regular; | ||||
|   left: 50%; | ||||
|   line-height: 1.3; | ||||
|   margin-bottom: calc(#{$plyr-markers-padding} * 2); | ||||
|   opacity: 0; | ||||
|   padding: $plyr-markers-padding calc(#{$plyr-markers-padding} * 1.5); | ||||
|   pointer-events: none; | ||||
|   position: absolute; | ||||
|   transform: translate(-50%, 10px) scale(0.8); | ||||
|   transform-origin: 50% 100%; | ||||
|   transition: transform 0.2s 0.1s ease, opacity 0.2s 0.1s ease; | ||||
|   white-space: nowrap; | ||||
|   z-index: 2; | ||||
|  | ||||
|   // The background triangle | ||||
|   &::before { | ||||
|     border-left: $plyr-markers-arrow-size solid transparent; | ||||
|     border-right: $plyr-markers-arrow-size solid transparent; | ||||
|     border-top: $plyr-markers-arrow-size solid $plyr-markers-background; | ||||
|     bottom: calc(#{$plyr-markers-arrow-size} * -1); | ||||
|     content: ''; | ||||
|     height: 0; | ||||
|     left: 50%; | ||||
|     position: absolute; | ||||
|     transform: translateX(-50%); | ||||
|     width: 0; | ||||
|     z-index: 2; | ||||
|   } | ||||
| } | ||||
|  | ||||
| .plyr__marker__tip--visible { | ||||
|   opacity: 1; | ||||
|   transform: translate(-50%, 0) scale(1); | ||||
|   z-index: 3; | ||||
| } | ||||
| @ -20,6 +20,7 @@ $css-vars-use-native: true; | ||||
| @import 'settings/progress'; | ||||
| @import 'settings/sliders'; | ||||
| @import 'settings/tooltips'; | ||||
| @import 'settings/markers'; | ||||
| @import 'lib/animation'; | ||||
| @import 'lib/functions'; | ||||
| @import 'lib/mixins'; | ||||
| @ -35,6 +36,7 @@ $css-vars-use-native: true; | ||||
| @import 'components/tooltips'; | ||||
| @import 'components/progress'; | ||||
| @import 'components/volume'; | ||||
| @import 'components/markers'; | ||||
| @import 'types/audio'; | ||||
| @import 'types/video'; | ||||
| @import 'states/fullscreen'; | ||||
|  | ||||
							
								
								
									
										11
									
								
								src/sass/settings/markers.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/sass/settings/markers.scss
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| // ========================================================================== | ||||
| // Markers | ||||
| // ========================================================================== | ||||
|  | ||||
| $plyr-markers-background: var(--plyr-markers-background, rgba(#fff, 0.9)) !default; | ||||
| $plyr-markers-color: var(--plyr-markers-color, $plyr-color-gray-700) !default; | ||||
| $plyr-markers-padding: calc(#{$plyr-control-spacing} / 2); | ||||
| $plyr-markers-padding: var(--plyr-markers-padding, $plyr-markers-padding) !default; | ||||
| $plyr-markers-arrow-size: var(--plyr-markers-arrow-size, 4px) !default; | ||||
| $plyr-markers-radius: var(--plyr-markers-radius, 3px) !default; | ||||
| $plyr-markers-shadow: var(--plyr-markers-shadow, 0 1px 2px rgba(0, 0, 0, 0.15)) !default; | ||||
		Reference in New Issue
	
	Block a user