Components
48
Background Gradients Breadcrumb Content Card Carousel Content Card Grid Content Cards Two Column Content Contact Form Content Contact Form Reveal Content Courses Map Content Courses Search Content Event Details Content Events Carousel Content Faqs Content Featured Cards Content Featured Products Content Featured Products Carousel Content Form Over Image Content Game Elements Content Hall Of Fame Carousel Content Horizontal Accordion Content Horizontal Scrolling Content How To Find Us Content Job Roles Grid Content Map Embed Content Marquee Text Content Media Carousel Content Players Content Quick Links Content Quote Over Image Content Simple Text And Image Variations Content Specification Content Stat Row Content Stat With Images And Content Content Text And Cards Grid Content Text And Image Variations Content Text Columns Content Text Image Carousel Content Text Over Image Content Title Content Useful Links Content Vacancies Grid Cookie Table Example Hero Basic Hero Featured Card Hero Game Hero Video And Carousel Hero Video Cards Playlist Hero Video Player

Content Courses Map

WHERE TO STUDY

Further education institutions throughout the UK offer our Esports BTEC. Explore those closest to you.

There are no ACF fields assigned to this component.

					

count === 0 ) : continue; endif; $marker_colour = get_field( 'map_marker_colour', 'approved_' . $filter ); if ( $marker_colour === null ) : $marker_colour = $default_marker_colour; endif; ?>
debug_fields(); ?>
@import "../../resources/scss/util/variables";
@import "../../resources/scss/util/mixins";
@import "../../resources/scss/vendor/bootstrap/vendor/rfs";

.block-courses-map {
	overflow: hidden;

	&__meta {
		display: flex;
		flex-direction: row;
		gap: rem-calc(16);
		flex-wrap: wrap;
		align-items: center;
		justify-content: space-between;
		@include margin-bottom( rem-calc(60) );

		.heading {
			margin-bottom: 0;
		}

		.btn {
			margin-right: 0;
		}

		.heading,
		.btn {
			color: var( --text-color );
		}
	}

	.map {
		width: 100%;
		max-height: 60vh;
		aspect-ratio: 4/3;

		@include bp($md) {
			aspect-ratio: 1720/662;
		}

		.marker {
			width: rem-calc(26);
			height: rem-calc(35);
			cursor: pointer;
			transition: 0.3s var( --ease );
			transition-property: opacity;

			&.hide {
				opacity: 0.25;
			}
		}

		.mapboxgl-popup-content {
			p {
				&:last-of-type {
					margin-bottom: 0;
				}
			}
		}

		.popup-terms {
			@include list-unstyled;
			@include fluid-type(12, 14);
			display: flex;
			flex-direction: row;
			flex-wrap: wrap;
			gap: 0.5rem;

			li {
				&:after {
					content: ", ";
				}

				&:last-child {
					&:after {
						content: none;
					}
				}
			}
		}

		.popup-title {
			@include fluid-type(12, 14);
		}

		.popup-address {
			@include fluid-type(12, 14);
		}

		.popup-url {
			a {
				@include fluid-type(12, 14);
			}
		}

		.mapboxgl-popup-close-button {
			&:hover {
				background-color: rgba($primary, 0.5);
				color: $white;
			}
		}
	}

	&__bottom-row {
		position: relative;
		@include padding( rem-calc(32) );
		background-color: #F4F4F4;

		&:before,
		&:after {
			width: 50%;
			height: 100%;
			content: '';
			background-color: $white;
			position: absolute;
			top: 0;
			pointer-events: none;
			z-index: -1;
		}

		&:before {
			left: -50%;
		}
		&:after {
			right: -50%;
		}

		p {
			margin-bottom: 0;
		}
	}

	&__text-row {
		display: flex;
		flex-direction: column;
		align-items: flex-start;
		justify-content: center;
	}

	&__filters-row {
		display: flex;
		flex-direction: row;
		flex-wrap: wrap;
		align-items: center;
		gap: rem-calc(16 20);
		margin-top: rem-calc(32);

		@include bp($md) {
			margin-top: 0;
		}

		@include bp($lg) {
			justify-content: flex-end;
		}

		p {
			text-transform: uppercase;
			@include fluid-type(14, 18);
		}

		.filters {
			display: flex;
			flex-direction: row;
			align-items: center;
			flex-wrap: wrap;
			gap: rfs-fluid-value( rem-calc(20) );

			button {
				@include fluid-type(14, 18);
				@include padding( rem-calc(8 10) );
				background-color: transparent;
				border: 1px solid rgba($black, 0.2);
				transition: 0.3s var( --ease );
				transition-property: background-color, border-color;
				text-align: left;
				display: flex;
				flex-direction: row;
				align-items: center;
				gap: rem-calc(8);

				@include bp($md) {
					@include padding( rem-calc(16 20) );
				}

				svg {
					width: rem-calc(18);
					height: rem-calc(27);

					@include bp($md) {
						width: rem-calc(26);
						height: rem-calc(35);
					}
				}

				&:hover,
				&.active {
					border-color: transparent;
					background-color: $white;
				}
			}
		}
	}
}
class CoursesMap {

	constructor( block ) {
		this.block = block;
		this.mapContainer = block.querySelector( '.map' );
		if ( this.mapContainer ) {
			this.initMap();
		}
	}

	initMap() {
        if ( ! mapboxgl ) {
            console.error( mapboxgl );
            return;
        }

        // Create a new token - https://account.mapbox.com/
        mapboxgl.accessToken = 'pk.eyJ1Ijoic3RyYXRlZ2lxIiwiYSI6ImNsZGRiZ2Q5azAyMGQzcHFvbXBuMXQ1bXkifQ.btRsN7ao0mRYoepAGqLxCw';

        let lng  = parseFloat( this.mapContainer.getAttribute('data-lng') );
		let lat  = parseFloat( this.mapContainer.getAttribute('data-lat') );
		let zoom = parseFloat( this.mapContainer.getAttribute('data-zoom') );

		this.map = new mapboxgl.Map({
			container: this.mapContainer,
			style: 'mapbox://styles/mapbox/streets-v11',
			center: [(lng), (lat)],
			zoom: zoom,
			cooperativeGestures: true,
		});

		// Add zoom and rotation controls to the map.
		this.map.addControl( new mapboxgl.NavigationControl() );

		if ( geojson ) {
			this.markersLookup = this.block.querySelectorAll( '.custom-marker' );
			for (let index = 0; index < geojson.features.length; index++) {
				const marker = geojson.features[index];
				const markerLookup = this.markersLookup[ index ];

				const el = document.createElement('div');
				el.className = 'marker';
				el.innerHTML = markerLookup.innerHTML;
				el.setAttribute( 'data-id', markerLookup.getAttribute( 'data-id' ) )

				const popup = new mapboxgl.Popup({ offset: 15 }).setHTML( marker.properties.description );

				// make a marker for each feature and add to the map
				new mapboxgl.Marker(el)
					.setLngLat(marker.geometry.coordinates)
					.setPopup(popup) // sets a popup on this marker
					.addTo(this.map);
			}

			this.filters = this.block.querySelectorAll( '.filters button' );
			this.filters.forEach( button => {
				button.addEventListener( 'click', e => this.clickHandler(e) );
			});

			this.markers = this.mapContainer.querySelectorAll( '.marker' );

			this.map.on('click', 'places', (e) => {
				// Copy coordinates array.
				const coordinates = e.features[0].geometry.coordinates.slice();
				const description = e.features[0].properties.description;

				// Ensure that if the map is zoomed out such that multiple
				// copies of the feature are visible, the popup appears
				// over the copy being pointed to.
				while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
					coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
				}

				new mapboxgl.Popup()
					.setLngLat(coordinates)
					.setHTML(description)
					.addTo(this.map);
			});
		}
    }

	clickHandler( e ) {
		if ( e.target.classList.contains( 'active' ) ) {
			e.target.classList.remove( 'active' );
			this.markers.forEach( marker => {
				marker.classList.remove('hide');
			});
			return;
		}

		this.filters.forEach( btn => {
			btn.classList.remove('active');
		});

		e.target.classList.add( 'active' );

		this.markers.forEach( marker => {
			marker.classList.add('hide');

			if ( marker.getAttribute( 'data-id' ) === e.target.getAttribute( 'data-id' ) ) {
				marker.classList.remove('hide');
			}
		});
	}
}

document.querySelectorAll('.block-courses-map').forEach((block) => {
	new CoursesMap( block );
});
Page Title
Page Type
Page URL

Animation: