// // SiteSection extends Stage // var SiteSection = function (context) { Stage.apply (this, arguments); var element = this.element; element.style.position = "relative"; this.texture = element; var fragmentName = this.fragmentName = element.getAttribute ("data-fragment-name"); var viewHeightScale = element.getAttribute ("data-screen-height"); if (viewHeightScale) this.viewHeightScale = parseFloat (viewHeightScale); this.addListener ("resize", this.resize, this); }; SiteSection.createSections = function () { var sectionElements = document.querySelectorAll ("div[data-class-name]"); var sections = this.sections = new Array (); var sectionMap = this.sectionMap = new Object (); for (var i = 0; i < sectionElements.length; i++) { var sectionElement = sectionElements [i]; var className = sectionElement.getAttribute ("data-class-name"); var section = Stage.fromElement.call ( window [className], sectionElement ); sections.push (section); sectionMap [section.fragmentName || className] = section; } }; SiteSection.prototype = Object.create (Stage.prototype); SiteSection.prototype.shouldAutoResize = false; SiteSection.prototype.paddingBottom = 0; SiteSection.prototype.setColour = SolidSprite.prototype.setColour; SiteSection.prototype.viewHeightScale = 1; SiteSection.prototype.resize = function (sender) { var context = this.context; var viewportSize = context.getViewportSize (); var windowSize = context.getWindowSize (); var viewSize = this.viewSize = this.fixedViewSize ([ windowSize [0], viewportSize [1] ]); viewSize [1] = Math.round (viewSize [1]); this.setSize (undefined, viewSize [1]); }; SiteSection.prototype.fixedViewSize = function (viewportSize) { var paddingBottom = this.paddingBottom || 0; return [ viewportSize [0], viewportSize [1] * this.viewHeightScale - paddingBottom ]; }; SiteSection.MODE_DESKTOP_LARGE = "desktop-large"; SiteSection.MODE_DESKTOP_SMALL = "desktop"; SiteSection.MODE_TABLET = "tablet"; SiteSection.MODE_MOBILE = "mobile"; SiteSection.prototype.updateLayout = function () { var viewSize = this.viewSize; var content = this.content; if (content) { var contentSize = content.textureSize; var paddingTop = this.paddingTop || 72 + 6; // 60; // 99; content.setPosition ( (viewSize [0] - contentSize [0]) / 2, (viewSize [1] - contentSize [1]) / 2 + paddingTop / 2 ); } }; SiteSection.prototype.injectedImageIntoContainerForName = function (containerElement, imageName, imageAlignment, imageAlignmentVertical) { containerElement.style.position = "relative"; containerElement.style.overflow = "hidden"; var image = this.attachSprite (TexturedSprite); image.containerElement = containerElement; image.alignment = alignmentFromAttribute (imageAlignment); if (imageAlignmentVertical) { image.alignmentHorizontal = image.alignment; image.alignmentVertical = alignmentFromAttribute (imageAlignmentVertical); } image.element.style.zIndex = -1; image.addListener ("complete", this.completeInjectedImage, this); image.loadTexture ( BASE_PATH + "images/" + imageName + "_" + (USE_LOW_RESOLUTION ? "1024" : "1440") + ".jpg" ); containerElement.insertBefore ( image.element, containerElement.firstChild ); return image; }; SiteSection.prototype.completeInjectedImage = function (image) { image.removeListener ("complete", this.completeInjectedImage, this); this.updateLayout (); }; SiteSection.prototype.fitInjectedImage = function (image) { if (!image || !image.isComplete) return; var containerElement = image.containerElement; var bounds = containerElement.getBoundingClientRect (); if (image.alignmentHorizontal) { var mode = Navigation.sharedInstance.mode; image.fitInSize ( this.viewSize, mode == "mobile-small" || mode == "mobile" ? image.alignmentVertical : image.alignmentHorizontal ); } else { image.fitInSize ( this.viewSize, image.alignment ); } image.renderInContext (this.context); }; // // GallerySection extends SiteSection // var GallerySection = function (context) { SiteSection.apply (this, arguments); var element = this.element; var contentElement = element.querySelector ("#startSectionContent"); var galleryElements = element.querySelectorAll (".start-teaser"); var gallery = this.gallery = this.attachSprite (Gallery); gallery.buildFromElements (galleryElements); if (galleryElements.length > 1) { var buttonLeft = this.buttonLeft = this.newControlButton ("icon-arrow-left", [15, 45]); var buttonRight = this.buttonRight = this.newControlButton ("icon-arrow-right", [15, 45]); buttonLeft.addListener ("click", this.clickGalleryControlButton, this); buttonRight.addListener ("click", this.clickGalleryControlButton, this); } if (element.getAttribute ("data-show-scroll-down-button") != "no") { var buttonDown = this.buttonDown = this.newControlButton ("icon-arrow-down", [45, 15]); buttonDown.addListener ("click", this.clickButtonDown, this); } }; GallerySection.prototype = Object.create (SiteSection.prototype); GallerySection.prototype.newControlButton = function (imageName, size) { var button = this.attachSprite (IconSprite); button.setTextureSize (size); button.takeDescription ({ imageName: "ui/" + imageName + "-", imageFileType: "svg", textures: ["desktop", "mobile"] }); // button.makeHoverable (); return button; }; GallerySection.prototype.paddingTop = 12; // 60; GallerySection.prototype.paddingBottom = 0; // 150; SiteSection.prototype.fixedViewSize = function (viewportSize) { var paddingBottom = this.paddingBottom || 0; return [ viewportSize [0], Math.max (450, viewportSize [1] * this.viewHeightScale - paddingBottom) ]; }; GallerySection.prototype.resize = function (sender) { SiteSection.prototype.resize.apply (this, arguments); var viewSize = this.viewSize; var gallery = this.gallery; gallery.setViewSize (viewSize); if (!gallery.isAwake) gallery.awake (); var mode = RenderContext.resizeDispatcher.mode; var modeName = mode.modeName; var isMobile = modeName == SiteSection.MODE_MOBILE; this.setIsMobile (isMobile); var horizontalPadding = (isMobile ? 20 : 40) - 2; var buttonLeft = this.buttonLeft; if (buttonLeft) { buttonLeft.setPosition ( horizontalPadding, (viewSize [1] - buttonLeft.textureSize [1]) / 2 + this.paddingTop / 2 ); var buttonRight = this.buttonRight; buttonRight.setPosition ( viewSize [0] - buttonLeft.textureSize [0] - horizontalPadding, buttonLeft.position [1] ); } var buttonDown = this.buttonDown; if (buttonDown) buttonDown.setPosition ( (viewSize [0] - buttonDown.textureSize [0]) / 2, viewSize [1] - buttonDown.textureSize [1] - horizontalPadding ); this.updateLayout (); this.renderInContext (this.context); }; GallerySection.prototype.setIsMobile = function (isMobile) { if (this.isMobile == isMobile) return; this.isMobile = isMobile; var buttonLeft = this.buttonLeft; if (buttonLeft) { var buttonRight = this.buttonRight; var buttonDown = this.buttonDown; if (isMobile) { buttonLeft.setTextureSize ([8, 25]); buttonRight.setTextureSize ([8, 25]); if (buttonDown) buttonDown.setTextureSize ([25, 8]); buttonLeft.setState (1, true); buttonRight.setState (1, true); if (buttonDown) buttonDown.setState (1, true); } else { buttonLeft.setTextureSize ([15, 45]); buttonRight.setTextureSize ([15, 45]); if (buttonDown) buttonDown.setTextureSize ([45, 15]); buttonLeft.setState (1, false); buttonRight.setState (1, false); if (buttonDown) buttonDown.setState (1, false); } } }; GallerySection.prototype.clickGalleryControlButton = function (sender) { var gallery = this.gallery; gallery.advanceInDirection ( sender == this.buttonLeft ? -1 : 1 ); }; GallerySection.prototype.clickButtonDown = function (buttonDown) { // trace ("down"); Navigation.sharedInstance.scrollTo (this.viewSize [1] - 99); }; // // MenuSection extends SiteSection // var MenuSection = function (context) { SiteSection.apply (this, arguments); var container = this.container = this.attachSprite (); container.element.className += " full-width"; var mobileContainer = this.mobileContainer = this.attachSprite (); mobileContainer.element.className += " full-width"; var items = this.items = new Array (); var mobileItems = this.mobileItems = new Array (); this.buildMenuItems (); var stage = this.getStage (); stage.addListener ("mousemove", this.mouseMoveStage, this); this.enableInteractivity (); }; MenuSection.prototype = Object.create (SiteSection.prototype); MenuSection.prototype.paddingTop = 20 - 1; MenuSection.prototype.setIsMobile = function (isMobile) { if (this.isMobile === isMobile) return; this.isMobile = isMobile; var container = this.container; var mobileContainer = this.mobileContainer; if (isMobile) { this.removeChild (container); this.addChild (mobileContainer); } else { this.removeChild (mobileContainer); this.addChild (container); } }; /* MenuSection.prototype.fixedViewSize = function (viewportSize) { if (this.isMobile) { var size = SiteSection.prototype.fixedViewSize.apply (this, arguments); size [1] = Math.max (700, size [1] - 99 + 10); return size; } else { return [ viewportSize [0], viewportSize [0] / 6 ]; } }; */ MenuSection.prototype.resize = function (sender) { var size = this.size; var viewportSize = RenderContext.getViewportSize (); var isMobile = viewportSize [0] <= 1024; this.setIsMobile (isMobile); var container = this.container; container.setSize (size [0], undefined); container.renderInContext (this.context); SiteSection.prototype.resize.apply (this, arguments); this.updateLayout (); this.renderInContext (this.context); }; MenuSection.prototype.buildMenuItems = function () { var container = this.container; var mobileContainer = this.mobileContainer; var items = this.items; var mobileItems = this.mobileItems; var itemElementContainer = document.getElementById ("menuSectionContent"); var itemElements = itemElementContainer.querySelectorAll ("ul > li"); for (var i = 0; i < itemElements.length; i++) { var itemElement = itemElements [i].cloneNode (true); var item = container.attachSprite (MenuSection.Item); item.index = i; item.takeContentElement (itemElement); item.element.classList.add ("shape"); items.push (item); itemElement = itemElements [i]; var mobileItem = mobileContainer.attachSprite (MenuSection.Item); mobileItem.takeContentElement (itemElement); mobileItems.push (mobileItem); } }; MenuSection.prototype.updateLayout = function () { SiteSection.prototype.updateLayout.apply (this, arguments); if (this.isMobile) this.updateLayoutForMobile (); else this.updateLayoutForDesktop (); }; MenuSection.prototype.updateLayoutForDesktop = function () { // trace ("upd lay", this.isMobile); var viewSize = this.viewSize; var items = this.items; var padding = 40; var width = viewSize [0]; // - 2 * padding; var itemWidth = width / items.length; // items [0].paddingLeft = 25; // items [items.length - 1].paddingRight = 25; var cursor = 0; for (var i = 0; i < items.length; i++) { var item = items [i]; /* var itemRightBound = i < items.length - 1 ? Math.round (padding + ((i + 1) * itemWidth)) : viewSize [0]; */ var itemRightBound = Math.round ((i + 1) * itemWidth); item.setPosition (cursor, 0); item.setViewSize ([ itemRightBound - cursor, viewSize [1] ]); cursor = itemRightBound; } }; MenuSection.prototype.updateLayoutForMobile = function () { // trace ("upd lay for mob", this.isMobile, this.viewSize); var viewSize = this.viewSize; var items = this.mobileItems; var paddingTop = 0; var height = viewSize [1] - paddingTop; var itemHeight = height / items.length; var cursor = paddingTop; for (var i = 0; i < items.length; i++) { var item = items [i]; var itemTopBound = Math.round (itemHeight * (i + 1) + paddingTop); item.setViewSize ([ viewSize [0], itemTopBound - cursor ]); item.setPosition (0, cursor); // trace (item, item.position, item.viewSize); cursor = itemTopBound; } viewSize [1] = Math.round (Math.max (viewSize [1], cursor)); this.setSize ( undefined, viewSize [1] ); }; MenuSection.prototype.enableInteractivity = function () { if (this.isInteractivityEnabled) return; this.isInteractivityEnabled = true; var items = this.items; for (var i = 0; i < items.length; i++) { var item = items [i]; item.element.classList.remove ("shape"); item.addListener ("mouseover", this.mouseOverItem, this); item.addListener ("mouseout", this.mouseOutItem, this); } }; MenuSection.prototype.disableInteractivity = function () { if (!this.isInteractivityEnabled) return; this.isInteractivityEnabled = false; this.removeRunLoopHandler ("deferredEnableInteractivity"); // trace ("disable interact"); var items = this.items; for (var i = 0; i < items.length; i++) { var item = items [i]; item.element.classList.add ("shape"); item.removeListener ("mouseover", this.mouseOverItem, this); item.removeListener ("mouseout", this.mouseOutItem, this); } this.mouseOutItem (); }; MenuSection.prototype.mouseMoveStage = function (stage) { var event = stage.currentEvent; var mouse = this.touchDescriptionForObject (event); this.lastMouse = mouse; }; MenuSection.prototype.mouseOverItem = function (item) { this.highlightItem (item); }; MenuSection.prototype.mouseOutItem = function (item) { this.highlightItem (null); }; MenuSection.prototype.highlightItem = function (item) { this.highlightedItem = item; this.addRunLoopHandler ("deferredHighlightItem"); }; MenuSection.prototype.deferredHighlightItem = function (item) { this.removeRunLoopHandler ("deferredHighlightItem"); var lastHighlightedItem = this.lastHighlightedItem; if (lastHighlightedItem) lastHighlightedItem.setIsHighlighted (false); var highlightedItem = this.highlightedItem; if (highlightedItem) highlightedItem.setIsHighlighted (true); this.lastHighlightedItem = highlightedItem; }; // // MenuSection.Item extends CroppingSprite // MenuSection.Item = function (context) { CroppingSprite.apply (this, arguments); var element = this.element; this.texture = element; element.className += " button"; var background = this.background = this.attachSprite (TexturedSprite); var overlay = this.overlay = this.attachSprite (AnimatableSprite); overlay.element.style.zIndex = 1; overlay.element.style.width = "100%"; overlay.element.style.height = "100%"; overlay.setAlpha (1); var overlayBackground = this.overlayBackground = overlay.attachSprite (SolidSprite); overlayBackground.setColour ("rgba(0, 0, 0, .8)"); overlayBackground.setAlpha (0); var content = this.content = overlay.attachSprite (ContainerSprite); this.addListener ("click", this.click, this); }; MenuSection.Item.prototype = Object.create (CroppingSprite.prototype); MenuSection.Item.prototype.toString = function () { return "[MenuSection.Item " + this.head.texture.textContent + "]"; }; function alignmentFromAttribute (alignmentAttribute) { if (alignmentAttribute) { var alignmentAttributes = alignmentAttribute.toString ().split (";"); return [ parseFloat (alignmentAttributes [0]), parseFloat (alignmentAttributes [1]) ]; } else { return undefined; } } MenuSection.Item.prototype.takeContentElement = function (contentElement) { this.contentElement = contentElement; var background = this.background; var backgroundImagePath = this.backgroundImagePath = contentElement.getAttribute ("data-background-image"); if (backgroundImagePath) { background.addListener ("complete", this.completeBackground, this); background.loadTexture (BASE_PATH + "images/" + backgroundImagePath + "_vertical.jpg"); this.backgroundAlignmentVertical = alignmentFromAttribute (contentElement.getAttribute ("data-background-image-alignment-vertical")); } else { this.setColour (contentElement.getAttribute ("data-background-colour")); this.updateBackgroundSize (); } // this.setColour (contentElement.getAttribute ("data-background-colour")); var content = this.content; content.setSize (undefined, undefined); content.takeOverElement (contentElement); content.element.style.display = ""; content.element.style.left = ""; content.element.style.top = ""; content.element.style.width = "100%"; content.element.style.height = "100%"; contentElement.style.display = "table"; contentElement.style.height = "100%"; contentElement.firstElementChild.style.display = "table-cell"; contentElement.firstElementChild.style.verticalAlign = "middle"; var targetURL = this.targetURL = contentElement.querySelectorAll ("a") [0].getAttribute ("href"); }; MenuSection.Item.prototype.completeBackground = function (background) { background.removeListener ("complete", this.completeBackground, this); var texture = background.texture; var transform = "translateZ(0)"; if (IS_WEBKIT) { texture.style.webkitTransform = transform; } else { texture.style.transform = transform; } this.updateBackgroundSize (this); }; MenuSection.Item.prototype.updateBackgroundSize = function () { var viewSize = this.viewSize; if (!viewSize) return; var background = this.background; background.fitInSize ( viewSize, this.backgroundAlignmentVertical || [.9, .5] ); }; MenuSection.Item.prototype.paddingLeft = 0; MenuSection.Item.prototype.paddingRight = 0; MenuSection.Item.prototype.setViewSize = function (viewSize) { this.viewSize = viewSize; this.setSize (viewSize); this.updateBackgroundSize (); var overlayBackground = this.overlayBackground; overlayBackground.setSize (viewSize); }; MenuSection.Item.prototype.setIsHighlighted = function (isHighlighted) { if (this.isHighlighted == isHighlighted) return; this.isHighlighted = isHighlighted; var overlayBackground = this.overlayBackground; if (isHighlighted) { overlayBackground.fadeIn (2); } else { overlayBackground.fadeOut (); } }; MenuSection.Item.prototype.click = function (sender) { var event = sender.currentEvent; event.preventDefault (); var targetURL = this.targetURL; window.open (targetURL, "_self"); }; // // ContentSection extends SiteSection // var ContentSection = function (context) { SiteSection.apply (this, arguments); var element = this.element; var contentElement = this.contentElement = element.firstElementChild; var backgroundImageName = element.getAttribute ("data-background-image"); if (backgroundImageName) { var headerImage = this.headerImage = this.injectedImageIntoContainerForName ( element, backgroundImageName, element.getAttribute ("data-background-image-alignment"), element.getAttribute ("data-background-image-alignment-vertical") ); } this.resize (); }; ContentSection.prototype = Object.create (SiteSection.prototype); ContentSection.prototype.paddingTop = 70; ContentSection.prototype.viewHeightScale = .5; ContentSection.prototype.resize = function (sender) { var context = this.context; var viewportSize = context.getViewportSize (); var windowSize = context.getWindowSize (); this.element.style.height = "auto"; var contentElement = this.contentElement; var contentHeight = contentElement.offsetHeight; var viewSize = this.viewSize = this.fixedViewSize ([ windowSize [0], viewportSize [1] ]); viewSize [1] = Math.round (Math.max (viewSize [1], contentHeight)); this.setSize (undefined, viewSize [1]); this.updateLayout (); this.renderInContext (); }; ContentSection.prototype.updateLayout = function () { SiteSection.prototype.updateLayout.apply (this); this.fitInjectedImage (this.headerImage); } // // GridSection extends SiteSection // function GridSection (context) { SiteSection.apply (this, arguments); var element = this.element; var gridContainer = this.gridContainer = element.querySelector (".content-grid"); gridContainer.style.display = "table"; var gridItems = this.gridItems = element.querySelectorAll (".content-grid > div"); var gridRows = this.gridRows = new Array (); }; GridSection.prototype = Object.create (SiteSection.prototype); GridSection.prototype.resize = function (sender) { var viewportSize = RenderContext.getViewportSize (); var gridWidth = viewportSize [0] < 640 ? 1 : viewportSize [0] < 1024 ? 2 : viewportSize [0] < 1600 ? 3 : 4; this.setGridWidth (gridWidth); var viewportSize = RenderContext.getViewportSize (); var layoutWidth = viewportSize [0] / gridWidth; var rowHeight = Math.round (layoutWidth * (gridWidth > 1 ? 1 / 4 * 2.66 : 1 / 16 * 9)); var gridRows = this.gridRows; for (var i = gridRows.length; i--;) { var gridRow = gridRows [i]; gridRow.style.height = rowHeight + "px"; } this.setSize (0, 0); var element = this.element; element.style.width = "100%"; element.style.height = "auto"; }; GridSection.prototype.setGridWidth = function (gridWidth) { if (this.gridWidth == gridWidth) return; this.gridWidth = gridWidth; var gridRows = this.gridRows; while (gridRows.length) { var gridRow = gridRows.pop (); gridRow.parentNode.removeChild (gridRow); } var gridContainer = this.gridContainer; var gridItems = this.gridItems; for (var i = 0; i < gridItems.length; i++) { var gridItem = gridItems [i]; if (!(i % gridWidth)) { gridRow = document.createElement ("div"); gridRow.style.display = "table-row"; gridContainer.appendChild (gridRow); gridRows.push (gridRow); } gridRow.appendChild (gridItem); } while (gridRow.childNodes.length < gridWidth) { var gridItem = document.createElement ("div"); gridItem.classList.add ("placeholder"); gridRow.appendChild (gridItem); } }; // // VideoGridSection extends GridSection // function VideoGridSection (context) { GridSection.apply (this, arguments); var gridItems = this.gridItems; var gridItemControllers = this.gridItemControllers = new Array (); for (var i = gridItems.length; i--;) { var gridItem = gridItems [i]; var gridItemController = this.gridItemController = this.attachSprite (VideoGridSection.ItemController); gridItemController.takeElement (gridItem); gridItemControllers.push (gridItemController); } }; VideoGridSection.prototype = Object.create (GridSection.prototype); VideoGridSection.prototype.resize = function (sender) { GridSection.prototype.resize.apply (this, arguments); var gridItemControllers = this.gridItemControllers; for (var i = gridItemControllers.length; i--;) { var gridItemController = gridItemControllers [i]; gridItemController.updateLayout (); } this.renderInContext (); }; // // VideoGridSection.ItemController extends AnimatableSprite // VideoGridSection.ItemController = function (context) { AnimatableSprite.apply (this, arguments); }; VideoGridSection.ItemController.prototype = Object.create (AnimatableSprite.prototype); VideoGridSection.ItemController.prototype.takeElement = function (element) { this.element.parentNode.removeChild (this.element); this.element = element; element.style.position = "relative"; element.style.overflow = "hidden"; element.classList.add ("button"); element.classList.add ("video-controller"); var playButton = this.playButton = this.attachSprite (TexturedSprite); playButton.element.classList.add ("video-controller-play-button"); playButton.setSize (50, 50); playButton.loadTexture ( BASE_PATH + "images/ui/button-video-play.svg" ); this.playButtonOffset = parseFloat (element.getAttribute ("data-play-button-offset")) || 0; element.insertBefore (playButton.element, element.firstChild); var background = this.background = this.attachSprite (TexturedSprite); // background.setAlpha (.2); background.element.style.zIndex = -1; var backgroundImagePath = element.getAttribute ("data-background-image"); if (backgroundImagePath) { this.backgroundImageAlignment = alignmentFromAttribute (element.getAttribute ("data-background-image-alignment")) || [.5, .5]; background.addListener ("complete", this.completeBackground, this); background.loadTexture (BASE_PATH + "images/" + backgroundImagePath); } element.insertBefore (background.element, element.firstChild); this.minHeight = parseFloat (element.getAttribute ("data-min-height")); this.addListener ("click", this.click, this); }; VideoGridSection.ItemController.prototype.completeBackground = function (background) { background.removeListener ("complete", this.completeBackground, this); this.updateBackgroundLayout (); }; VideoGridSection.ItemController.prototype.updateLayout = function (background) { var element = this.element; var minHeight = this.minHeight; if (minHeight) { var mode = Navigation.sharedInstance.mode; if (mode == "mobile-small" || mode == "mobile") element.style.minHeight = minHeight + "px"; else element.style.minHeight = ""; } var bounds = element.getBoundingClientRect (); var playButton = this.playButton; var playButtonOffset = this.playButtonOffset; playButton.setPosition ( (bounds.width - playButton.size [0]) / 2, (bounds.height - playButton.size [1]) / 2 - 20 + playButtonOffset ); this.viewSize = [bounds.width, bounds.height]; this.updateBackgroundLayout (); }; VideoGridSection.ItemController.prototype.updateBackgroundLayout = function () { var viewSize = this.viewSize; var background = this.background if (!(viewSize && background.isComplete)) return; var imageSize = background.textureSize; var scale = Math.max ( viewSize [0] / imageSize [0], viewSize [1] / imageSize [1] ); background.setSize ( imageSize [0] * scale, imageSize [1] * scale ); imageSize = background.size; var alignment = this.backgroundImageAlignment; background.setPosition ( (viewSize [0] - imageSize [0]) / 2, (viewSize [1] - imageSize [1]) / 2 ); }; VideoGridSection.ItemController.prototype.click = function (sender) { var overlay = this.overlay = this.attachSprite (VideoOverlay); var element = this.element; element.insertBefore (overlay.element, element.firstChild); overlay.takeSourceElement (element); overlay.startVideo (element.getAttribute ("data-video-id")); }; // // VideoHeaderSection extends ContentSection // var VideoHeaderSection = function (context) { ContentSection.apply (this, arguments); var element = this.element; var videoItem = element.querySelector (".content-table > div"); var videoController = this.videoController = this.attachSprite (VideoGridSection.ItemController); videoController.takeElement (videoItem); }; VideoHeaderSection.prototype = Object.create (ContentSection.prototype); VideoHeaderSection.prototype.resize = function (sender) { var videoController = this.videoController; if (videoController) videoController.updateLayout (); ContentSection.prototype.resize.apply (this, arguments); this.renderInContext (); }; // // VideoOverlay extends AnimatableSprite // VideoOverlay = function (context) { AnimatableSprite.apply (this, arguments); VideoOverlay.sharedInstance = this; var element = this.element; element.classList.add ("video-overlay"); var background = this.background = this.attachSprite (SolidSprite); background.element.style.overflow = "hidden"; background.setColour (0x0); var videoContainer = this.videoContainer = this.attachSprite (ContainerSprite); var tag = document.createElement ("script"); tag.src = "https://www.youtube.com/iframe_api"; var firstScriptTag = document.getElementsByTagName ("script") [0]; firstScriptTag.parentNode.insertBefore (tag, firstScriptTag); context.resizeDispatcher.addListener ("postResize", this.resize, this) var closeButton = this.closeButton = this.attachSprite (SolidSprite); if (IS_IPAD) { closeButton.element.style.marginBottom = "27px"; } else if (IS_IPHONE) { closeButton.element.classList.add ("i-phone"); } closeButton.setPosition (undefined, undefined); closeButton.element.classList.add ("close-button"); this.getStage ().addListener ("leaveScreen", this.leaveScreenStage, this); }; VideoOverlay.prototype = Object.create (AnimatableSprite.prototype); VideoOverlay.prototype.takeSourceElement = function (sourceElement) { this.sourceElement = sourceElement; }; VideoOverlay.prototype.startVideo = function (resourceId) { this.resourceId = resourceId; this.setPosition (0, 0); this.startAnimation ("Zoom", {direction: 1, rate: .03 / 1}); this.addListener (IS_TOUCH_DEVICE ? "touchend" : "click", this.click, this); VideoOverlay.isActive = true; }; VideoOverlay.prototype.stopVideo = function (resourceId) { this.isPlaying = false; var player = this.player; try { player.stopVideo (); player.destroy (); } catch (exception) { var delayedDestroy = window.setInterval (function () { try { player.stopVideo (); player.destroy (); window.clearInterval (delayedDestroy); } catch (exception) {} }, 60); } VideoOverlay.isActive = false; }; VideoOverlay.prototype.click = function (sender) { /* var site = Site.sharedInstance; var scrollingController = site.scrollingController; if (scrollingController.didDrag) return; */ var videoContainer = this.videoContainer; if (videoContainer.parent) videoContainer.parent.removeChild (videoContainer); var event = sender.currentEvent; event.stopPropagation (); this.startAnimation ("Zoom", {direction: 0, rate: .03 / 1}); this.stopVideo (); }; VideoOverlay.prototype.animateZoom = function () { var state = this.updatedState ("Zoom"); var t = state.phase; if (state.direction) { t = 1 - t; t = 1 - t * t * t; } else { t = t * t * t; } t = .5 - Math.cos (t * Math.PI) / 2; this.drawZoomForT (t); }; VideoOverlay.prototype.drawZoomForT = function (t) { this.lastT = t; var t_ = 1 - t; var selfBounds = this.element.getBoundingClientRect (); this.setPosition (0, this.position [1] - selfBounds.top); var sourceElement = this.sourceElement; var sourceFrameBounds = sourceElement.getBoundingClientRect (); var viewSize = RenderContext.getViewportSize (); var rectLeft = t_ * (sourceFrameBounds.left); var rectTop = t_ * sourceFrameBounds.top; var rectRight = rectLeft + t_ * (sourceFrameBounds.right - sourceFrameBounds.left) + t * viewSize [0]; var rectBottom = t_ * (sourceFrameBounds.bottom) + t * viewSize [1]; var background = this.background; background.setPosition ( Math.round (rectLeft), Math.round (rectTop) ); background.setSize ( Math.round (rectRight - background.position [0]), Math.round (rectBottom - background.position [1]) ); this.setAlpha (t); if (t == 0) { this.parent.removeChild (this); } else if (t == 1) { if (this.resourceId) { this.setUpVideoContainer (); } } }; VideoOverlay.prototype.setUpVideoContainer = function () { this.isPlaying = true; var videoContainer = this.videoContainer; videoContainer.setSize (undefined, undefined); var videoSnippet = document.createElement ("div"); videoSnippet.innerHTML = '
'; var videoTexture = videoSnippet.firstElementChild; videoContainer.takeOverElement (videoTexture); // this.updatePlayerSize (); videoContainer.setAlpha (0); videoContainer.fadeIn (1, 45); this.resourceId = null; }; VideoOverlay.prototype.updatePlayerSize = function () { var videoContainer = this.videoContainer; var stageSize = RenderContext.getViewportSize (); var breakpoint = Navigation.sharedInstance.mode; var margin; switch (breakpoint) { case "mobile": case "mobile-small": margin = [0, 0, 0, 0]; break; case "tablet": margin = [60, 0, 88, 0]; break; case "desktop": margin = [100, 0, 96, 0]; break; } var layoutSpace = [ stageSize [0] - margin [1] - margin [3], stageSize [1] - margin [0] - margin [2] ]; var videoSize = [16, 9]; var scale = Math.min ( layoutSpace [0] / videoSize [0], layoutSpace [1] / videoSize [1] ); videoSize = [ Math.round (videoSize [0] * scale), Math.round (videoSize [1] * scale) ]; var videoContainerElement = videoContainer.element; videoContainer.element.style.width = videoSize [0] + "px"; videoContainer.element.style.height = videoSize [1] + "px"; var videoPosition = [ (layoutSpace [0] - videoSize [0]) / 2 + margin [3], (layoutSpace [1] - videoSize [1]) / 2 + margin [0] ]; videoContainer.element.style.left = videoPosition [0] + "px"; videoContainer.element.style.top = videoPosition [1] + "px"; }; VideoOverlay.prototype.resize = function () { if (this.alpha) { this.drawZoomForT (this.lastT); this.updatePlayerSize (); } }; VideoOverlay.prototype.leaveScreenStage = function () { if (this.isPlaying) { this.removeRunLoopHandler ("Zoom"); this.states ["Zoom"] = {phase: 0}; this.startAnimation ("Fade", {direction: 0, phase: this.alpha, rate: .05}); this.stopVideo (); } }; // // DropDownSection extends SiteSection // var DropDownSection = function (context) { SiteSection.apply (this, arguments); var element = this.element; var dropDowns = this.dropDowns = new Array (); var dropDownElements = element.querySelectorAll (".drop-down-item"); for (var i = dropDownElements.length; i--;) { var dropDownElement = dropDownElements [i]; var dropDown = this.attachSprite (DropDownSection.DropDown); dropDown.takeElement (dropDownElement); dropDowns.push (dropDown); } }; DropDownSection.prototype = Object.create (SiteSection.prototype); DropDownSection.prototype.resize = function () { this.setSize (0, 0); var element = this.element; element.style.width = "100%"; element.style.height = "auto"; }; // // DropDownSection.DropDown extends AnimatableSprite // DropDownSection.DropDown = function (context) { AnimatableSprite.apply (this, arguments); }; DropDownSection.DropDown.prototype = Object.create (AnimatableSprite.prototype); DropDownSection.DropDown.prototype.takeElement = function (element) { this.element.parentNode.removeChild (this.element); this.element = element; var isOpen = this.isOpen = element.classList.contains ("open"); if (isOpen) this.states ["Expansion"] = {phase: 1}; element.classList.add ("button"); var contentElement = this.contentElement = element.querySelector (".drop-down-content"); contentElement.style.overflow = "hidden"; this.addListener ("click", this.toggle, this); }; DropDownSection.DropDown.prototype.toggle = function (sender) { if (this.isOpen) this.collapse (); else this.expand (); }; DropDownSection.DropDown.prototype.collapse = function () { this.isOpen = false; this.element.classList.remove ("open"); this.measureExpandedHeight (); this.startAnimation ("Expansion", {direction: 0, rate: .065}); }; DropDownSection.DropDown.prototype.expand = function () { this.isOpen = true; this.element.classList.add ("open"); this.measureExpandedHeight (); this.startAnimation ("Expansion", {direction: 1, rate: .065}); }; DropDownSection.DropDown.prototype.measureExpandedHeight = function () { var contentElement = this.contentElement; contentElement.style.display = "block"; contentElement.style.height = ""; var expandedHeight = this.expandedHeight = contentElement.offsetHeight; }; DropDownSection.DropDown.prototype.animateExpansion = function () { var state = this.updatedState ("Expansion"); var t = state.phase; if (state.direction > 0) { t = 1 - t; t = 1 - t * t; } else { t = t * t; } t = .5 - Math.cos (t * Math.PI) / 2; var contentElement = this.contentElement; contentElement.style.height = t == 1 ? "auto" : t * this.expandedHeight + "px"; contentElement.style.display = t == 0 ? "none" : "block"; contentElement.style.overflow = t == 1 ? "" : "hidden"; };