canvasIndex.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. (function () {
  2. window.CanvasSlideshow = function (options) {
  3. var hasCanvas = false;
  4. // SCOPE
  5. /// ---------------------------
  6. var that = this;
  7. // OPTIONS
  8. /// ---------------------------
  9. options = options || {};
  10. options.stageWidth = options.hasOwnProperty('stageWidth') ? options.stageWidth : 1920;
  11. options.stageHeight = options.hasOwnProperty('stageHeight') ? options.stageHeight : 1080;
  12. options.pixiSprites = options.hasOwnProperty('sprites') ? options.sprites : [];
  13. options.centerSprites = options.hasOwnProperty('centerSprites') ? options.centerSprites : false;
  14. options.texts = options.hasOwnProperty('texts') ? options.texts : [];
  15. options.autoPlay = options.hasOwnProperty('autoPlay') ? options.autoPlay : true;
  16. options.autoPlaySpeed = options.hasOwnProperty('autoPlaySpeed') ? options.autoPlaySpeed : [10, 3];
  17. options.fullScreen = options.hasOwnProperty('fullScreen') ? options.fullScreen : true;
  18. options.displaceScale = options.hasOwnProperty('displaceScale') ? options.displaceScale : [10, 3];
  19. options.origImages = options.hasOwnProperty('origImages') ? options.origImages : {};
  20. options.displacementImage = options.hasOwnProperty('displacementImage') ? options.displacementImage : '';
  21. options.navElement = options.hasOwnProperty('navElement') ? options.navElement : document.querySelectorAll('.scene-nav');
  22. options.displaceAutoFit = options.hasOwnProperty('displaceAutoFit') ? options.displaceAutoFit : false;
  23. options.wacky = options.hasOwnProperty('wacky') ? options.wacky : false;
  24. options.interactive = options.hasOwnProperty('interactive') ? options.interactive : false;
  25. options.interactionEvent = options.hasOwnProperty('interactionEvent') ? options.interactionEvent : '';
  26. options.displaceScaleTo = (options.autoPlay === false) ? [0, 0] : [10, 3];
  27. options.textColor = options.hasOwnProperty('textColor') ? options.textColor : '#fff';
  28. options.displacementCenter = options.hasOwnProperty('displacementCenter') ? options.displacementCenter : false;
  29. options.dispatchPointerOver = options.hasOwnProperty('dispatchPointerOver') ? options.dispatchPointerOver : false;
  30. // PIXI VARIABLES
  31. /// ---------------------------
  32. var renderer = new PIXI.autoDetectRenderer(options.stageWidth, options.stageHeight, { transparent: true });
  33. var stage = new PIXI.Container();
  34. var slidesContainer = new PIXI.Container();
  35. var displacementSprite = new PIXI.Sprite.fromImage(options.displacementImage);
  36. var displacementFilter = new PIXI.filters.DisplacementFilter(displacementSprite);
  37. // TEXTS
  38. /// ---------------------------
  39. var style = new PIXI.TextStyle({
  40. fill: options.textColor,
  41. wordWrap: true,
  42. wordWrapWidth: 400,
  43. letterSpacing: 20,
  44. fontSize: 14
  45. });
  46. // SLIDES ARRAY INDEX
  47. /// ---------------------------
  48. this.currentIndex = 0;
  49. /**
  50. * 移除canvas
  51. */
  52. this.removeCanvas = function () {
  53. let indexCanvas = document.getElementById("indexCanvas");
  54. let parentDiv = document.getElementById("index-body");
  55. if(indexCanvas && parentDiv){
  56. indexCanvas.height=0;
  57. renderer.view.clearRect(0,0,renderer.view.style.width ,renderer.view.style.height);
  58. renderer.view = null;
  59. parentDiv.removeChild(indexCanvas);
  60. // document.body.removeChild(indexCanvas);
  61. }
  62. };
  63. /// ---------------------------
  64. // INITIALISE PIXI
  65. /// ---------------------------
  66. this.initPixi = function () {
  67. let indexCanvas = document.getElementById("indexCanvas");
  68. let parentDiv = document.getElementById("index-body");
  69. if(indexCanvas && parentDiv){
  70. // document.body.removeChild(indexCanvas);
  71. parentDiv.removeChild(document.getElementById("indexCanvas"));
  72. }
  73. // Add canvas to the HTML
  74. parentDiv.appendChild(renderer.view);
  75. // document.body.appendChild(renderer.view);
  76. renderer.view.setAttribute("id","indexCanvas");
  77. hasCanvas = true;
  78. // Add child container to the main container
  79. stage.addChild(slidesContainer);
  80. // Enable Interactions
  81. stage.interactive = true;
  82. console.log(renderer.view.style);
  83. // Fit renderer to the screen
  84. if (options.fullScreen === true) {
  85. renderer.view.style.objectFit = 'cover';
  86. renderer.view.style.width = '92%';
  87. renderer.view.style.height = 'calc(100% - 64px - 50px)';
  88. renderer.view.style.top = '64px';
  89. renderer.view.style.left = '4%';
  90. renderer.view.style.position = 'absolute';
  91. renderer.view.style.webkitTransform = 'translate( 0%, 0% ) scale(1)';
  92. renderer.view.style.transform = 'translate( 0%, 0% ) scale(1)';
  93. renderer.view.style.zIndex="0";
  94. } else {
  95. renderer.view.style.maxWidth = '100%';
  96. renderer.view.style.top = '50%';
  97. renderer.view.style.left = '50%';
  98. renderer.view.style.webkitTransform = 'translate( -50%, -50% )';
  99. renderer.view.style.transform = 'translate( -50%, -50% )';
  100. }
  101. displacementSprite.texture.baseTexture.wrapMode = PIXI.WRAP_MODES.REPEAT;
  102. // Set the filter to stage and set some default values for the animation
  103. stage.filters = [displacementFilter];
  104. if (options.autoPlay === false) {
  105. displacementFilter.scale.x = 0;
  106. displacementFilter.scale.y = 0;
  107. }
  108. if (options.wacky === true) {
  109. displacementSprite.anchor.set(0.5);
  110. displacementSprite.x = renderer.width / 2;
  111. displacementSprite.y = renderer.height / 2;
  112. }
  113. const ratioHeight = window.screen.height/754;
  114. const ratioWidth = window.screen.width/1100;
  115. let ratio = ratioHeight>ratioWidth?ratioHeight:ratioWidth;
  116. console.log("ratio:"+ratio);
  117. displacementSprite.scale.x = ratio;
  118. displacementSprite.scale.y = ratio;
  119. displacementSprite.scale.x = 1.2;
  120. displacementSprite.scale.y = 1.2;
  121. // displacementSprite.position.x = 400;
  122. // displacementSprite.position.y = 400;
  123. // PIXI tries to fit the filter bounding box to the renderer so we optionally bypass
  124. displacementFilter.autoFit = options.displaceAutoFit;
  125. stage.addChild(displacementSprite);
  126. };
  127. var imageList=[];
  128. /// ---------------------------
  129. // LOAD SLIDES TO CANVAS
  130. /// ---------------------------
  131. this.loadPixiSprites = function (sprites) {
  132. imageList = [];
  133. var rSprites = options.sprites;
  134. var rTexts = options.texts;
  135. var origImages = options.origImages;
  136. for (var i = 0; i < rSprites.length; i++) {
  137. var texture = new PIXI.Texture.fromImage(sprites[i]);
  138. var image = new PIXI.Sprite(texture);
  139. var origImages = options.origImages;
  140. var scaleX;
  141. var scaleY;
  142. if (rTexts) {
  143. var richText = new PIXI.Text(rTexts[i], style);
  144. image.addChild(richText);
  145. richText.anchor.set(0.5);
  146. richText.x = image.width / 2;
  147. richText.y = image.height / 2;
  148. }
  149. if (options.centerSprites === true) {
  150. const ratioHeight = window.screen.height/1691;
  151. const ratioWidth = window.screen.width/1256;
  152. let ratio = ratioHeight>ratioWidth?ratioHeight:ratioWidth;
  153. image.width = renderer.width ;
  154. image.height = renderer.height;
  155. // image.scale.x = ratio;
  156. // image.scale.y = ratio;
  157. /* scaleX = renderer.width/origImages.get(sprites[i]).width;
  158. scaleY = renderer.height/origImages.get(sprites[i]).height;
  159. console.log(scaleX + "|" + scaleY);
  160. image.scale.x = scaleX;
  161. image.scale.y = scaleY;*/
  162. image.position.x = renderer.width / 2;
  163. image.position.y = renderer.height / 2;
  164. image.anchor.set(0.5);
  165. // image.x = renderer.width / 2;
  166. // image.y = renderer.height / 2;
  167. }
  168. if (i !== 0) {
  169. TweenMax.set(image, { alpha: 0 });
  170. }
  171. imageList.push(image);
  172. slidesContainer.addChild(image);
  173. }
  174. };
  175. /// ---------------------------
  176. // DEFAULT RENDER/ANIMATION
  177. /// ---------------------------
  178. if (options.autoPlay === true) {
  179. var ticker = new PIXI.ticker.Ticker();
  180. ticker.autoStart = options.autoPlay;
  181. ticker.add(function (delta) {
  182. displacementSprite.x += options.autoPlaySpeed[0] * delta;
  183. displacementSprite.y += options.autoPlaySpeed[1];
  184. renderer.render(stage);
  185. });
  186. } else {
  187. var render = new PIXI.ticker.Ticker();
  188. render.autoStart = true;
  189. render.add(function (delta) {
  190. renderer.render(stage);
  191. });
  192. }
  193. /// ---------------------------
  194. // TRANSITION BETWEEN SLIDES
  195. /// ---------------------------
  196. var isPlaying = false;
  197. var slideImages = slidesContainer.children;
  198. this.moveSlider = function (newIndex) {
  199. isPlaying = true;
  200. var baseTimeline = new TimelineMax({
  201. onComplete: function () {
  202. that.currentIndex = newIndex;
  203. isPlaying = false;
  204. if (options.wacky === true) {
  205. displacementSprite.scale.set(1);
  206. }
  207. }, onUpdate: function () {
  208. if (options.wacky === true) {
  209. displacementSprite.rotation += baseTimeline.progress() * 10;
  210. displacementSprite.scale.set(baseTimeline.progress() * 3);
  211. }
  212. }
  213. });
  214. var baseTimelineFrom = new TimelineMax({
  215. onComplete: function () {
  216. }, onUpdate: function () {
  217. if (options.wacky === true) {
  218. displacementSprite.rotation += baseTimeline.progress() * 10;
  219. displacementSprite.scale.set(baseTimeline.progress() * 3);
  220. }
  221. }
  222. });
  223. baseTimelineFrom.clear();
  224. baseTimeline.clear();
  225. if (baseTimeline.isActive()) {
  226. return;
  227. }
  228. if(baseTimelineFrom.isActive()){
  229. return;
  230. }
  231. baseTimelineFrom
  232. // .to(displacementFilter.scale, 1, { x: options.displaceScale[0], y: options.displaceScale[1] })
  233. .to(slideImages[that.currentIndex], 1.5, { alpha: 0 });
  234. baseTimeline
  235. // .to(displacementFilter.scale, 1, {
  236. // x: options.displaceScaleTo[0],
  237. // y: options.displaceScaleTo[1]
  238. // })
  239. .to(slideImages[newIndex], 1.5, { alpha: 1 });
  240. };
  241. /// ---------------------------
  242. // CLICK HANDLERS
  243. /// ---------------------------
  244. var nav = options.navElement;
  245. for (var i = 0; i < nav.length; i++) {
  246. var navItem = nav[i];
  247. navItem.onclick = function (event) {
  248. // Make sure the previous transition has ended
  249. if (isPlaying) {
  250. return false;
  251. }
  252. if (this.getAttribute('data-nav') === 'next') {
  253. if (that.currentIndex >= 0 && that.currentIndex < slideImages.length - 1) {
  254. that.moveSlider(that.currentIndex + 1);
  255. } else {
  256. that.moveSlider(0);
  257. }
  258. } else {
  259. if (that.currentIndex > 0 && that.currentIndex < slideImages.length) {
  260. that.moveSlider(that.currentIndex - 1);
  261. } else {
  262. that.moveSlider(spriteImages.length - 1);
  263. }
  264. }
  265. return false;
  266. };
  267. }
  268. /// ---------------------------
  269. // INIT FUNCTIONS
  270. /// ---------------------------
  271. this.init = function () {
  272. that.initPixi();
  273. that.loadPixiSprites(options.pixiSprites);
  274. if ( options.fullScreen === true ) {
  275. window.addEventListener("resize", function( event ){
  276. // scaleToWindow( renderer.view );
  277. // that.loadPixiSprites(options.pixiSprites);
  278. // console.log("http://localhost:8080/#/index");
  279. // console.log("renderer.width:"+renderer.width);
  280. // console.log("renderer.height:"+renderer.height);
  281. for(let idx in imageList){
  282. /*let itemImg = imageList[idx];
  283. itemImg.width = renderer.width ;
  284. itemImg.height = renderer.height;
  285. const ratio = window.screen.height/754;
  286. itemImg.scale.x = ratio;
  287. itemImg.scale.y = ratio;
  288. itemImg.position.x = renderer.width / 2;
  289. itemImg.position.y = renderer.height / 2;*/
  290. }
  291. });
  292. // scaleToWindow( renderer.view );
  293. }
  294. };
  295. /// ---------------------------
  296. // INTERACTIONS
  297. /// ---------------------------
  298. function rotateSpite() {
  299. displacementSprite.rotation += 0.001;
  300. rafID = requestAnimationFrame(rotateSpite);
  301. }
  302. if (options.interactive === true) {
  303. var rafID,
  304. mouseX,
  305. mouseY;
  306. // Enable interactions on our slider
  307. slidesContainer.interactive = true;
  308. slidesContainer.buttonMode = true;
  309. // HOVER
  310. if (options.interactionEvent === 'hover' || options.interactionEvent === 'both') {
  311. slidesContainer.pointerover = function (mouseData) {
  312. mouseX = mouseData.data.global.x;
  313. mouseY = mouseData.data.global.y;
  314. TweenMax.to(displacementFilter.scale, 1, {
  315. x: '+=' + Math.sin(mouseX) * 100 + '',
  316. y: '+=' + Math.cos(mouseY) * 100 + ''
  317. });
  318. rotateSpite();
  319. };
  320. slidesContainer.pointerout = function (mouseData) {
  321. TweenMax.to(displacementFilter.scale, 1, { x: 0, y: 0 });
  322. cancelAnimationFrame(rafID);
  323. };
  324. }
  325. // CLICK
  326. if (options.interactionEvent === 'click' || options.interactionEvent === 'both') {
  327. slidesContainer.pointerup = function (mouseData) {
  328. if (options.dispatchPointerOver === true) {
  329. TweenMax.to(displacementFilter.scale, 1, {
  330. x: 0, y: 0, onComplete: function () {
  331. TweenMax.to(displacementFilter.scale, 1, { x: 20, y: 20 });
  332. }
  333. });
  334. } else {
  335. TweenMax.to(displacementFilter.scale, 1, { x: 0, y: 0 });
  336. cancelAnimationFrame(rafID);
  337. }
  338. };
  339. slidesContainer.pointerdown = function (mouseData) {
  340. mouseX = mouseData.data.global.x;
  341. mouseY = mouseData.data.global.y;
  342. TweenMax.to(displacementFilter.scale, 1, {
  343. x: '+=' + Math.sin(mouseX) * 1200 + '',
  344. y: '+=' + Math.cos(mouseY) * 200 + ''
  345. });
  346. };
  347. slidesContainer.pointerout = function (mouseData) {
  348. if (options.dispatchPointerOver === true) {
  349. TweenMax.to(displacementFilter.scale, 1, {
  350. x: 0, y: 0, onComplete: function () {
  351. TweenMax.to(displacementFilter.scale, 1, { x: 20, y: 20 });
  352. }
  353. });
  354. } else {
  355. TweenMax.to(displacementFilter.scale, 1, { x: 0, y: 0 });
  356. cancelAnimationFrame(rafID);
  357. }
  358. };
  359. }
  360. }
  361. /// ---------------------------
  362. // CENTER DISPLACEMENT
  363. /// ---------------------------
  364. if (options.displacementCenter === true) {
  365. displacementSprite.anchor.set(0.5);
  366. displacementSprite.x = renderer.view.width / 2;
  367. displacementSprite.y = renderer.view.height / 2;
  368. }
  369. /// ---------------------------
  370. // START
  371. /// ---------------------------
  372. this.init();
  373. /// ---------------------------
  374. // HELPER FUNCTIONS
  375. /// ---------------------------
  376. function scaleToWindow(canvas, backgroundColor) {
  377. var scaleX,
  378. scaleY,
  379. scale,
  380. center;
  381. //1. Scale the canvas to the correct size
  382. //Figure out the scale amount on each axis
  383. scaleX = window.innerWidth / canvas.offsetWidth;
  384. scaleY = window.innerHeight / canvas.offsetHeight;
  385. //Scale the canvas based on whichever value is less: `scaleX` or `scaleY`
  386. scale = Math.min(scaleX, scaleY);
  387. canvas.style.transformOrigin = '0 0';
  388. canvas.style.transform = 'scale(' + scale + ')';
  389. //2. Center the canvas.
  390. //Decide whether to center the canvas vertically or horizontally.
  391. //Wide canvases should be centered vertically, and
  392. //square or tall canvases should be centered horizontally
  393. if (canvas.offsetWidth > canvas.offsetHeight) {
  394. if (canvas.offsetWidth * scale < window.innerWidth) {
  395. center = 'horizontally';
  396. } else {
  397. center = 'vertically';
  398. }
  399. } else {
  400. if (canvas.offsetHeight * scale < window.innerHeight) {
  401. center = 'vertically';
  402. } else {
  403. center = 'horizontally';
  404. }
  405. }
  406. //Center horizontally (for square or tall canvases)
  407. var margin;
  408. if (center === 'horizontally') {
  409. margin = (window.innerWidth - canvas.offsetWidth * scale) / 2;
  410. canvas.style.marginTop = 0 + 'px';
  411. canvas.style.marginBottom = 0 + 'px';
  412. canvas.style.marginLeft = margin + 'px';
  413. canvas.style.marginRight = margin + 'px';
  414. }
  415. //Center vertically (for wide canvases)
  416. if (center === 'vertically') {
  417. margin = (window.innerHeight - canvas.offsetHeight * scale) / 2;
  418. canvas.style.marginTop = margin + 'px';
  419. canvas.style.marginBottom = margin + 'px';
  420. canvas.style.marginLeft = 0 + 'px';
  421. canvas.style.marginRight = 0 + 'px';
  422. }
  423. //3. Remove any padding from the canvas and body and set the canvas
  424. //display style to "block"
  425. canvas.style.paddingLeft = 0 + 'px';
  426. canvas.style.paddingRight = 0 + 'px';
  427. canvas.style.paddingTop = 0 + 'px';
  428. canvas.style.paddingBottom = 0 + 'px';
  429. canvas.style.display = 'block';
  430. //4. Set the color of the HTML body background
  431. document.body.style.backgroundColor = backgroundColor;
  432. //Fix some quirkiness in scaling for Safari
  433. var ua = navigator.userAgent.toLowerCase();
  434. if (ua.indexOf('safari') != -1) {
  435. if (ua.indexOf('chrome') > -1) {
  436. // Chrome
  437. } else {
  438. // Safari
  439. //canvas.style.maxHeight = "100%";
  440. //canvas.style.minHeight = "100%";
  441. }
  442. }
  443. //5. Return the `scale` value. This is important, because you'll nee this value
  444. //for correct hit testing between the pointer and sprites
  445. return scale;
  446. } // http://bit.ly/2y1Yk2k
  447. };
  448. })();