- エーオーシステム コーポレートサイト
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-15
* @date 2024-01-17 Rewrite the code using the class syntax.
*
<section class="switchPanel">
<div>
<div id="switchPanelStage"></div>
</div>
</section>
<style>
section.switchPanel {
background-color: #000;
> div {
max-width: 1920px;
margin: 0 auto;
overflow: hidden;
> #switchPanelStage {
user-select: none;
display: grid;
grid-template-rows: 1fr;
grid-template-columns: 1fr;
> img {
grid-row: 1/2;
grid-column: 1/2;
width: 100%;
user-select: none;
}
> div {
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('switchPanelStage')},
{prop: 'layerImg', value: document.createElement('img')},
{prop: 'layerNav', 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: 'imageDisplayTime', value: 8000}, //画像表示時間
{prop: 'fadeTime', value: 1000}, //フェードの時間
{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.#values = shuffle(this.#values); //シャッフルさせる場合
//window.addEventListener('focus',() => { this.#focusFlag = true;}); //out focusで停止させる場合の処理
//window.addEventListener('blur',() => { this.#focusFlag = false;}); //out focusで停止させる場合の処理
//
this.stage.appendChild(this.layerImg);
this.stage.appendChild(this.layerNav);
this.layerImg.setAttribute('draggable','false');
this.layerImg.src = this.#getImage(0);
this.layerImg.onload = () => {
this.#initNav();
this.#initSwipe();
this.#ballOn();
this.#imageZoom();
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;
}
#getIsLarge() {
return window.matchMedia('(width >= ' + this.#config.breakpoint + 'px)').matches;
}
#getImage(ptr) {
return this.#getIsLarge() ? this.#values[ptr].image1 : this.#values[ptr].image2;
}
#initNav() {
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.layerNav.appendChild(span);
});
const pauseImg = new Image();
pauseImg.src = this.markPause;
this.buttonPause.appendChild(pauseImg);
this.layerNav.appendChild(this.buttonPause);
const playImg = new Image();
playImg.src = this.markPlay;
this.buttonPlay.appendChild(playImg);
this.layerNav.appendChild(this.buttonPlay);
this.buttonPlay.style.display = 'none';
this.buttonPause.addEventListener('click',() => this.#setPause());
this.buttonPlay.addEventListener('click',() => this.#setPlay());
}
#initSwipe() {
this.layerImg.addEventListener('click', (e) => { e.preventDefault();});
this.layerImg.addEventListener('mousedown', (e) => { this.#swipeStart(e.clientX); });
this.layerImg.addEventListener('mouseup', (e) => { this.#swipeEnd(e.clientX); });
this.layerImg.addEventListener('touchstart', (e) => { this.#swipeStart(e.touches[0].clientX); });
this.layerImg.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';
}
#imageZoom() {
this.layerImg.animate(
[
{transform: 'scale(1)'},
{transform: 'scale(1.05)'},
],
{delay:0,duration:this.imageDisplayTime, easing:'linear', fill:'forwards'},
);
}
#slideForward() {
if (this.#isBusy) {
return;
}
this.#isBusy = true;
this.layerImg.animate(
[{opacity: 0}],
{delay:0, duration:this.fadeTime, easing:'linear', fill:'forwards'},
);
setTimeout(() => {
this.#ballOn();
this.layerImg.animate(
[{transform: 'scale(1)'}],
{delay:0,duration:1, easing:'linear', fill:'forwards'},
);
this.layerImg.src = this.#getImage(this.#valueIndex);
this.layerImg.onload = () => {
this.layerImg.animate(
[
{opacity: 0},
{opacity: 1},
],
{delay:0,duration:this.fadeTime, easing:'linear', fill:'forwards'},
);
this.#isBusy = false;
this.#imageZoom();
}
},this.fadeTime);
}
#autoSlide() {
this.#loopTimeoutId = setTimeout(() => {
if (this.#pausePlayFlag && this.#focusFlag) {
this.#slideAction();
} else {
this.#autoSlide();
}
}, this.imageDisplayTime - this.fadeTime);
}
#slideAction(num = this.#valueIndex + 1) {
clearTimeout(this.#loopTimeoutId);
this.#valueIndex = this.#withinRange(num);
this.#slideForward();
this.#autoSlide();
}
#ballOn() {
const spans = this.layerNav.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) アプリ