(function () { window.CanvasSlideshow = function (options) { var hasCanvas = false; // SCOPE /// --------------------------- var that = this; // OPTIONS /// --------------------------- options = options || {}; options.stageWidth = options.hasOwnProperty('stageWidth') ? options.stageWidth : 1920; options.stageHeight = options.hasOwnProperty('stageHeight') ? options.stageHeight : 1080; options.pixiSprites = options.hasOwnProperty('sprites') ? options.sprites : []; options.centerSprites = options.hasOwnProperty('centerSprites') ? options.centerSprites : false; options.texts = options.hasOwnProperty('texts') ? options.texts : []; options.autoPlay = options.hasOwnProperty('autoPlay') ? options.autoPlay : true; options.autoPlaySpeed = options.hasOwnProperty('autoPlaySpeed') ? options.autoPlaySpeed : [10, 3]; options.fullScreen = options.hasOwnProperty('fullScreen') ? options.fullScreen : true; options.displaceScale = options.hasOwnProperty('displaceScale') ? options.displaceScale : [10, 3]; options.origImages = options.hasOwnProperty('origImages') ? options.origImages : {}; options.displacementImage = options.hasOwnProperty('displacementImage') ? options.displacementImage : ''; options.navElement = options.hasOwnProperty('navElement') ? options.navElement : document.querySelectorAll('.scene-nav'); options.displaceAutoFit = options.hasOwnProperty('displaceAutoFit') ? options.displaceAutoFit : false; options.wacky = options.hasOwnProperty('wacky') ? options.wacky : false; options.interactive = options.hasOwnProperty('interactive') ? options.interactive : false; options.interactionEvent = options.hasOwnProperty('interactionEvent') ? options.interactionEvent : ''; options.displaceScaleTo = (options.autoPlay === false) ? [0, 0] : [10, 3]; options.textColor = options.hasOwnProperty('textColor') ? options.textColor : '#fff'; options.displacementCenter = options.hasOwnProperty('displacementCenter') ? options.displacementCenter : false; options.dispatchPointerOver = options.hasOwnProperty('dispatchPointerOver') ? options.dispatchPointerOver : false; // PIXI VARIABLES /// --------------------------- var renderer = new PIXI.autoDetectRenderer(options.stageWidth, options.stageHeight, { transparent: true }); var stage = new PIXI.Container(); var slidesContainer = new PIXI.Container(); var displacementSprite = new PIXI.Sprite.fromImage(options.displacementImage); var displacementFilter = new PIXI.filters.DisplacementFilter(displacementSprite); // TEXTS /// --------------------------- var style = new PIXI.TextStyle({ fill: options.textColor, wordWrap: true, wordWrapWidth: 400, letterSpacing: 20, fontSize: 14 }); // SLIDES ARRAY INDEX /// --------------------------- this.currentIndex = 0; /** * 移除canvas */ this.removeCanvas = function () { let indexCanvas = document.getElementById("indexCanvas"); let parentDiv = document.getElementById("index-body"); if(indexCanvas && parentDiv){ indexCanvas.height=0; renderer.view.clearRect(0,0,renderer.view.style.width ,renderer.view.style.height); renderer.view = null; parentDiv.removeChild(indexCanvas); // document.body.removeChild(indexCanvas); } }; /// --------------------------- // INITIALISE PIXI /// --------------------------- this.initPixi = function () { let indexCanvas = document.getElementById("indexCanvas"); let parentDiv = document.getElementById("index-body"); if(indexCanvas && parentDiv){ // document.body.removeChild(indexCanvas); parentDiv.removeChild(document.getElementById("indexCanvas")); } // Add canvas to the HTML parentDiv.appendChild(renderer.view); // document.body.appendChild(renderer.view); renderer.view.setAttribute("id","indexCanvas"); hasCanvas = true; // Add child container to the main container stage.addChild(slidesContainer); // Enable Interactions stage.interactive = true; console.log(renderer.view.style); // Fit renderer to the screen if (options.fullScreen === true) { renderer.view.style.objectFit = 'cover'; renderer.view.style.width = '92%'; renderer.view.style.height = 'calc(100% - 64px - 50px)'; renderer.view.style.top = '64px'; renderer.view.style.left = '4%'; renderer.view.style.position = 'absolute'; renderer.view.style.webkitTransform = 'translate( 0%, 0% ) scale(1)'; renderer.view.style.transform = 'translate( 0%, 0% ) scale(1)'; renderer.view.style.zIndex="0"; } else { renderer.view.style.maxWidth = '100%'; renderer.view.style.top = '50%'; renderer.view.style.left = '50%'; renderer.view.style.webkitTransform = 'translate( -50%, -50% )'; renderer.view.style.transform = 'translate( -50%, -50% )'; } displacementSprite.texture.baseTexture.wrapMode = PIXI.WRAP_MODES.REPEAT; // Set the filter to stage and set some default values for the animation stage.filters = [displacementFilter]; if (options.autoPlay === false) { displacementFilter.scale.x = 0; displacementFilter.scale.y = 0; } if (options.wacky === true) { displacementSprite.anchor.set(0.5); displacementSprite.x = renderer.width / 2; displacementSprite.y = renderer.height / 2; } const ratioHeight = window.screen.height/754; const ratioWidth = window.screen.width/1100; let ratio = ratioHeight>ratioWidth?ratioHeight:ratioWidth; console.log("ratio:"+ratio); displacementSprite.scale.x = ratio; displacementSprite.scale.y = ratio; displacementSprite.scale.x = 1.2; displacementSprite.scale.y = 1.2; // displacementSprite.position.x = 400; // displacementSprite.position.y = 400; // PIXI tries to fit the filter bounding box to the renderer so we optionally bypass displacementFilter.autoFit = options.displaceAutoFit; stage.addChild(displacementSprite); }; var imageList=[]; /// --------------------------- // LOAD SLIDES TO CANVAS /// --------------------------- this.loadPixiSprites = function (sprites) { imageList = []; var rSprites = options.sprites; var rTexts = options.texts; var origImages = options.origImages; for (var i = 0; i < rSprites.length; i++) { var texture = new PIXI.Texture.fromImage(sprites[i]); var image = new PIXI.Sprite(texture); var origImages = options.origImages; var scaleX; var scaleY; if (rTexts) { var richText = new PIXI.Text(rTexts[i], style); image.addChild(richText); richText.anchor.set(0.5); richText.x = image.width / 2; richText.y = image.height / 2; } if (options.centerSprites === true) { const ratioHeight = window.screen.height/1691; const ratioWidth = window.screen.width/1256; let ratio = ratioHeight>ratioWidth?ratioHeight:ratioWidth; image.width = renderer.width ; image.height = renderer.height; // image.scale.x = ratio; // image.scale.y = ratio; /* scaleX = renderer.width/origImages.get(sprites[i]).width; scaleY = renderer.height/origImages.get(sprites[i]).height; console.log(scaleX + "|" + scaleY); image.scale.x = scaleX; image.scale.y = scaleY;*/ image.position.x = renderer.width / 2; image.position.y = renderer.height / 2; image.anchor.set(0.5); // image.x = renderer.width / 2; // image.y = renderer.height / 2; } if (i !== 0) { TweenMax.set(image, { alpha: 0 }); } imageList.push(image); slidesContainer.addChild(image); } }; /// --------------------------- // DEFAULT RENDER/ANIMATION /// --------------------------- if (options.autoPlay === true) { var ticker = new PIXI.ticker.Ticker(); ticker.autoStart = options.autoPlay; ticker.add(function (delta) { displacementSprite.x += options.autoPlaySpeed[0] * delta; displacementSprite.y += options.autoPlaySpeed[1]; renderer.render(stage); }); } else { var render = new PIXI.ticker.Ticker(); render.autoStart = true; render.add(function (delta) { renderer.render(stage); }); } /// --------------------------- // TRANSITION BETWEEN SLIDES /// --------------------------- var isPlaying = false; var slideImages = slidesContainer.children; this.moveSlider = function (newIndex) { isPlaying = true; var baseTimeline = new TimelineMax({ onComplete: function () { that.currentIndex = newIndex; isPlaying = false; if (options.wacky === true) { displacementSprite.scale.set(1); } }, onUpdate: function () { if (options.wacky === true) { displacementSprite.rotation += baseTimeline.progress() * 10; displacementSprite.scale.set(baseTimeline.progress() * 3); } } }); var baseTimelineFrom = new TimelineMax({ onComplete: function () { }, onUpdate: function () { if (options.wacky === true) { displacementSprite.rotation += baseTimeline.progress() * 10; displacementSprite.scale.set(baseTimeline.progress() * 3); } } }); baseTimelineFrom.clear(); baseTimeline.clear(); if (baseTimeline.isActive()) { return; } if(baseTimelineFrom.isActive()){ return; } baseTimelineFrom // .to(displacementFilter.scale, 1, { x: options.displaceScale[0], y: options.displaceScale[1] }) .to(slideImages[that.currentIndex], 1.5, { alpha: 0 }); baseTimeline // .to(displacementFilter.scale, 1, { // x: options.displaceScaleTo[0], // y: options.displaceScaleTo[1] // }) .to(slideImages[newIndex], 1.5, { alpha: 1 }); }; /// --------------------------- // CLICK HANDLERS /// --------------------------- var nav = options.navElement; for (var i = 0; i < nav.length; i++) { var navItem = nav[i]; navItem.onclick = function (event) { // Make sure the previous transition has ended if (isPlaying) { return false; } if (this.getAttribute('data-nav') === 'next') { if (that.currentIndex >= 0 && that.currentIndex < slideImages.length - 1) { that.moveSlider(that.currentIndex + 1); } else { that.moveSlider(0); } } else { if (that.currentIndex > 0 && that.currentIndex < slideImages.length) { that.moveSlider(that.currentIndex - 1); } else { that.moveSlider(spriteImages.length - 1); } } return false; }; } /// --------------------------- // INIT FUNCTIONS /// --------------------------- this.init = function () { that.initPixi(); that.loadPixiSprites(options.pixiSprites); if ( options.fullScreen === true ) { window.addEventListener("resize", function( event ){ // scaleToWindow( renderer.view ); // that.loadPixiSprites(options.pixiSprites); // console.log("http://localhost:8080/#/index"); // console.log("renderer.width:"+renderer.width); // console.log("renderer.height:"+renderer.height); for(let idx in imageList){ /*let itemImg = imageList[idx]; itemImg.width = renderer.width ; itemImg.height = renderer.height; const ratio = window.screen.height/754; itemImg.scale.x = ratio; itemImg.scale.y = ratio; itemImg.position.x = renderer.width / 2; itemImg.position.y = renderer.height / 2;*/ } }); // scaleToWindow( renderer.view ); } }; /// --------------------------- // INTERACTIONS /// --------------------------- function rotateSpite() { displacementSprite.rotation += 0.001; rafID = requestAnimationFrame(rotateSpite); } if (options.interactive === true) { var rafID, mouseX, mouseY; // Enable interactions on our slider slidesContainer.interactive = true; slidesContainer.buttonMode = true; // HOVER if (options.interactionEvent === 'hover' || options.interactionEvent === 'both') { slidesContainer.pointerover = function (mouseData) { mouseX = mouseData.data.global.x; mouseY = mouseData.data.global.y; TweenMax.to(displacementFilter.scale, 1, { x: '+=' + Math.sin(mouseX) * 100 + '', y: '+=' + Math.cos(mouseY) * 100 + '' }); rotateSpite(); }; slidesContainer.pointerout = function (mouseData) { TweenMax.to(displacementFilter.scale, 1, { x: 0, y: 0 }); cancelAnimationFrame(rafID); }; } // CLICK if (options.interactionEvent === 'click' || options.interactionEvent === 'both') { slidesContainer.pointerup = function (mouseData) { if (options.dispatchPointerOver === true) { TweenMax.to(displacementFilter.scale, 1, { x: 0, y: 0, onComplete: function () { TweenMax.to(displacementFilter.scale, 1, { x: 20, y: 20 }); } }); } else { TweenMax.to(displacementFilter.scale, 1, { x: 0, y: 0 }); cancelAnimationFrame(rafID); } }; slidesContainer.pointerdown = function (mouseData) { mouseX = mouseData.data.global.x; mouseY = mouseData.data.global.y; TweenMax.to(displacementFilter.scale, 1, { x: '+=' + Math.sin(mouseX) * 1200 + '', y: '+=' + Math.cos(mouseY) * 200 + '' }); }; slidesContainer.pointerout = function (mouseData) { if (options.dispatchPointerOver === true) { TweenMax.to(displacementFilter.scale, 1, { x: 0, y: 0, onComplete: function () { TweenMax.to(displacementFilter.scale, 1, { x: 20, y: 20 }); } }); } else { TweenMax.to(displacementFilter.scale, 1, { x: 0, y: 0 }); cancelAnimationFrame(rafID); } }; } } /// --------------------------- // CENTER DISPLACEMENT /// --------------------------- if (options.displacementCenter === true) { displacementSprite.anchor.set(0.5); displacementSprite.x = renderer.view.width / 2; displacementSprite.y = renderer.view.height / 2; } /// --------------------------- // START /// --------------------------- this.init(); /// --------------------------- // HELPER FUNCTIONS /// --------------------------- function scaleToWindow(canvas, backgroundColor) { var scaleX, scaleY, scale, center; //1. Scale the canvas to the correct size //Figure out the scale amount on each axis scaleX = window.innerWidth / canvas.offsetWidth; scaleY = window.innerHeight / canvas.offsetHeight; //Scale the canvas based on whichever value is less: `scaleX` or `scaleY` scale = Math.min(scaleX, scaleY); canvas.style.transformOrigin = '0 0'; canvas.style.transform = 'scale(' + scale + ')'; //2. Center the canvas. //Decide whether to center the canvas vertically or horizontally. //Wide canvases should be centered vertically, and //square or tall canvases should be centered horizontally if (canvas.offsetWidth > canvas.offsetHeight) { if (canvas.offsetWidth * scale < window.innerWidth) { center = 'horizontally'; } else { center = 'vertically'; } } else { if (canvas.offsetHeight * scale < window.innerHeight) { center = 'vertically'; } else { center = 'horizontally'; } } //Center horizontally (for square or tall canvases) var margin; if (center === 'horizontally') { margin = (window.innerWidth - canvas.offsetWidth * scale) / 2; canvas.style.marginTop = 0 + 'px'; canvas.style.marginBottom = 0 + 'px'; canvas.style.marginLeft = margin + 'px'; canvas.style.marginRight = margin + 'px'; } //Center vertically (for wide canvases) if (center === 'vertically') { margin = (window.innerHeight - canvas.offsetHeight * scale) / 2; canvas.style.marginTop = margin + 'px'; canvas.style.marginBottom = margin + 'px'; canvas.style.marginLeft = 0 + 'px'; canvas.style.marginRight = 0 + 'px'; } //3. Remove any padding from the canvas and body and set the canvas //display style to "block" canvas.style.paddingLeft = 0 + 'px'; canvas.style.paddingRight = 0 + 'px'; canvas.style.paddingTop = 0 + 'px'; canvas.style.paddingBottom = 0 + 'px'; canvas.style.display = 'block'; //4. Set the color of the HTML body background document.body.style.backgroundColor = backgroundColor; //Fix some quirkiness in scaling for Safari var ua = navigator.userAgent.toLowerCase(); if (ua.indexOf('safari') != -1) { if (ua.indexOf('chrome') > -1) { // Chrome } else { // Safari //canvas.style.maxHeight = "100%"; //canvas.style.minHeight = "100%"; } } //5. Return the `scale` value. This is important, because you'll nee this value //for correct hit testing between the pointer and sprites return scale; } // http://bit.ly/2y1Yk2k }; })();