- エーオーシステム コーポレートサイト
https://www.aosystem.co.jp/ - エーオーシステム プロダクトサイト
https://ao-system.net/ - レンタルサーバー
- バーチャル展示会
- ウェブカタログサービス
- 3Dグラフィック
- Android アプリ
- iOS (iPhone,iPad) アプリ
- Flutter開発
- プログラミング記録QuickAnswer
- 無料画像素材
- スカイボックス 3D SKY BOX
このページのQRコード
/**
* 画像切り替え
*
* @author ao-system, Inc.
* @date 2024-01-14
* @date 2024-01-17 Rewrite the code using the class syntax.
*
<section class="peelPanel">
<div id="peelPanelStage">
<img id="peelPanelCurrent" draggable="false">
<div class="peelPanelShadow">
<div id="peelPanelContainer">
<div id="peelPanelPaperBack"></div>
<div class="image"><img id="peelPanelCurrentBack" draggable="false"></div>
</div>
</div>
<img id="peelPanelNext" draggable="false">
<img id="peelPanelCover" draggable="false">
</div>
</section>
<style>
section.peelPanel {
background-color: #000;
> div {
max-width: 1920px;
margin: 0 auto;
overflow: hidden;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
position: relative;
cursor: ew-resize;
> img#peelPanelCurrent {
grid-row: 1/2;
grid-column: 1/2;
width: 100%;
user-select: none;
}
> .peelPanelShadow {
grid-row: 1/2;
grid-column: 1/2;
height: 100%;
width: 100%;
overflow: hidden;
> #peelPanelContainer {
box-shadow: 0px 0px 50px rgba(0, 0, 0, 1);
position: absolute;
width: 0px;
height: 0px;
top: 0px;
right: 0px;
overflow: hidden;
> #peelPanelPaperBack {
transform: rotate(45deg);
transform-origin: 0% 0%;
position: absolute;
width: calc(0px * 1.414);
height: 0px;
background-color: #888;
z-index: 1;
box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.8);
background-image: linear-gradient(rgba(0,0,0,0.6) 0%, rgba(0,0,0,0.2) 10%, rgba(255,255,255,0.4) 50%);
}
> .image {
position: absolute;
left: 0;
bottom: 0;
z-index: 1;
transform: scaleX(-1) rotate(90deg);
mix-blend-mode: overlay;
> img#peelPanelCurrentBack {
user-select: none;
}
}
}
}
> img#peelPanelNext {
grid-row: 1/2;
grid-column: 1/2;
width: 100%;
clip-path: polygon(calc(100% - 0px) 0, 100% 0, 100% 0px);
user-select: none;
}
> img#peelPanelCover {
grid-row: 1/2;
grid-column: 1/2;
width: 100%;
user-select: none;
}
> .nav {
z-index: 1;
grid-row: 1/2;
grid-column: 1/2;
justify-self: flex-end;
align-self: end;
display: flex;
justify-content: center;
align-items: center;
column-gap: 5px;
padding: 0 20px 20px 0;
@media (width < 670px) {
column-gap: 3px;
padding: 0 3px 3px 0;
> span {
> img {
width: 16px;
}
}
}
> span {
cursor: pointer;
> img:nth-of-type(1) {
display: block;
}
> img:nth-of-type(2) {
display: none;
}
&.on {
> img:nth-of-type(1) {
display: none;
}
> img:nth-of-type(2) {
display: block;
}
}
}
}
}
}
</style>
*
*/
(() => {
'use strict';
class SwitchImage {
#constProperties = [
{prop: 'stage', value: document.getElementById('peelPanelStage')},
{prop: 'peelPanelContainer', value: document.getElementById('peelPanelContainer')},
{prop: 'peelPanelPaperBack', value: document.getElementById('peelPanelPaperBack')},
{prop: 'peelPanelCurrentBack', value: document.getElementById('peelPanelCurrentBack')},
{prop: 'peelPanelCurrent', value: document.getElementById('peelPanelCurrent')},
{prop: 'peelPanelNext', value: document.getElementById('peelPanelNext')},
{prop: 'peelPanelCover', value: document.getElementById('peelPanelCover')},
{prop: 'layerBall', value: document.createElement('div')},
{prop: 'markPause', value: './image/panel_pause.svg'},
{prop: 'markPlay', value: './image/panel_play.svg'},
{prop: 'markNavOn', value: './image/panel_ball_on.svg'},
{prop: 'markNavOff', value: './image/panel_ball_off.svg'},
{prop: 'buttonPause', value: document.createElement('span')},
{prop: 'buttonPlay', value: document.createElement('span')},
{prop: 'imageChangeInterval', value: 6000}, //画像と画像の切り替え間隔
{prop: 'peelTime', value: 1500}, //切り替わり時間
{prop: 'easeInSlow', value: 'cubic-bezier(1, 0, 1, 1)'}, //強いease-in
{prop: 'swipeShreshold', value: 50}, //スワイプ判定幅
];
#loopTimeoutId = null; //自動動作のタイマー
#isBusy = false; //動作中
#pausePlayFlag = true; //falseで停止
#focusFlag = true; //フォーカスが外れている時は動作させないため
#valueIndex = 0; //this.#valuesの添え字
#swipeStartX = 0; //スワイプ開始位置
#isSwiping = false; //スワイプ中
#config = {};
#values = [];
//
constructor(config, values) {
this.#config = config;
this.#values = values;
this.#constProperties.forEach((obj) => Object.defineProperty(this, obj.prop, {value:obj.value, writable:false}));
this.#init();
}
#init() {
//this.#switchImage = shuffle(this.#switchImage); //シャッフルさせる場合
//window.addEventListener('focus',() => { this.#focusFlag = true;}); //out focusで停止させる場合の処理
//window.addEventListener('blur',() => { this.#focusFlag = false;}); //out focusで停止させる場合の処理
//
this.stage.appendChild(this.layerBall);
this.peelPanelCurrent.src = this.#getImage(0);
this.peelPanelCurrentBack.src = this.#getImage(0);
this.peelPanelNext.src = this.#getImage(1);
this.peelPanelCover.animate(
[{opacity: 0}],
{delay:0,duration:10, easing:'linear',fill:'forwards'},
);
this.peelPanelCover.src = this.#getImage(1);
this.#preload();
this.#initBall();
this.#initSwipe();
this.#ballOn();
this.#autoSlide();
}
#shuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
#preload() {
for (let i = 2; i < this.#values.length; i++) {
setTimeout(() => {
const dummyImg = new Image();
dummyImg.src = this.#getImage(i);
},10);
}
}
#getIsLarge() {
return window.matchMedia('(width >= ' + this.#config.breakpoint + 'px)').matches;
}
#getImage(ptr) {
return this.#getIsLarge() ? this.#values[ptr].image1 : this.#values[ptr].image2;
}
#initBall() {
this.layerBall.classList.add('nav');
this.#values.map((x,index) => {
const span = document.createElement('span');
span.addEventListener('click',(e) => {
if (this.#isBusy) {
return;
}
this.#slideAction(index);
});
span.innerHTML = '<img src="' + this.markNavOff + '"><img src="' + this.markNavOn + '">';
this.layerBall.appendChild(span);
});
const pauseImg = new Image();
pauseImg.src = this.markPause;
this.buttonPause.appendChild(pauseImg);
this.layerBall.appendChild(this.buttonPause);
const playImg = new Image();
playImg.src = this.markPlay;
this.buttonPlay.appendChild(playImg);
this.layerBall.appendChild(this.buttonPlay);
this.buttonPlay.style.display = 'none';
this.buttonPause.addEventListener('click',() => this.#setPause());
this.buttonPlay.addEventListener('click',() => this.#setPlay());
}
#initSwipe() {
this.peelPanelCover.addEventListener('click', (e) => { e.preventDefault();});
this.peelPanelCover.addEventListener('mousedown', (e) => { this.#swipeStart(e.clientX); });
this.peelPanelCover.addEventListener('mouseup', (e) => { this.#swipeEnd(e.clientX); });
this.peelPanelCover.addEventListener('touchstart', (e) => { this.#swipeStart(e.touches[0].clientX); });
this.peelPanelCover.addEventListener('touchend', (e) => { this.#swipeEnd(e.changedTouches[0].clientX); });
}
#swipeStart(positionX) {
if (this.#isBusy) {
return;
}
this.#swipeStartX = positionX;
this.stage.style.cursor = 'grabbing';
this.#isSwiping = true;
}
#swipeEnd(positionX) {
if (this.#isSwiping == false) {
return;
}
if (this.#swipeStartX - positionX > this.swipeShreshold) {
this.#slideAction(this.#withinRange(this.#valueIndex + 1));
} else if (this.#swipeStartX - positionX < -this.swipeShreshold) {
this.#slideAction(this.#withinRange(this.#valueIndex - 1));
} else {
if (this.#values[this.#valueIndex].link) {
if (this.#values[this.#valueIndex].external) {
window.open(this.#values[this.#valueIndex].link, '_blank');
} else {
window.location.href = this.#values[this.#valueIndex].link;
}
return;
}
}
this.stage.style.cursor = '';
this.#isSwiping = false;
}
#setPause() {
this.#pausePlayFlag = false;
this.buttonPause.style.display = 'none';
this.buttonPlay.style.display = 'block';
}
#setPlay() {
this.#pausePlayFlag = true;
this.buttonPause.style.display = 'block';
this.buttonPlay.style.display = 'none';
}
#slideForward() {
if (this.#isBusy) {
return;
}
this.#isBusy = true;
this.peelPanelNext.src = this.#getImage(this.#valueIndex);
this.#ballOn();
const peelWidth = Math.max(this.peelPanelCurrent.width,this.peelPanelCurrent.height) * 3;
this.peelPanelContainer.animate(
[
{width: '0px', height: '0px'},
{width: peelWidth + 'px', height: peelWidth + 'px'},
],
{delay:0,duration:this.peelTime, easing:this.easeInSlow, fill:'forwards'},
);
this.peelPanelPaperBack.animate(
[
{width: '0px', height: '0px'},
{width: (peelWidth * 1.414) + 'px', height: peelWidth + 'px'},
],
{delay:0,duration:this.peelTime, easing:this.easeInSlow, fill:'forwards'},
);
this.peelPanelNext.animate(
[
{clipPath: 'polygon(100% 0px, 100% 0px, 100% 0px)'},
{clipPath: 'polygon(calc(100% - ' + peelWidth + 'px) 0, 100% 0, 100% ' + peelWidth + 'px)'},
],
{delay:0,duration:this.peelTime, easing:this.easeInSlow, fill:'forwards'},
);
if (this.#getIsLarge()) {
this.peelPanelCurrentBack.style.transform = 'translate(-610px,-610px)';
} else {
this.peelPanelCurrentBack.style.transform = 'translate(150px,150px)';
}
this.peelPanelCurrentBack.animate(
[
{clipPath: 'polygon(100% 0px, 100% 0px, 100% 0px)'},
{clipPath: 'polygon(calc(100% - ' + peelWidth + 'px) 0, 100% ' + peelWidth + 'px, 100% 0)'},
],
{delay:0,duration:this.peelTime, easing:this.easeInSlow, fill:'forwards'},
);
this.peelPanelCover.src = this.#getImage(this.#valueIndex);
this.peelPanelCover.animate(
[{opacity: 1}],
{delay:this.peelTime - 200,duration:200, easing:'linear',fill:'forwards', },
);
setTimeout(() => {
this.peelPanelCurrent.src = this.#getImage(this.#valueIndex);
this.peelPanelCurrentBack.src = this.#getImage(this.#valueIndex);
setTimeout(() => {
this.peelPanelCover.animate(
[{opacity: 0}],
{delay:0,duration:10, easing:'linear',fill:'forwards'},
);
setTimeout(() => {
this.peelPanelCover.src = this.#getImage(this.#withinRange(this.#valueIndex + 1));
this.#isBusy = false;
},100);
},100);
},this.peelTime + 100);
}
#autoSlide() {
this.#loopTimeoutId = setTimeout(() => {
if (this.#pausePlayFlag && this.#focusFlag) {
this.#slideAction();
} else {
this.#autoSlide();
}
}, this.imageChangeInterval - this.peelTime);
}
#slideAction(num = this.#valueIndex + 1) {
clearTimeout(this.#loopTimeoutId);
this.#valueIndex = this.#withinRange(num);
this.#slideForward();
this.#autoSlide();
}
#ballOn() {
const spans = this.layerBall.querySelectorAll('span');
spans.forEach((elm) => elm.classList.remove('on'));
spans[this.#valueIndex].classList.add('on');
}
#withinRange(nextNumber) {
const num = (nextNumber >= 0) ? nextNumber : this.#values.length - 1;
return num % this.#values.length;
}
}
//
new SwitchImage(
//config
{
'breakpoint': 700,
},
//values
[
{
'link': '',
'external': false,
'image1': './image/panel01.webp',
'image2': './image/panel01b.webp',
},
{
'link': '',
'external': false,
'image1': './image/panel02.webp',
'image2': './image/panel02b.webp',
},
{
'link': '',
'external': false,
'image1': './image/panel03.webp',
'image2': './image/panel03b.webp',
},
{
'link': '',
'external': false,
'image1': './image/panel04.webp',
'image2': './image/panel04b.webp',
},
{
'link': '',
'external': false,
'image1': './image/panel05.webp',
'image2': './image/panel05b.webp',
},
{
'link': '',
'external': false,
'image1': './image/panel06.webp',
'image2': './image/panel06b.webp',
},
]
);
})();
このページのQRコード
便利ウェブサイト
便利 Android アプリ
便利 iOS(iPhone,iPad) アプリ