JavaScript_javascript 기술로 구현된 그림 3D 디스플레이 공간(3DRoom)

WBOY
풀어 주다: 2016-05-16 18:18:48
원래의
1380명이 탐색했습니다.

프로그램은 이러한 3차원 공간을 시뮬레이션하며, 내부의 사진은 3차원 좌표에 따라 이 공간에 표시됩니다.
복잡한 계산을 통해 구현되는 3DRoom 효과를 오래전에 봤습니다.
이전 글 이미지 변환에서 CSS3 변환을 연구한 후, 이를 구현하는 더 간단한 방법을 생각했습니다.
호환 대상: ie6/7/8, firefox 3.6.8, Opera 10.6, safari 5.0.1, chrome 5.0

효과 미리보기
JavaScript_javascript 기술로 구현된 그림 3D 디스플레이 공간(3DRoom)
3DRoom
JavaScript_javascript 기술로 구현된 그림 3D 디스플레이 공간(3DRoom)
절차 설명

【구현원리】

3D 효과의 핵심은 깊이감 구현입니다.
3D 컨테이너는 깊이가 다른 여러 레이어로 구성된 공간이라고 생각하세요. 이러한 레이어의 크기는 기본적으로 컨테이너와 동일합니다.
레이어에 심도 그림을 배치하고, 심도 변화에 따라 각 레이어의 크기가 조정되고 변형되어 시각적인 깊이 차이가 발생합니다.
가장 가까운 지점이 1이 되고 가장 먼 지점이 0이 되는 방식으로 스케일링 변환 비율이 점진적으로 변경됩니다.
핵심은 레이어에 있는 이미지의 크기와 좌표가 레이어와 동시에 변환되어야 한다는 것입니다. 이는 CSS3 변환을 통해 쉽게 달성할 수 있습니다.
이런 방식으로 이미지의 크기를 설정하고 레이어를 기준으로 위치를 지정하기만 하면 심도 변화에 따라 이미지 크기와 위치를 지속적으로 조정하는 수고를 피할 수 있습니다.


【사진 불러오기】

프로그램 초기화 후 add 메소드를 호출하여 사진을 추가할 수 있습니다.
add 메소드에는 이미지 주소와 매개변수 개체라는 두 가지 매개변수가 있으며 이미지 작업 개체도 반환합니다.
작업 개체에는 그림 작업을 용이하게 하기 위해 다음과 같은 속성과 메서드가 포함되어 있습니다.
img: 그림 요소
src: 그림 주소
options: 매개변수 개체
show: 그림 표시 방법
remove : 이미지 제거 방법
여기서 옵션은 다음 속성을 설정할 수 있습니다.
속성: 기본값 // 설명
x: 0, // 가로 변위
y: 0, // 세로 변위
z: 0,//깊이
너비: 0,//너비
높이: 0,//높이
scaleW: 1,//너비 스케일링
scaleH: 1//높이 스케일링
그 중 x, y는 각각 가로 좌표와 세로 좌표의 변위 매개변수입니다. 좌표 원점은 컨테이너 하단 중앙, 가로 좌표는 오른쪽, 세로 좌표는 위쪽입니다. 단위는 px입니다.
Z는 스케일 계산에 사용되는 깊이이며, 방향은 가까운 지점에서 원점을 향합니다.
좌표계는 아래와 같습니다.


이미지가 성공적으로 로드되면 _load 이미지 로딩 프로그램이 실행됩니다.
먼저 매개변수에 따라 이미지 스타일을 설정하세요.

코드 복사 코드는 다음과 같습니다.

img.style.cssText = "위치:절대;경계:0;패딩:0;마진:0;-ms-보간-모드:가장 가까운 이웃;
"z-색인 :" (99999 - z) ";width:" 너비 "px;height:" 높이 "px;"
"왼쪽:" (((clientWidth - 너비) / 2 opt.x) / clientWidth * JavaScript_javascript 기술로 구현된 그림 3D 디스플레이 공간(3DRoom)). toFixed(5) "%; "
"top:" ((clientHeight - height - opt.y) / clientHeight * JavaScript_javascript 기술로 구현된 그림 3D 디스플레이 공간(3DRoom)).toFixed(5) "%;"

절대 위치 지정이 필요하며 매개변수에 따라 너비와 높이를 설정할 수 있습니다.
왼쪽과 위쪽은 좌표 매개변수를 기준으로 계산되며, 이에 대해서는 나중에 자세히 설명합니다.
또한 쉽게 호출할 수 있도록 깊이를 기록하려면 이미지에 _z 속성을 추가하세요.
마지막으로 z에 해당하는 레이어를 삽입하고 레이어를 다시 표시합니다.


【레이어 변형】

이미지가 로드된 후 _insertLayer 프로그램을 사용하여 해당 레이어에 이미지를 삽입합니다.
_insertLayer에는 이미지 요소와 z 깊이라는 두 가지 매개변수가 있습니다.
프로그램은 _layers 개체를 사용하여 z를 키워드로 해당 레이어 요소를 기록합니다.
이 깊이에서 레이어가 생성되지 않은 경우 자동으로 생성됩니다.

코드 복사 코드는 다음과 같습니다.

layer = document.createElement("div")
layer.style.cssText = "position:absolute;border:0;padding:0;margin: 0;왼쪽:0;상단 :0;가시성:숨김;배경:투명;너비:" this._clientWidth "px;height:" this._clientHeight "px;";

레이어의 좌표와 크기는 컨테이너와 일치해야 합니다. 삽입된 이미지의 좌표는 컨테이너를 기준으로 정의되므로 사용하기가 더 편리합니다.
레이어에 포함된 사진 수를 기록하기 위해 _count 속성도 추가되고, 마지막으로 컨테이너에 삽입되어 _layers 개체에 기록됩니다.
레이어 객체를 얻은 후 이미지를 레이어에 삽입하고 _count에 1을 추가합니다.

그런 다음 _showLayer 프로그램을 사용하여 깊이에 따라 해당 레이어를 표시할 수 있습니다.
프로그램에는 컨테이너의 3차원 좌표 오프셋을 나타내는 _x, _y, _z의 세 가지 좌표 속성이 포함되어 있습니다.
먼저 _getScale 메소드를 통해 z 깊이의 스케일을 가져옵니다.
비율이 1보다 크면 이미지가 시각적인 깊이보다 뒤에 있어 이론적으로 보이지 않아야 함을 의미하므로 0보다 작으면 너무 작아서 보이지 않는다는 의미입니다. 숨겨져 있습니다.

_x 및 _y 오프셋도 깊이에 따라 다시 계산해야 합니다. 프로그램에는 원거리 고정과 근거리 고정의 두 가지 오프셋 방법이 있습니다.
원점 고정은 평면 변위 오프셋이 깊이에 따라 점차 작아짐을 의미하며, 결과적으로 가장 먼 점을 고정점 이동 방향으로 사용하는 효과가 발생합니다.
이 효과를 얻으려면 변위 오프셋도 비율에 따라 변경되는 한, 즉 먼 점이 고정되면 오프셋이 비율에 비례하고 먼 점이 고정되면 반비례합니다. :

코드 복사 코드는 다음과 같습니다.

var moveScale = this. fixedFar ? scale : (1 - scale);

그런 다음 이러한 매개변수를 _show 프로그램에 제공하여 효과를 표시합니다.

레이어 요소의 사용을 극대화하기 위해 프로그램은 그림이 없는 레이어를 _remove 그림 제거 프로그램의 _invalid 폐기 레이어 컬렉션에 넣습니다. 레이어를 삽입해야 할 경우 먼저 _invalid에서 가져옵니다.


【규모 비율】

위에서 언급했듯이 스케일링 비율은 가장 가까운 지점이 1이 되고 가장 먼 지점이 0이 되는 방식으로 점진적으로 변경되어야 합니다.
프로그램은 기본적으로 다음 공식에 따라 계산합니다.

함수(z){ return 1 - z / JavaScript_javascript 기술로 구현된 그림 3D 디스플레이 공간(3DRoom)0 }

그러나 이 공식을 사용하여 3DRoom 효과를 얻으면 비율이 너무 빨리 변하고 이 3DRoom만큼 매끄럽지 않다는 것을 알게 될 것입니다.

코드를 연구한 결과, 사용된 공식은 다음과 같습니다.

.r = FL / (FL (z * Z));

여기서 FL과 Z는 상수입니다. 즉, 공식은 다음과 같이 표현될 수 있습니다.

기능(z){ 반환 1/ (1 z/ 상수) }

이 공식에 따르면 깊이가 0이면 눈금이 1이고, 깊이가 일정하면 눈금이 0.5이고, 깊이가 무한대이면 눈금이 0입니다.

효과를 변경하려면 다음 절차를 참조하세요.


[Ctrl A 모두 선택 참고: 외부 J를 도입해야 하는 경우 실행하려면 새로 고쳐야 합니다.
]

As 보시다시피, 스케일링 비율은 기본 공식이 균등하게 변경되는 반면, 3DRoom 공식은 처음에는 빠르다가 느려졌다가 점차 느려지므로 부드러운 느낌을 줍니다. 실제 상황에 따라 1과 0 사이에서 변경되는 한 적절한 수식을 직접 설계할 수도 있습니다.


[css3 모드]


프로그램에는 css3, Zoom 및 Base의 세 가지 확대/축소 변환 방법이 있습니다. 모드의 프로그램 구조는 이전과 유사합니다.

스케일링 변환의 목적은 전달된 비율과 위치 오프셋을 기반으로 스케일링 효과를 표시하여 최종 3D 효과를 얻는 것입니다.


css3 모드는 CSS3 변환을 사용합니다. 이전 기사에서는 크기 조정 및 회전을 위한 변환 행렬의 사용을 소개했습니다. 이번에는 위치 변환을 위한 다음 두 매개변수도 필요합니다. MDC의 -moz-transform
에 설명된 마지막 두 매개변수의 단위 설정에 주의하세요.
Gecko(Firefox)는 tx와 tx에 ty.
Safari(WebKit) 및 Opera는 현재 tx 및 ty에 대해 단위 없는 를 지원합니다.
즉, Firefox에서는 변위 매개변수 tx 및 ty에 단위가 있어야 하지만 WebKit 및 Opera에는 숫자만 필요합니다. (단위 없음, 기본 px)

프로그램은 브라우저에 따라 단위를 설정합니다.


css3 모드를 사용하면 _r arc 속성을 수정하여 회전할 수도 있습니다.
마지막으로 변환을 구현하기 위한 행렬을 설정합니다.

코드는 다음과 같습니다.


layer.style [ css3Transform ] = "matrix("
( Cos * scale).toFixed(5) "," (Sin * scale).toFixed(5) ","
(-Sin * scale).toFixed(5 ) "," (Cos * scale).toFixed(5) ", "
Math.round(x) 단위 ", " Math.round(y) 단위 ")"; >

여기서 주목해야 할 또 다른 문제가 있습니다. 계산된 비율이 매우 긴 소수점으로 인해 문자 철자에 문제가 발생할 수 있습니다.
예를 들어, 경고(0.0000001)를 실행하면 "1e-7"이 표시됩니다. JS는 이 결과를 사용하여 문자를 철자하고 잘못된 결과를 얻습니다.
따라서 숫자와 문자를 이어붙일 때 정수를 사용할 수 있는 것부터 정수로 변환하고, 소수도 toFixed를 사용해 변환해야 합니다.


【확대 모드】

IE는 아직 변환을 지원하지 않지만 비슷한 효과를 얻을 수 있는 확대/축소 스타일이 있습니다.
확대 후 크기가 변경되므로 왼쪽과 위쪽의 움직임을 올바른 위치로 수정해야 합니다.

ie 외에도 webkit(chrome/safari)도 확대/축소를 지원하지만 ie6/7, ie8 및 webkit의 구현이 완전히 동일하지는 않습니다.
.inner{ 너비:JavaScript_javascript 기술로 구현된 그림 3D 디스플레이 공간(3DRoom)px; 높이:JavaScript_javascript 기술로 구현된 그림 3D 디스플레이 공간(3DRoom)px; 배경:#0CF; 왼쪽:50px;}
.inner div ; 높이:50px;위치:절대; 왼쪽:25px;배경:#CCC;}

test

ie6/7에서 원하는 효과를 얻었으나 웹킷에 표시되는 위치가 잘못되었습니다.
이유는 확대/축소를 사용하면 요소의 왼쪽과 위쪽도 크기가 조정되므로 비율에 따라 다시 계산하면 되기 때문입니다.
위의 예처럼 왼쪽과 위쪽을 50/0.5, 즉 JavaScript_javascript 기술로 구현된 그림 3D 디스플레이 공간(3DRoom)으로 변경하면 정확합니다.

ie8은 더욱 번거롭습니다. 내부 내용은 확대/축소에 따라 크기가 조정되지만 왼쪽과 상단은 여전히 ​​원래 크기입니다.
저는 이 문제로 오랫동안 고민했는데, 마침내 백분율 위치 지정을 사용하면 이 문제를 해결할 수 있다는 것을 알게 되었습니다. 이것이 바로 이미지를 로드할 때 왼쪽과 위쪽에 백분율이 사용되는 이유입니다.
예를 들어, 예시에서는 왼쪽과 위쪽을 수정하고 가장 안쪽 div의 왼쪽을 25%로 변경합니다.
IE8에서도 문제가 보이더군요. 확대 후 내용이 줄어들었는데, 컨테이너 크기와 내부 요소는 바뀌지 않았네요. 다행히도 이미지 표시에는 영향을 미치지 않습니다. 문제가 발생하지 않도록 위치 지정을 위한 상단입니다.
또한 확대/축소 요소의 크기를 백분율로 설정하면 요소의 크기가 확대/축소에 따라 조정되지 않습니다.

계산할 때 주의해야 할 또 다른 문제가 있는데, 위에서 언급한 것처럼 webkit과 ie8에서는 scale이 어느 정도 0에 가까울 때 왼쪽과 위쪽을 나누어서 수정해야 합니다. 무한대(무한대).
Infinity를 사용하여 작업을 수행할 때 오류가 발생합니다. 이 문제를 해결해야 합니다.

왼쪽 = Math.min(MAX, Math.max( -MAX, 왼쪽 )) | 0;
top
= Math.min(MAX, Math. max(-MAX, 상단 )) | 0;

여기서 MAX는 Number.MAX_VALUE(js가 표현할 수 있는 최대 숫자)입니다.


【기본 모드】

모든 브라우저와 호환되는 기본 모드도 있는데, 기존 방식, 즉 배율을 기준으로 각 이미지의 크기와 위치를 계산하고 설정하는 것입니다.
표시될 때마다 레이어의 이미지를 순회하며 설정이 하나씩 계산됩니다.
계산에는 이미지의 원래 위치와 크기가 필요합니다. 첫 번째 계산 중에 데이터는 _original 속성에 저장됩니다:

var 원본 = img._original = img._original || {
너비: img.offsetWidth, 높이: img.offsetHeight,
왼쪽: img.offsetLeft, 위쪽: img.offsetTop
};

비율에 따라 크기만 조정하면 됩니다. 상대 레이어 배율을 계산하는 것 외에도 위치에 상대 컨테이너 변위도 추가해야 합니다. 이는 확대/축소 모드의 계산과 동일합니다.
레이어 변형 방법을 이해하고 나면 이를 이해하는 것은 어렵지 않습니다.


[zIndex]

크기 조정 및 위치 지정 외에도 깊이에는 합리적인 전면 및 후면 덮개도 필요합니다.
전면 및 후면 마스킹은 이미지나 레이어에 설정할 수 있는 zIndex를 사용하여 구현해야 합니다.
첫 번째로 가장 쉬운 방법은 레이어에 설정하는 것입니다.

코드 복사 코드는 다음과 같습니다.



JavaScript_javascript 기술로 구현된 그림 3D 디스플레이 공간(3DRoom)


JavaScript_javascript 기술로 구현된 그림 3D 디스플레이 공간(3DRoom)


일반적인 3D 효과를 얻으려면 이렇게 설정하면 됩니다.
그런데 테스트를 클릭하면 ff와 webkit 앞에 있는 것들은 실행될 수 있지만 뒤에 있는 것들은 실행될 수 없고, ie와 Opera는 전후에 모두 실행될 수 있습니다.
ps: img를 div로 대체하면 ie와 Opera 뒤에 있는 요소가 실행될 수 없습니다. 이유는 아직 불분명합니다.
이런 방식으로 3DRoom과 같은 사진 이벤트를 실행하려면 해당 레이어에 zIndex를 설정할 수 없습니다.
사진에 설정할 수도 있습니다.

코드 복사 코드는 다음과 같습니다.



300


JavaScript_javascript 기술로 구현된 그림 3D 디스플레이 공간(3DRoom)

这样图片在所有浏览器都能正常触发,但在ie6/7层叠的效果失效了,看来在ie6/7只能在层用zIndex。
还有一个问题,如果给div加上变换效果:
div{-moz-transform:scale(1);-webkit-transform:scale(1);-o-transform:scale(1);}
那图片上的zIndex就会失效,那css3模式就只能在层设置zIndex了。

总结一下:
在css3模式肯定要在层设置zIndex,但图片也不能触发事件。
在zoom和base模式,应该在图片设置zIndex,但在ie6/7就要在层设置。
这样至少在base模式层叠和图片触发事件都是正常的。


【msInterpolationMode】

开始做的时候,效果在ie8下会很卡,但这个3DRoom却不会卡,最后发现是使用了-ms-interpolation-mode。
这个东西在aoao的文章中看过,但没想到可以用在这里。

在MSDN有msInterpolationMode的介绍:
Gets or sets the interpolation (resampling) method used to stretch images.
即获取或设置用于拉伸图像的插值(重采样)方法。
它有两个值:
nearest-neighbor:使用近邻插值模式。
bicubic:使用高品质的双三次插值模式。
这些名词比较专业,我们只要知道使用nearest-neighbor效率高但效果差,而bicubic效果好效率低就够了。
程序把它设为nearest-neighbor提高效率,这样在ie8中也不会卡了。


【拖动方向变换/滚轮深度变换】

程序扩展了拖动视觉变换和滚轮深度变换。
拖动和滚动的做法跟上一个的做法差不多,这里拖动是实现方向的变换,滚轮是实现深度的变换。
移动是通过修改_x和_y属性来实现,缩放是通过修改_z来实现。
修改属性之后再调用show方法显示效果。


使用技巧

【3DRoom】

在3DRoom效果中,因为要实现图片的触发事件,所以不能用css3模式,原因是上面提到的层叠问题。
上面也提到在ie8被zoom的元素尺寸不会改变,导致触发范围错误,所以也不用zoom模式。
使用base模式就不会有问题了。

在点击图片时,视觉会移动到图片上面,这个通过点击图片后根据本身的三维参数修改_x/_y/_z来实现:

img.onclick = function(){
    i3D._z 
= -options.z | 0;
    i3D._x 
= -options.x | 0;
    i3D._y 
= options.y | 0;
    i3D.show();
}


그림에 마우스를 올리면 테두리가 표시됩니다. 테두리를 추가한 후 그림이 바뀌는 것을 방지하기 위해 마우스를 떼면 "-1px" 여백이 추가되고 제거됩니다.
3DRoom의 효과와 여기서 참고한 내용 사이에는 아직 격차가 있습니다. 이 기사는 주로 3D 효과의 구현 및 연구에 관한 것입니다.

【모드 선택】

CSS3 모드는 안정적이며 IE를 제외한 대부분의 브라우저에서 지원됩니다.
줌 모드는 호환성이 좋지 않지만 IE에서는 지원합니다.
base는 가장 느리지만 호환성이 좋고 버그가 없습니다.
일반적으로 CSS3 모드를 먼저 사용한 다음 Zoom, 마지막으로 Base를 사용해야 하지만 3DRoom과 같은 경우에는 실제 선택을 해야 합니다.
IE에서는 디자인할 때 Matrix 필터를 사용하려고 했으나, 개발 과정에서 몇 가지 문제점이 발견되고 효율성이 너무 낮아 고려하지 않았습니다.


사용 지침

인스턴스화할 때 매개변수로 컨테이너가 있어야 합니다.

var i3D = new Image3D( container , 옵션 );

그런 다음 i3D 메서드를 호출하여 이미지를 추가합니다.

i3D.add(src, 옵션);


선택적 매개변수는 다음을 포함하여 시스템의 기본 속성을 설정하는 데 사용됩니다.
속성: 기본값 // 설명
mode: "css3|zoom|base", //Mode
x: 0,//가로 오프셋 값
y: 0,//세로 오프셋 값
z: 0,//깊이 오프셋 값
r: 0,//회전 각도(css3 지원)
fixedFar: false,//원거리 지점이 고정되었는지 여부
getScale: function(z){ return 1 - z / JavaScript_javascript 기술로 구현된 그림 3D 디스플레이 공간(3DRoom)0 },//크기 조정 방법 가져오기
onError: function(err){}/ /오류

일 때 실행

add 메소드의 선택적 매개변수는 이미지 로딩에 설명되어 있습니다.

은 다음과 같은 방법도 제공합니다.
추가: 사진 추가
표시: 효과 표시
재설정: 기본 상태 재설정
처리: 프로그램 삭제.

드래그 방향 변환이나 휠 깊이 변환 확장을 추가한 후 관련 매개변수를 설정하여 변환 범위를 정의할 수 있습니다.

패키지 다운로드 주소http://demo.jb51.net/js/Image3D/index.htm
데모 주소/201010/yuanma/Image3D.rar

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿