( function() { var app = window.app = window.app || {}; window.ccc = console.log; let Z_PATCH = -180; //-140; //let Z_INDEX_SCALE = 100000; //making it too big appar. crashes anim. let WRAPPER_WIDTH = 1020; let WRAPPER_HEIGHT = 800; let MASTER = { animDuration : 20, width : 1020, height : 800, distance : 1500, //800 //=perspective, px distanceToCarousel : 300, //20000; //300; //=perspective and distance at the same time insede of "Master layer space" perspectiveOrigin : [ 510, 400 ] }; let CAROUSELS = [ { facetsCount : 3, animationCycleDuration : 20, //sec position : { left : 0, top : 0, zz : 0 }, //no zz yet rotation : 'rotateY', //[ 0, 1, 0 ], spriteWidth : 450, spriteHeight : 300, rotateClockwise : false, //true; //false = right-to-left along x axis; rotation around y axis imageList : app.horizontalFiles } /*, { facetsCount : 10, animationCycleDuration : 180, //sec position : { left : 600, top : 0, zz : 0 }, rotation : 'rotateX', //[ 1, 0, 0 ], spriteWidth : 400, spriteHeight : 600, rotateClockwise : true, //true; //false = right-to-left along x axis; rotation around y axis imageList : app.verticalFiles } */ ]; //:inner config let SPRITE_TRANSPARENT_BACKGROUND = true; let DIGITS_FOR_CSS = 8; //.vital to set safely //let zInverter = 2000 + //2radius // MASTER.distanceToCarousel; //:spawning config let rad2deg = Math.PI / 180; let pX = MASTER.perspectiveOrigin[ 0 ]; let pY = MASTER.perspectiveOrigin[ 1 ]; ///parents let wrapperStyle =` #wrapper { position: relative; padding: 0px; margin: auto; left: 0; top: 0; background-color: transparent; width: ${WRAPPER_WIDTH}px; height: ${WRAPPER_HEIGHT}px; overflow: visible; color: white; perspective: ${MASTER.distance}px; perspective-origin: ${MASTER.perspectiveOrigin[0]}px ${MASTER.perspectiveOrigin[1]}px; } `; //preparing master rotation let spriteWidth2 = 0.5 * CAROUSELS[ 0 ].spriteWidth; let centerShiftX = 0; let centerShiftY = 0; let rotationRadius; //from center of facet, not from its edge; let turnStep = 360 / CAROUSELS[ 0 ].facetsCount; rotationRadius = spriteWidth2 / Math.tan( rad2deg * turnStep / 2 ); let masterStyle =` #master2, #master { position: absolute; padding: 0px; margin: 0px; top: 80px; border 1px solid #AAAAAA; background-color: transparent; width: ${MASTER.width}px; height: ${MASTER.height}px; overflow: visible; color: white; perspective: ${MASTER.distanceToCarousel}px; perspective-origin: ${pX}px ${pY}px; transform-style: preserve-3d; //transform-origin: ${-MASTER.width/2 + centerShiftX.toFixed(10)}px ${centerShiftY.toFixed(10)}px ${(-rotationRadius).toFixed(10)}px; transform-origin: 225px 0px -129.9px; } #master2 { background-color: green; top:0px; opacity:0.5;} `; let mstAnim = ` @keyframes move_master { from { transform: rotateY(0deg); } to { transform: rotateY(360deg); } } #master { -webkit-animation: ${MASTER.animDuration}s linear 0s infinite normal move_master; animation: ${MASTER.animDuration}s linear 0s infinite normal move_master; }`; // //\\ helpers //transform: ${rotateAxis}(${turn}deg); z-index: ${zIndex}; //transform: rotate3d( ${rotateAxis}, ${turn}deg ); z-index: ${zIndex}; function makeTurnPhase( rotateAxis, phase, turn ) { //, zIndex ) { //function makeTurnPhase( rotateAxis, phase, turn, zIndex, preShift ) { //misses: transform: ${preShift}rotate3d( ${rotateAxis}, ${turn}deg ); z-index: ${zIndex}; return ` ${phase}% { transform: ${rotateAxis}(${turn}deg); }`; }; // \\// helpers function makeCarousel ( startCssId, crs ) { let FACETS_COUNT = crs.facetsCount; let phaseStep = 100 / FACETS_COUNT; let turnStep = 360 / FACETS_COUNT; let rotationDir = crs.rotateClockwise ? 1 : -1; let facets2 = FACETS_COUNT / 2; let spriteWidth2 = 0.5 * crs.spriteWidth; let centerShiftX = 0; let centerShiftY = 0; let rotationRadius; //from center of facet, not from its edge; if( crs.rotation === 'rotateX' ) { //[ 0 ] ) { ////around axis X centerShiftY = 0.5 * crs.spriteHeight; rotationRadius = centerShiftY / Math.tan( rad2deg * turnStep / 2 ); } else { centerShiftX = 0.5 * crs.spriteWidth; rotationRadius = centerShiftX / Math.tan( rad2deg * turnStep / 2 ); } let rotation = crs.rotation; //crs.rotation[ 0 ] + ', ' + crs.rotation[ 1 ] + ', ' + crs.rotation[ 2 ]; //let preShift = ''; //crs.position.zz ? `translate3d( 0, 0, ${crs.position.zz} ); ` : ''; let anim = ''; let sprites = ''; let html = ''; let spriteStyle = ` .sprite-${startCssId} { position: absolute; background-color: transparent; background-size: cover; border-radius: 15px; color: white; height: ${crs.spriteHeight}px; width: ${crs.spriteWidth}px; margin: 0px; padding: 0px; left: ${crs.position.left}px; top: ${crs.position.top}px; /*. sprite rotates over this point */ transform-origin: ${centerShiftX.toFixed(10)}px ${centerShiftY.toFixed(10)}px ${(-rotationRadius).toFixed(10)}px; } `; ///prepare child sprites for( let iFacet = 0; iFacet < FACETS_COUNT; iFacet++ ) { let sId = `sprite-${startCssId}-${iFacet}` let an = ''; for( let iPhase = 0; iPhase <= FACETS_COUNT; iPhase++ ) { let absPhase = iPhase + iFacet; if( !startCssId ) absPhase = iFacet; let ePhase = absPhase % FACETS_COUNT; let floatPhase = ePhase / FACETS_COUNT /* let distance2observer = MASTER.distanceToCarousel - crs.position.zz + rotationRadius * ( 1 - Math.cos( floatPhase * 2 * Math.PI ) ); */ //let inverseDistance = zInverter - distance2observer; //if( startCssId === 0 ) { // inverseDistance += Z_PATCH; //} //let zIndex = ( Z_INDEX_SCALE * inverseDistance ).toFixed( 0 ); //if( startCssId || !iPhase ) { an += makeTurnPhase( rotation, ( iPhase * phaseStep ).toFixed( DIGITS_FOR_CSS ), ( rotationDir * absPhase * turnStep ).toFixed( DIGITS_FOR_CSS ) //zIndex //preShift ); //} } anim += ` @keyframes move_sprite_${startCssId}_${iFacet} {${an} }`; let color; if( SPRITE_TRANSPARENT_BACKGROUND ) { color = ''; } else { let colorGrain = FACETS_COUNT / 3; let cMas = 3 * iFacet / FACETS_COUNT; let colorGroup = Math.floor( cMas ); let subColor = cMas - colorGroup + 1/3; let subColorValue = [ [ 254, 0, 0 ], [ 0, 254, 0 ], [ 0, 0, 254 ] ]; let rr = subColorValue[ colorGroup ][0] * subColor; let gg = subColorValue[ colorGroup ][1] * subColor; let bb = subColorValue[ colorGroup ][2] * subColor; let forColor = 'rgb(' + rr.toFixed(0) + ', ' + gg.toFixed(0) + ', ' + bb.toFixed(0) + ')'; color = ` background-color: ${forColor};`; } ////sprites let wAn = `${crs.animationCycleDuration}s linear 0s infinite normal move_sprite_${startCssId}_${iFacet}`; let imgInfo = crs.imageList; sprites += ` #${sId} {${color} background-image: url("${imgInfo.path}/${imgInfo.list[ iFacet ]}"); -webkit-animation: ${wAn}; animation: ${wAn}; }`; html += `
`; } app.cssAnimation += mstAnim + spriteStyle + anim + sprites; app.html += html; } // //\\// doing the job app.cssAnimation = ''; app.html = ''; CAROUSELS.forEach( function( crs, ix ) { makeCarousel( ix, crs ); }); app.cssAnimation = wrapperStyle + masterStyle + app.cssAnimation; app.html = `