1)
풍뎅이뎅이..의 휴재편이 나와있는데,
혹시나 스크롤 애니메이션화하면 어떨까..라는 생각에 만들어봤습니다만..
*참고*
22화 이후 휴재공지 - 풍뎅이뎅이 - 다음 만화속세상..
(이미지 직접 끌어다 써보고 있습니다 = =;..)
...
2)
<a href=http://cartoon.media.daum.net/webtoon/viewer/18189 style=color:red; target=_blank>http://cartoon.media.daum.net/webtoon/viewer/18189</a>
<div id=mon121003_1 ></div>
<div id=output121003_1 >
<div id=backpo121003_1 ><div id=back121003_1></div></div>
<div id=frontpo121003_1 ><div id=front121003_1 ></div></div>
<div id=scrollpo121003_1 >
</div>
</div>
<br/><br/>
<div id=originalZone></div>
<script>
// <'+'div id=scrollpo ><'+'div id=scrollDiv ><'+'div id=scrollBoard ><'+'/div><'+'/div><'+'/div>
// z-index: 999 !important;
// <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
(function(){
function ele(v) {
return document.getElementById(v);
}
String.prototype.replaceAll=function() {
var ar=arguments, arl=ar.length, i, ov=this;
for (i=0; i<arl; i+=2) {
ov=ov.replace(ar[i], ar[i+1]);
}
return ov;
}
// 이미지의 세로위치를 기준으로, 표시기준위치값 계싼
function getpoyA(poy, poyN, divedZone) {
var
ov=[]
, i, j, poyl=poy.length, tp, bp, ep;
j=0; tp=bp=0;
for (i=0; i<poyl; i++) {
if (i>=poyN[j]) {
tp=bp;
j++;
ep=divedZone.getElementsByTagName('img')[j];
// if (ep) bp-=ep.offsetTop;
if (ep) bp=-ep.offsetTop; // 기존에는 이미지 크기로 정했지만, offsetTop 으로 하는 이상, 이미지 크기를 처리할 필요가 없음.
}
ov[i]=tp+poy[i];
}
// alert(divedZone.getElementsByTagName('img')[0].offsetTop);
// alert(divedZone.offsetTop);
// alert(bp);
return ov;
}
/*
// image 들의 크기를 기준으로 스크롤값 추출. 이 역시 offsetTop 으로 하는 이상, 후처리할 필요 없음.
// 단, 이미지가 들어오기 전이므로, 선처리용 값으로 사용할 경우는 있었음.
function getscrollHeight(ilist) {
var ov, i, ilistl=ilist.length;
ov=0;
for (i=0; i<ilistl; i+=3) {
ov+=ilist[i+2];
}
return ov;
}
*/
function getimageAll(ilist) {
var ov, i, ilistl=ilist.length;
ov='';
for (i=0; i<ilistl; i+=3) {
ov+=('<img src={v} width={w} height={h} /><'+'br/>').replaceAll(/{v}/, ilist[i]
//, /{w}/, '400', /{h}/, 'inherit');
, /{w}/, ilist[i+1], /{h}/, ilist[i+2]);
}
return ov;
}
var
vWidth=760, vHeight=760, sWidth=23
, poy=[
// ilist 0*3
0, // 0
-662, -1334, -2012, -2665, -3328, -3967, -4615, -5281, -5929
// ilist 1*3
, 59 // 10
, -560, -1190, -1814, -2445, -3078, -3702, -4337, -4934, -5562, -6196
// ilist 2*3
, -66 // 21
, -727, -1403, -2098, -2780, -3827
]
, poyN=[0, 10, 21, 27] // 27==poy.length
, monn=poy.length-1 // front's initializing position
// , monn=0
, mon=ele('mon121003_1')
, ilist=[ // 'image_url', image_width, image_height
'http://i1.cartoon.daumcdn.net/svc/image/U03/cartoon/506B6FC60451960001', 760, 6584
, 'http://i1.cartoon.daumcdn.net/svc/image/U03/cartoon/506B6FC70450010001', 760, 6778
, 'http://i1.cartoon.daumcdn.net/svc/image/U03/cartoon/506B6FC804707D0001', 760, 4746
]
, poyA, poyAl
, back=ele('back121003_1'), backpo=ele('backpo121003_1'), front=ele('front121003_1'), frontpo=ele('frontpo121003_1')
, output=ele('output121003_1'), scrollDiv, scrollpo=ele('scrollpo121003_1')
// , scrollBoard=ele('scrollBoard')
, originalZone=ele('originalZone')
// , scrollHeight=getscrollHeight(ilist)
, scrollHeight
, imageAll=getimageAll(ilist)
, backpn=0, frontpn=1
;
/*
// patching for point's up and down..
function keydownFunction(e) {
if (!e) e=event;
var c=e.keyCode, y=poy[monn];
switch(c) {
case 38 :
poy[monn]--;
break;
case 40 :
poy[monn]++;
break;
default: return true;
}
mon.innerHTML=poy[monn];
locSet(frontpo, 0, poy[monn]);
}
document.body.onkeydown=keydownFunction;
*/
// 위치 설정. position:absolute 포함.
function locSet(e, l, t) {
e.style.left=l+'px';
e.style.top=t+'px';
e.style.position='absolute';
}
function locFixSet(e, l, t) {
e.style.left=l+'px';
e.style.top=t+'px';
// e.style.position='fixed !important';
}
// 스크롤위치 지정.
function scrollSet(e, t) {
e.scrollTop=-t;
}
// e(n)의 위치를 좌측위 구석으로 설정. position:absolute 포함.
function lefttopAll() {
var ar=arguments, arl=ar.length, i;
for (i=0; i<arl; i++)
locSet(ar[i], 0, 0);
}
function lefttopFixAll() {
var ar=arguments, arl=ar.length, i;
for (i=0; i<arl; i++)
locSet(ar[i], 0, 0);
// locFixSet(ar[i], 0, 0);
}
// relative 설장
function relativeSet(e) {
e.style.position='relative';
}
// 크기지정 : overflow:hidden; position:relative; 설정 포함
function zoneSet(e, w, h) {
e.style.width=w+'px';
e.style.height=h+'px';
e.style.overflow='hidden';
relativeSet(e)
}
// e(n)의 크기 지정 : overflow:hidden; position:relative; 설정 포함.
function zoneAll(w, h) {// w, h, e1, e2, ..
var ar=arguments, arl=ar.length, i;
for (i=2; i<arl; i++)
zoneSet(ar[i], w, h);
}
// 배경색 지정
function backSet(e, c) {
e.style.backgroundColor=c;
}
// scrollBar 의 컨트롤 설정
function setscrollLeader(scrollDiv, front, back) {
var scrollP, opav, lbackpn=-1, lfrontpn=-1, lvs;
function scrollLeader() {
// back.scrollTop=scrollP=scrollDiv.scrollTop;
scrollP=scrollDiv.scrollTop;
// alert(scrollP);
/*
// fixed 설정 안되어있을 때 내용
if (scrollP+vHeight<scrollDiv.scrollHeight) {
backpo.style.top=scrollP+'px';
frontpo.style.top=scrollP+'px';
}
else {
backpo.style.top=(scrollDiv.scrollHeight-vHeight)+'px';
frontpo.style.top=(scrollDiv.scrollHeight-vHeight)+'px';
}
*/
while (backpn>0) {
if (scrollP<-poyA[backpn]) backpn--; else break;
}
while (backpn<poyAl) {
if (scrollP>-poyA[backpn]) backpn++; else break;
}
if (backpn==poyAl) backpn--;
frontpn=backpn+1;
if (frontpn==poyAl) frontpn--;
if (backpn==frontpn) {
scrollSet(back, poyA[backpn]);
scrollSet(front, poyA[frontpn]);
front.style.filter='Alpha(opacity=0)';
front.style.opacity='0';
return;
}
opav=1-((scrollP+poyA[backpn])/(poyA[frontpn]-poyA[backpn])*6/1-3);
if (opav<0) opav=0; else if (opav>1) opav=1;
if (((backpn==lfrontpn)||(frontpn==lbackpn))&&(backpn!=frontpn)) {
lvs=backpn; backpn=frontpn; frontpn=lvs;
opav=1-opav;
}
if (opav==1) {
front.style.filter='Alpha(opacity={})'.replaceAll(/{}/, parseInt(opav*100));
front.style.opacity=opav;
}
else if (opav==0) {
front.style.filter='Alpha(opacity={})'.replaceAll(/{}/, parseInt(opav*100));
front.style.opacity=opav;
}
else if (lbackpn!=backpn) {
front.style.filter='Alpha(opacity={})'.replaceAll(/{}/, parseInt(1*100));
front.style.opacity=1;
}
else if (lfrontpn!=frontpn) {
front.style.filter='Alpha(opacity={})'.replaceAll(/{}/, parseInt(0*100));
front.style.opacity=0;
}
scrollSet(back, poyA[backpn]);
scrollSet(front, poyA[frontpn]);
front.style.filter='Alpha(opacity={})'.replaceAll(/{}/, parseInt(opav*100));
front.style.opacity=opav;
lbackpn=backpn;
lfrontpn=frontpn;
}
if (scrollDiv==document.body) window.onscroll=scrollLeader;
else if (scrollDiv==document.documentElement) window.onscroll=scrollLeader; // for IE
else
scrollDiv.onscroll=scrollLeader;
scrollDiv.onclick=function(){
// scrollP=scrollDiv.scrollTop;
//
// alert(scrollP+' / '+backpn+' '+frontpn+' / '+back.scrollTop+' '+front.scrollTop+' '+front.style.filter+' '+front.opacity);
if (opav<0.5) {
front.style.filter='Alpha(opacity={})'.replaceAll(/{}/, parseInt(0*100));
front.style.opacity=0;
}
else {
front.style.filter='Alpha(opacity={})'.replaceAll(/{}/, parseInt(1*100));
front.style.opacity=1;
}
};
}
// end of scrollLeader
if (navigator.userAgent.match(/mobile/i)) {
scrollpo.innerHTML='<textarea style="font-size:100px;" width=100% height=100% readonly=readonly id=scrollDiv121003_1 ></textarea>';
}
else {
scrollpo.innerHTML='<'+'div id=scrollDiv121003_1 ><'+'div id=scrollBoard ><'+'/div><'+'/div>';
}
scrollDiv=ele('scrollDiv121003_1');
zoneAll(vWidth+sWidth, vHeight, output, scrollDiv);
// zoneAll(vWidth+sWidth, vHeight, scrollDiv);
// zoneAll(vWidth+sWidth, vHeight);
zoneAll(vWidth, vHeight, back, front);
back.innerHTML=imageAll;
front.innerHTML=imageAll;
scrollHeight=back.scrollHeight;
// scrollDiv.style.overflow='auto';
scrollDiv.style.overflowY='scroll';
scrollDiv.style.filter='Alpha(opacity=0.01)';
// scrollDiv.style.filter='Alpha(opacity=0)';
scrollDiv.style.opacity='0.01';
// scrollDiv.style.opacity='0';
scrollDiv.style.backgroundColor='inherit';
// scrollDiv.style.backgroundColor='white';
function fillscrollDiv(scrollDiv, h) {
var ov='\n\n\n\n\n';
scrollDiv.innerHTML=ov;
while (scrollDiv.scrollHeight<h) {
ov+=ov; ov+=ov;
scrollDiv.innerHTML=ov;
}
scrollDiv.innerHTML=ov.substring(0, parseInt(
ov.length/scrollDiv.scrollHeight*h
)+2);
// alert(scrollDiv.scrollHeight+' '+h);
//alert(scrollDiv.outerHTML+' '+h);
}
if (navigator.userAgent.match(/mobile/i)) {
fillscrollDiv(scrollDiv, back.scrollHeight);
}
else {
// scrollBoard.width=vWidth;
// scrollBoard.height=scrollHeight;
scrollBoard.style.backgroundColor='white';
zoneSet(scrollBoard, vWidth, scrollHeight);
scrollBoard.style.filter='Alpha(opacity=0)';
scrollBoard.style.opacity='0';
// scrollBoard.style.visibility='hidden'; // 요건 실패.. IE8 <!DOCTYPE> 에서 작동 안함..
}
// lefttopAll(backpo, frontpo, scrollpo);
lefttopAll(scrollpo);
lefttopFixAll(backpo, frontpo);
front.style.filter='Alpha(opacity=50)';
front.style.opacity='0.5';
poyA=getpoyA(poy, poyN, back); // back 과 front 에 표시되는 이미지들의 사이 간격이 같다는 가정을 하고..
poyAl=poyA.length;
// alert(poyA);
// with ending message test..
// scrollSet(front, poyA[monn]);
// init scroll's prevalue
scrollSet(back, poyA[backpn]);
scrollSet(front, poyA[frontpn]);
setscrollLeader(scrollDiv, front, back); // 스크롤 컨트롤을 설정함
// if (document.all) setscrollLeader(document.documentElement, front, back); // IE
// else setscrollLeader(document.body, front, back); // 스크롤 컨트롤을 설정함
// under screen, sampled images..
// relativeSet(originalZone);
// originalZone.innerHTML=imageAll;
// originalZone.innerHTML=poyA+' /*a,b*/'.replaceAll(/a/, poyA[backpn], /b/, poyA[frontpn]);
})();
</script>
...
3)
-- 새 창에 샘플 보여주기.. --
...
4)
설명을 하자면..
**
// <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
사실, 모바일용을 염두에 두고 만든 내용이었거든요.
그런데, 스케일 조정을 못하면 이미지가 모두 나오지 않는 문제를 해결하지 못해서요..
**
function getpoyA(poy, poyN, divedZone) { .. }
이미지의 세로 위치를 array 로 반환하는 함수입니다.
이미지 하나하나를 쓰는 게 아니라,
이미지를 나열해놓은 div 를 쓰는 거라서요..
그래서, 미세(?)하게 위치가 다를 이미지의 스크롤 위치를 받아놓을 필요가 있는거죠.
**
function getscrollHeight(ilist) { .. }
이미지 element 를 추적할 수 없다고 생각했을 때 사용한 함수입니다.
.. 위에서 위치를 받아, 정확도(?)를 높인 이상, 딱히 쓸 일이 없어서 주석처리 했습니다.
**
function getimageAll(ilist) { .. }
div 내에 넣을 이미지 list 를 준비하는 함수입니다.
.. 너무 세분화 시킨걸까요 -.-?
**
vWidth=760, vHeight=760, sWidth=23
뷰 가로세로폭과, 스크롤 폭입니다.
.. 자동화 시킬 수 있겠지만, .. 일단 기본 값이 필요할 것 같아서요.. (자동화 못시켰습니다 = =;..)
**
, poy=[ .. ]
, poyN=[0, 10, 21, 27] // 27==poy.length
이미지들의 세로표시될 지점과 (가로값은 따로 안뽑았어요..)
각 이미지들의 세로 표시지점을 저장한 위치입니다.
각각 만들지 않았는데요, =.=.. 좀 귀찮아서랄지..
(생각해보니, 각각 뽑는게 코드 보기에 이로울 것 같네요..)
**
, ilist=[ // 'image_url', image_width, image_height
.. ]
쓰일 이미지입니다.
가능하다면 직접 이미지 등록해서 쓰고 싶긴 한데, ..
.. 다음웹툰쪽에 일단 이미지 쓰고 있다고 얘기는 올려봐야겠군요.
**
function keydownFunction(e) { .. }
이벤트를 모니터링 하려고 만든 내용입니다.
스크롤 끝부분에서 어떤 이벤트가 있는지 확인해보려고 했습니다만,
= =;.. 잘 안됐서요..
**
function locSet(e, l, t) { .. }
function locFixSet(e, l, t) {..}
element 의 위치를 조정한다는 내용입니다.
function scrollSet(e, t) { .. }
div 의 스크롤값을 조정한다는 내용입니다.
function lefttopAll() { .. }
function lefttopFixAll() { .. }
리스트들에 locSet(0,0) 또는 locFixSet(0,0) 을 적용한다는 내용입니다.
function backSet(e, c) { .. }
function relativeSet(e) { .. }
일일이 style[]=.. 형식으로 값 넣기가 귀찮아서요 = =;..
function zoneSet(e, w, h) { .. }
크기 지정하고, 위치기준을 자신으로 맞춘다는 내용입니다.
function zoneAll(w, h) { .. }
w, h 이후에 나오는 리스트들에 zoneSet 을 지정한다는 내용입니다.
**
function setscrollLeader(scrollDiv, front, back) { .. }
scroll 이벤트가 지정될 element 를 정한다는 내용입니다.
**
function scrollLeader() { .. }
scroll 이벤트가 동작될 내용입니다.
**
while (backpn>0) {
if (scrollP<-poyA[backpn]) backpn--; else break;
}
while (backpn<poyAl) {
if (scrollP>-poyA[backpn]) backpn++; else break;
}
스크롤위치와 이미지 표시위치값을 찾는다는 내용입니다.
2진트리화하면 속도는 빠르겠습니다만,
= =;.. 이거 만들 땐 방법이 생각나지 않아서요..
**
if (backpn==frontpn) {
scrollSet(back, poyA[backpn]);
scrollSet(front, poyA[frontpn]);
front.style.filter='Alpha(opacity=0)';
front.style.opacity='0';
return;
}
요 부분은 조금(?) 실수했군요.
이미지의 앞쪽 값과 뒤쪽 값이 같을 때, 앞쪽이 투명하도록 지정한다는 내용인데요,
초기에는 코드 만들 땐
앞쪽 이미지가 먼저 갈 내용을 기준으로 하고, 뒤쪽 이미지가 지나갈 이미지를 기준으로 서술했는데,
.. 그게 깜박임 현상이 있어서
나중에 코드 수정할 땐
연속성을 염두에 두고 만들었죠. .. 수정을 해야할 내용 같습니다.
(물론, 연속성쪽 문제도 해결해야겠죠..)
**
opav=1-((scrollP+poyA[backpn])/(poyA[frontpn]-poyA[backpn])*6/1-3);
if (opav<0) opav=0; else if (opav>1) opav=1;
스크롤을 하다보면 이미지와 이미지 사이에
살짝 흐림처리한 부분이 있을겁니다.
setTimeout 넣어서 좋은쪽(?) 이미지를 보여주도록 하는 것도 좋겠습니다만,
.. 일단 그냥 냅뒀습니다.
**
if (((backpn==lfrontpn)||(frontpn==lbackpn))&&(backpn!=frontpn)) { .. }
요부분이 연속성 처리과정입니다.
이전(?)에 표시한 내용과 비교해서 준비한 위치가 반대쪽과 같다면
준비한 값들 자리바꿔 표시한다는 내용이죠.
**
else if (lbackpn!=backpn) { .. }
else if (lfrontpn!=frontpn) { .. }
진짜(?) 표시될 위치가 이전과 다를 때,
우선, 표시될 투명도를 조정한다는 내용입니다.
이 방법론보다 더 진지(?)해야 합니다만,
= =;.. 딱히 생각나는 방법이 없어서요..
**
if (scrollDiv==document.body) window.onscroll=scrollLeader;
else if (scrollDiv==document.documentElement) window.onscroll=scrollLeader; // for IE
else
scrollDiv.onscroll=scrollLeader;
scrollDiv 에 적용될 내용에 관련해 서술한 내용입니다.
가능하다면 document.body 나 document.documentElement 에 적용하고 싶었습니다만,
(실제 onscroll 이벤트를 받는 element 입니다..)
모바일에서는 그게 사치(?)라서요.. = =;..
**
scrollDiv.onclick=function(){ .. }
스크롤되던 내용을 클릭하면 어떤 것을 보여줄까..에 대한 내용입니다.
훨씬(?) 잘 보이는 쪽을 보여주는게 정답이더라구요.
**
if (navigator.userAgent.match(/mobile/i)) {
scrollpo.innerHTML='<textarea style="font-size:100px;" width=100% height=100% readonly=readonly id=scrollDiv ></textarea>';
}
else {
scrollpo.innerHTML='<'+'div id=scrollDiv ><'+'div id=scrollBoard ><'+'/div><'+'/div>';
}
모바일용과 일반 브라우져용을 구별해놨습니다.
브라우져용으로는 textarea 를, 일반 브라우져용으로는 div 를 쓰기로 한거죠.
처음에는 div 를 써봤습니다만,
모바일에서 스크롤이 표시 안되는 문제가 있어 찾다찾다 textarea 를 선택했죠.
그러다가, pc 용에서 클릭 한번이 더 소모된다는 것을 알고(?)
일반 브라우져용 기준으로만 다시 div 로 복귀시킨 내용입니다.
**
function fillscrollDiv(scrollDiv, h) { .. }
if (navigator.userAgent.match(/mobile/i)) {
fillscrollDiv(scrollDiv, back.scrollHeight);
}
else { .. }
scrollDiv 의 스크롤크기를 지정한다는 내용입니다.
fillscrollDiv 내용을 보시면 \n 이 여러개 있는데요,
textarea 의 scrollHeight 를 최대한 맞추려고 loop 돌리게 되어있죠..
= =;.. 이 부분때문에 PC 가 멈출 수도 있을겁니다.. (가능성의 부분에서요..)
loop 횟수를 제한해야하는 것 아닐까..라는 생각도 드네요.
...
5)
대충 이런 내용으로 작성한거죠.
가끔씩 animation by script 관련 기술을 구사해보면서
페이징은 단순 flip 만 시도했습니다만,
이번에는 참 간만에(?) smooth flip 까지 적용해봤군요.
(이전에 가입한 클럽에서 유사한 기술을 구사해본 적이 있긴 했죠..)
가장 힘들었던 부분이 모바일이었습니다.
scroll 이벤트를 어떻게든 받아쓴다고, 고생 좀 했죠.
.. 가능하다면 minimul-scale:1.0, maximu-scale:1.0 환경에서도
쓸 수 있도록 만들고 싶다는 욕심도 드는군요..
*참고*
원본 이미지 쿼리티..를 남겨두고 싶어서
이미지 크기 조정 하지 않았습니다.
*참고2*
풍뎅이뎅이 연재관라하는 쪽에서 이미지 못쓴다고 한다면
.. 딱히 쓸수 이미지는 없고.. 그냥 이미지 없이 넣어두는 게 맞겠네요.
.. 숫자라도 집어넣을까..라는 생각도 해보구요.
*참고3*
이쪽에 올리기 전에 올렸던 내용입니다.
http://www.cyworld.com/kimkiewoong/7013006
ㅜ.ㅜ.. 모바일에서는 안나오는군요.. (무슨 문제인지는 파악을 못하고 있구요..)
댓글쪽에 첨부파일 주소 있긴 합니다.
풍뎅이뎅이..의 휴재편이 나와있는데,
혹시나 스크롤 애니메이션화하면 어떨까..라는 생각에 만들어봤습니다만..
*참고*
22화 이후 휴재공지 - 풍뎅이뎅이 - 다음 만화속세상..
(이미지 직접 끌어다 써보고 있습니다 = =;..)
...
2)
<a href=http://cartoon.media.daum.net/webtoon/viewer/18189 style=color:red; target=_blank>http://cartoon.media.daum.net/webtoon/viewer/18189</a>
<div id=mon121003_1 ></div>
<div id=output121003_1 >
<div id=backpo121003_1 ><div id=back121003_1></div></div>
<div id=frontpo121003_1 ><div id=front121003_1 ></div></div>
<div id=scrollpo121003_1 >
</div>
</div>
<br/><br/>
<div id=originalZone></div>
<script>
// <'+'div id=scrollpo ><'+'div id=scrollDiv ><'+'div id=scrollBoard ><'+'/div><'+'/div><'+'/div>
// z-index: 999 !important;
// <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
(function(){
function ele(v) {
return document.getElementById(v);
}
String.prototype.replaceAll=function() {
var ar=arguments, arl=ar.length, i, ov=this;
for (i=0; i<arl; i+=2) {
ov=ov.replace(ar[i], ar[i+1]);
}
return ov;
}
// 이미지의 세로위치를 기준으로, 표시기준위치값 계싼
function getpoyA(poy, poyN, divedZone) {
var
ov=[]
, i, j, poyl=poy.length, tp, bp, ep;
j=0; tp=bp=0;
for (i=0; i<poyl; i++) {
if (i>=poyN[j]) {
tp=bp;
j++;
ep=divedZone.getElementsByTagName('img')[j];
// if (ep) bp-=ep.offsetTop;
if (ep) bp=-ep.offsetTop; // 기존에는 이미지 크기로 정했지만, offsetTop 으로 하는 이상, 이미지 크기를 처리할 필요가 없음.
}
ov[i]=tp+poy[i];
}
// alert(divedZone.getElementsByTagName('img')[0].offsetTop);
// alert(divedZone.offsetTop);
// alert(bp);
return ov;
}
/*
// image 들의 크기를 기준으로 스크롤값 추출. 이 역시 offsetTop 으로 하는 이상, 후처리할 필요 없음.
// 단, 이미지가 들어오기 전이므로, 선처리용 값으로 사용할 경우는 있었음.
function getscrollHeight(ilist) {
var ov, i, ilistl=ilist.length;
ov=0;
for (i=0; i<ilistl; i+=3) {
ov+=ilist[i+2];
}
return ov;
}
*/
function getimageAll(ilist) {
var ov, i, ilistl=ilist.length;
ov='';
for (i=0; i<ilistl; i+=3) {
ov+=('<img src={v} width={w} height={h} /><'+'br/>').replaceAll(/{v}/, ilist[i]
//, /{w}/, '400', /{h}/, 'inherit');
, /{w}/, ilist[i+1], /{h}/, ilist[i+2]);
}
return ov;
}
var
vWidth=760, vHeight=760, sWidth=23
, poy=[
// ilist 0*3
0, // 0
-662, -1334, -2012, -2665, -3328, -3967, -4615, -5281, -5929
// ilist 1*3
, 59 // 10
, -560, -1190, -1814, -2445, -3078, -3702, -4337, -4934, -5562, -6196
// ilist 2*3
, -66 // 21
, -727, -1403, -2098, -2780, -3827
]
, poyN=[0, 10, 21, 27] // 27==poy.length
, monn=poy.length-1 // front's initializing position
// , monn=0
, mon=ele('mon121003_1')
, ilist=[ // 'image_url', image_width, image_height
'http://i1.cartoon.daumcdn.net/svc/image/U03/cartoon/506B6FC60451960001', 760, 6584
, 'http://i1.cartoon.daumcdn.net/svc/image/U03/cartoon/506B6FC70450010001', 760, 6778
, 'http://i1.cartoon.daumcdn.net/svc/image/U03/cartoon/506B6FC804707D0001', 760, 4746
]
, poyA, poyAl
, back=ele('back121003_1'), backpo=ele('backpo121003_1'), front=ele('front121003_1'), frontpo=ele('frontpo121003_1')
, output=ele('output121003_1'), scrollDiv, scrollpo=ele('scrollpo121003_1')
// , scrollBoard=ele('scrollBoard')
, originalZone=ele('originalZone')
// , scrollHeight=getscrollHeight(ilist)
, scrollHeight
, imageAll=getimageAll(ilist)
, backpn=0, frontpn=1
;
/*
// patching for point's up and down..
function keydownFunction(e) {
if (!e) e=event;
var c=e.keyCode, y=poy[monn];
switch(c) {
case 38 :
poy[monn]--;
break;
case 40 :
poy[monn]++;
break;
default: return true;
}
mon.innerHTML=poy[monn];
locSet(frontpo, 0, poy[monn]);
}
document.body.onkeydown=keydownFunction;
*/
// 위치 설정. position:absolute 포함.
function locSet(e, l, t) {
e.style.left=l+'px';
e.style.top=t+'px';
e.style.position='absolute';
}
function locFixSet(e, l, t) {
e.style.left=l+'px';
e.style.top=t+'px';
// e.style.position='fixed !important';
}
// 스크롤위치 지정.
function scrollSet(e, t) {
e.scrollTop=-t;
}
// e(n)의 위치를 좌측위 구석으로 설정. position:absolute 포함.
function lefttopAll() {
var ar=arguments, arl=ar.length, i;
for (i=0; i<arl; i++)
locSet(ar[i], 0, 0);
}
function lefttopFixAll() {
var ar=arguments, arl=ar.length, i;
for (i=0; i<arl; i++)
locSet(ar[i], 0, 0);
// locFixSet(ar[i], 0, 0);
}
// relative 설장
function relativeSet(e) {
e.style.position='relative';
}
// 크기지정 : overflow:hidden; position:relative; 설정 포함
function zoneSet(e, w, h) {
e.style.width=w+'px';
e.style.height=h+'px';
e.style.overflow='hidden';
relativeSet(e)
}
// e(n)의 크기 지정 : overflow:hidden; position:relative; 설정 포함.
function zoneAll(w, h) {// w, h, e1, e2, ..
var ar=arguments, arl=ar.length, i;
for (i=2; i<arl; i++)
zoneSet(ar[i], w, h);
}
// 배경색 지정
function backSet(e, c) {
e.style.backgroundColor=c;
}
// scrollBar 의 컨트롤 설정
function setscrollLeader(scrollDiv, front, back) {
var scrollP, opav, lbackpn=-1, lfrontpn=-1, lvs;
function scrollLeader() {
// back.scrollTop=scrollP=scrollDiv.scrollTop;
scrollP=scrollDiv.scrollTop;
// alert(scrollP);
/*
// fixed 설정 안되어있을 때 내용
if (scrollP+vHeight<scrollDiv.scrollHeight) {
backpo.style.top=scrollP+'px';
frontpo.style.top=scrollP+'px';
}
else {
backpo.style.top=(scrollDiv.scrollHeight-vHeight)+'px';
frontpo.style.top=(scrollDiv.scrollHeight-vHeight)+'px';
}
*/
while (backpn>0) {
if (scrollP<-poyA[backpn]) backpn--; else break;
}
while (backpn<poyAl) {
if (scrollP>-poyA[backpn]) backpn++; else break;
}
if (backpn==poyAl) backpn--;
frontpn=backpn+1;
if (frontpn==poyAl) frontpn--;
if (backpn==frontpn) {
scrollSet(back, poyA[backpn]);
scrollSet(front, poyA[frontpn]);
front.style.filter='Alpha(opacity=0)';
front.style.opacity='0';
return;
}
opav=1-((scrollP+poyA[backpn])/(poyA[frontpn]-poyA[backpn])*6/1-3);
if (opav<0) opav=0; else if (opav>1) opav=1;
if (((backpn==lfrontpn)||(frontpn==lbackpn))&&(backpn!=frontpn)) {
lvs=backpn; backpn=frontpn; frontpn=lvs;
opav=1-opav;
}
if (opav==1) {
front.style.filter='Alpha(opacity={})'.replaceAll(/{}/, parseInt(opav*100));
front.style.opacity=opav;
}
else if (opav==0) {
front.style.filter='Alpha(opacity={})'.replaceAll(/{}/, parseInt(opav*100));
front.style.opacity=opav;
}
else if (lbackpn!=backpn) {
front.style.filter='Alpha(opacity={})'.replaceAll(/{}/, parseInt(1*100));
front.style.opacity=1;
}
else if (lfrontpn!=frontpn) {
front.style.filter='Alpha(opacity={})'.replaceAll(/{}/, parseInt(0*100));
front.style.opacity=0;
}
scrollSet(back, poyA[backpn]);
scrollSet(front, poyA[frontpn]);
front.style.filter='Alpha(opacity={})'.replaceAll(/{}/, parseInt(opav*100));
front.style.opacity=opav;
lbackpn=backpn;
lfrontpn=frontpn;
}
if (scrollDiv==document.body) window.onscroll=scrollLeader;
else if (scrollDiv==document.documentElement) window.onscroll=scrollLeader; // for IE
else
scrollDiv.onscroll=scrollLeader;
scrollDiv.onclick=function(){
// scrollP=scrollDiv.scrollTop;
//
// alert(scrollP+' / '+backpn+' '+frontpn+' / '+back.scrollTop+' '+front.scrollTop+' '+front.style.filter+' '+front.opacity);
if (opav<0.5) {
front.style.filter='Alpha(opacity={})'.replaceAll(/{}/, parseInt(0*100));
front.style.opacity=0;
}
else {
front.style.filter='Alpha(opacity={})'.replaceAll(/{}/, parseInt(1*100));
front.style.opacity=1;
}
};
}
// end of scrollLeader
if (navigator.userAgent.match(/mobile/i)) {
scrollpo.innerHTML='<textarea style="font-size:100px;" width=100% height=100% readonly=readonly id=scrollDiv121003_1 ></textarea>';
}
else {
scrollpo.innerHTML='<'+'div id=scrollDiv121003_1 ><'+'div id=scrollBoard ><'+'/div><'+'/div>';
}
scrollDiv=ele('scrollDiv121003_1');
zoneAll(vWidth+sWidth, vHeight, output, scrollDiv);
// zoneAll(vWidth+sWidth, vHeight, scrollDiv);
// zoneAll(vWidth+sWidth, vHeight);
zoneAll(vWidth, vHeight, back, front);
back.innerHTML=imageAll;
front.innerHTML=imageAll;
scrollHeight=back.scrollHeight;
// scrollDiv.style.overflow='auto';
scrollDiv.style.overflowY='scroll';
scrollDiv.style.filter='Alpha(opacity=0.01)';
// scrollDiv.style.filter='Alpha(opacity=0)';
scrollDiv.style.opacity='0.01';
// scrollDiv.style.opacity='0';
scrollDiv.style.backgroundColor='inherit';
// scrollDiv.style.backgroundColor='white';
function fillscrollDiv(scrollDiv, h) {
var ov='\n\n\n\n\n';
scrollDiv.innerHTML=ov;
while (scrollDiv.scrollHeight<h) {
ov+=ov; ov+=ov;
scrollDiv.innerHTML=ov;
}
scrollDiv.innerHTML=ov.substring(0, parseInt(
ov.length/scrollDiv.scrollHeight*h
)+2);
// alert(scrollDiv.scrollHeight+' '+h);
//alert(scrollDiv.outerHTML+' '+h);
}
if (navigator.userAgent.match(/mobile/i)) {
fillscrollDiv(scrollDiv, back.scrollHeight);
}
else {
// scrollBoard.width=vWidth;
// scrollBoard.height=scrollHeight;
scrollBoard.style.backgroundColor='white';
zoneSet(scrollBoard, vWidth, scrollHeight);
scrollBoard.style.filter='Alpha(opacity=0)';
scrollBoard.style.opacity='0';
// scrollBoard.style.visibility='hidden'; // 요건 실패.. IE8 <!DOCTYPE> 에서 작동 안함..
}
// lefttopAll(backpo, frontpo, scrollpo);
lefttopAll(scrollpo);
lefttopFixAll(backpo, frontpo);
front.style.filter='Alpha(opacity=50)';
front.style.opacity='0.5';
poyA=getpoyA(poy, poyN, back); // back 과 front 에 표시되는 이미지들의 사이 간격이 같다는 가정을 하고..
poyAl=poyA.length;
// alert(poyA);
// with ending message test..
// scrollSet(front, poyA[monn]);
// init scroll's prevalue
scrollSet(back, poyA[backpn]);
scrollSet(front, poyA[frontpn]);
setscrollLeader(scrollDiv, front, back); // 스크롤 컨트롤을 설정함
// if (document.all) setscrollLeader(document.documentElement, front, back); // IE
// else setscrollLeader(document.body, front, back); // 스크롤 컨트롤을 설정함
// under screen, sampled images..
// relativeSet(originalZone);
// originalZone.innerHTML=imageAll;
// originalZone.innerHTML=poyA+' /*a,b*/'.replaceAll(/a/, poyA[backpn], /b/, poyA[frontpn]);
})();
</script>
...
3)
-- 새 창에 샘플 보여주기.. --
...
4)
설명을 하자면..
**
// <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
사실, 모바일용을 염두에 두고 만든 내용이었거든요.
그런데, 스케일 조정을 못하면 이미지가 모두 나오지 않는 문제를 해결하지 못해서요..
**
function getpoyA(poy, poyN, divedZone) { .. }
이미지의 세로 위치를 array 로 반환하는 함수입니다.
이미지 하나하나를 쓰는 게 아니라,
이미지를 나열해놓은 div 를 쓰는 거라서요..
그래서, 미세(?)하게 위치가 다를 이미지의 스크롤 위치를 받아놓을 필요가 있는거죠.
**
function getscrollHeight(ilist) { .. }
이미지 element 를 추적할 수 없다고 생각했을 때 사용한 함수입니다.
.. 위에서 위치를 받아, 정확도(?)를 높인 이상, 딱히 쓸 일이 없어서 주석처리 했습니다.
**
function getimageAll(ilist) { .. }
div 내에 넣을 이미지 list 를 준비하는 함수입니다.
.. 너무 세분화 시킨걸까요 -.-?
**
vWidth=760, vHeight=760, sWidth=23
뷰 가로세로폭과, 스크롤 폭입니다.
.. 자동화 시킬 수 있겠지만, .. 일단 기본 값이 필요할 것 같아서요.. (자동화 못시켰습니다 = =;..)
**
, poy=[ .. ]
, poyN=[0, 10, 21, 27] // 27==poy.length
이미지들의 세로표시될 지점과 (가로값은 따로 안뽑았어요..)
각 이미지들의 세로 표시지점을 저장한 위치입니다.
각각 만들지 않았는데요, =.=.. 좀 귀찮아서랄지..
(생각해보니, 각각 뽑는게 코드 보기에 이로울 것 같네요..)
**
, ilist=[ // 'image_url', image_width, image_height
.. ]
쓰일 이미지입니다.
가능하다면 직접 이미지 등록해서 쓰고 싶긴 한데, ..
.. 다음웹툰쪽에 일단 이미지 쓰고 있다고 얘기는 올려봐야겠군요.
**
function keydownFunction(e) { .. }
이벤트를 모니터링 하려고 만든 내용입니다.
스크롤 끝부분에서 어떤 이벤트가 있는지 확인해보려고 했습니다만,
= =;.. 잘 안됐서요..
**
function locSet(e, l, t) { .. }
function locFixSet(e, l, t) {..}
element 의 위치를 조정한다는 내용입니다.
function scrollSet(e, t) { .. }
div 의 스크롤값을 조정한다는 내용입니다.
function lefttopAll() { .. }
function lefttopFixAll() { .. }
리스트들에 locSet(0,0) 또는 locFixSet(0,0) 을 적용한다는 내용입니다.
function backSet(e, c) { .. }
function relativeSet(e) { .. }
일일이 style[]=.. 형식으로 값 넣기가 귀찮아서요 = =;..
function zoneSet(e, w, h) { .. }
크기 지정하고, 위치기준을 자신으로 맞춘다는 내용입니다.
function zoneAll(w, h) { .. }
w, h 이후에 나오는 리스트들에 zoneSet 을 지정한다는 내용입니다.
**
function setscrollLeader(scrollDiv, front, back) { .. }
scroll 이벤트가 지정될 element 를 정한다는 내용입니다.
**
function scrollLeader() { .. }
scroll 이벤트가 동작될 내용입니다.
**
while (backpn>0) {
if (scrollP<-poyA[backpn]) backpn--; else break;
}
while (backpn<poyAl) {
if (scrollP>-poyA[backpn]) backpn++; else break;
}
스크롤위치와 이미지 표시위치값을 찾는다는 내용입니다.
2진트리화하면 속도는 빠르겠습니다만,
= =;.. 이거 만들 땐 방법이 생각나지 않아서요..
**
if (backpn==frontpn) {
scrollSet(back, poyA[backpn]);
scrollSet(front, poyA[frontpn]);
front.style.filter='Alpha(opacity=0)';
front.style.opacity='0';
return;
}
요 부분은 조금(?) 실수했군요.
이미지의 앞쪽 값과 뒤쪽 값이 같을 때, 앞쪽이 투명하도록 지정한다는 내용인데요,
초기에는 코드 만들 땐
앞쪽 이미지가 먼저 갈 내용을 기준으로 하고, 뒤쪽 이미지가 지나갈 이미지를 기준으로 서술했는데,
.. 그게 깜박임 현상이 있어서
나중에 코드 수정할 땐
연속성을 염두에 두고 만들었죠. .. 수정을 해야할 내용 같습니다.
(물론, 연속성쪽 문제도 해결해야겠죠..)
**
opav=1-((scrollP+poyA[backpn])/(poyA[frontpn]-poyA[backpn])*6/1-3);
if (opav<0) opav=0; else if (opav>1) opav=1;
스크롤을 하다보면 이미지와 이미지 사이에
살짝 흐림처리한 부분이 있을겁니다.
setTimeout 넣어서 좋은쪽(?) 이미지를 보여주도록 하는 것도 좋겠습니다만,
.. 일단 그냥 냅뒀습니다.
**
if (((backpn==lfrontpn)||(frontpn==lbackpn))&&(backpn!=frontpn)) { .. }
요부분이 연속성 처리과정입니다.
이전(?)에 표시한 내용과 비교해서 준비한 위치가 반대쪽과 같다면
준비한 값들 자리바꿔 표시한다는 내용이죠.
**
else if (lbackpn!=backpn) { .. }
else if (lfrontpn!=frontpn) { .. }
진짜(?) 표시될 위치가 이전과 다를 때,
우선, 표시될 투명도를 조정한다는 내용입니다.
이 방법론보다 더 진지(?)해야 합니다만,
= =;.. 딱히 생각나는 방법이 없어서요..
**
if (scrollDiv==document.body) window.onscroll=scrollLeader;
else if (scrollDiv==document.documentElement) window.onscroll=scrollLeader; // for IE
else
scrollDiv.onscroll=scrollLeader;
scrollDiv 에 적용될 내용에 관련해 서술한 내용입니다.
가능하다면 document.body 나 document.documentElement 에 적용하고 싶었습니다만,
(실제 onscroll 이벤트를 받는 element 입니다..)
모바일에서는 그게 사치(?)라서요.. = =;..
**
scrollDiv.onclick=function(){ .. }
스크롤되던 내용을 클릭하면 어떤 것을 보여줄까..에 대한 내용입니다.
훨씬(?) 잘 보이는 쪽을 보여주는게 정답이더라구요.
**
if (navigator.userAgent.match(/mobile/i)) {
scrollpo.innerHTML='<textarea style="font-size:100px;" width=100% height=100% readonly=readonly id=scrollDiv ></textarea>';
}
else {
scrollpo.innerHTML='<'+'div id=scrollDiv ><'+'div id=scrollBoard ><'+'/div><'+'/div>';
}
모바일용과 일반 브라우져용을 구별해놨습니다.
브라우져용으로는 textarea 를, 일반 브라우져용으로는 div 를 쓰기로 한거죠.
처음에는 div 를 써봤습니다만,
모바일에서 스크롤이 표시 안되는 문제가 있어 찾다찾다 textarea 를 선택했죠.
그러다가, pc 용에서 클릭 한번이 더 소모된다는 것을 알고(?)
일반 브라우져용 기준으로만 다시 div 로 복귀시킨 내용입니다.
**
function fillscrollDiv(scrollDiv, h) { .. }
if (navigator.userAgent.match(/mobile/i)) {
fillscrollDiv(scrollDiv, back.scrollHeight);
}
else { .. }
scrollDiv 의 스크롤크기를 지정한다는 내용입니다.
fillscrollDiv 내용을 보시면 \n 이 여러개 있는데요,
textarea 의 scrollHeight 를 최대한 맞추려고 loop 돌리게 되어있죠..
= =;.. 이 부분때문에 PC 가 멈출 수도 있을겁니다.. (가능성의 부분에서요..)
loop 횟수를 제한해야하는 것 아닐까..라는 생각도 드네요.
...
5)
대충 이런 내용으로 작성한거죠.
가끔씩 animation by script 관련 기술을 구사해보면서
페이징은 단순 flip 만 시도했습니다만,
이번에는 참 간만에(?) smooth flip 까지 적용해봤군요.
(이전에 가입한 클럽에서 유사한 기술을 구사해본 적이 있긴 했죠..)
가장 힘들었던 부분이 모바일이었습니다.
scroll 이벤트를 어떻게든 받아쓴다고, 고생 좀 했죠.
.. 가능하다면 minimul-scale:1.0, maximu-scale:1.0 환경에서도
쓸 수 있도록 만들고 싶다는 욕심도 드는군요..
*참고*
원본 이미지 쿼리티..를 남겨두고 싶어서
이미지 크기 조정 하지 않았습니다.
*참고2*
풍뎅이뎅이 연재관라하는 쪽에서 이미지 못쓴다고 한다면
.. 딱히 쓸수 이미지는 없고.. 그냥 이미지 없이 넣어두는 게 맞겠네요.
.. 숫자라도 집어넣을까..라는 생각도 해보구요.
*참고3*
이쪽에 올리기 전에 올렸던 내용입니다.
http://www.cyworld.com/kimkiewoong/7013006
ㅜ.ㅜ.. 모바일에서는 안나오는군요.. (무슨 문제인지는 파악을 못하고 있구요..)
댓글쪽에 첨부파일 주소 있긴 합니다.
*update* ('16.06.03 10:45)
opacity:0; => display:none; .. so, opacity:0.01; background-color:inherit;
easyBow killofki@.
'event' 카테고리의 다른 글
IE8] 싸이월드 공감아이콘을 공감버튼으로 바꿔봅니다. (0) | 2013.11.14 |
---|---|
window.event] 이벤트가 받아내는 값을 봅니다.. (0) | 2013.09.16 |
selection] 선택 범위 해제에 관련해서.. (0) | 2012.04.04 |
scrollBar] 스크롤 드래그를 감지해보고 싶었습니다. (0) | 2012.04.04 |
z-index] 이미지 DIV 의 z-index 값을 변경해봤습니다.. (0) | 2012.04.02 |