javascript - 如何限制 360 度查看器在 180 度视图上停止 - 所以后面会被隐藏?
问题描述
我使用 jQuery 插件创建可拖动的 360 度查看器:http: //nick-jonas.github.io/threesixtyjs/。
观众的对象是一个展台,我想将视图限制为 180 度,因为没有可用的对象的后视图。通过限制视图,我的意思是在对象到达其中一个侧视图时停止对象的“旋转”。使用现有代码,由于缺少后视图,在拖动时,视图在旋转时会从一侧视图跳转到对面。
是否可以对现有的 Javascript 代码进行一些更改以实现此结果?
HTML/CSS/JS 如下:
/*!
* ThreeSixty: A jQuery plugin for generating a draggable 360 preview from an image sequence.
* Version: 0.1.2
* Original author: @nick-jonas
* Website: http://www.nickjonas.nyc
* Licensed under the Apache License Version 2.0
*/
;(function ( $, _window, document ) {
var scope,
pluginName = 'threeSixty',
defaults = {
dragDirection: 'horizontal',
useKeys: false,
draggable: true
},
dragDirections = ['horizontal', 'vertical'],
options = {},
$el = {},
data = [],
total = 0,
loaded = 0;
/**
* Constructor
* @param {jQuery Object} element main jQuery object
* @param {Object} customOptions options to override defaults
*/
function ThreeSixty( element, customOptions ) {
scope = this;
this.element = element;
options = options = $.extend( {}, defaults, customOptions) ;
this._defaults = defaults;
this._name = pluginName;
// make sure string input for drag direction is valid
if($.inArray(options.dragDirection, dragDirections) < 0){
options.dragDirection = defaults.dragDirection;
}
this.init();
}
// PUBLIC API -----------------------------------------------------
$.fn.destroy = ThreeSixty.prototype.destroy = function(){
if(options.useKeys === true) $(document).unbind('keydown', this.onKeyDown);
$(this).removeData();
$el.html('');
};
$.fn.nextFrame = ThreeSixty.prototype.nextFrame = function(){
$(this).each(function(i){
var $this = $(this),
val = $this.data('lastVal') || 0,
thisTotal = $this.data('count');
val = val + 1;
$this.data('lastVal', val);
if(val >= thisTotal) val = val % (thisTotal - 1);
else if(val <= -thisTotal) val = val % (thisTotal - 1);
if(val > 0) val = thisTotal - val;
val = Math.abs(val);
$this.find('.threesixty-frame').css({display: 'none'});
$this.find('.threesixty-frame:eq(' + val + ')').css({display: 'block'});
});
};
$.fn.prevFrame = ThreeSixty.prototype.prevFrame = function(){
$(this).each(function(i){
var $this = $(this),
val = $this.data('lastVal') || 0,
thisTotal = $this.data('count');
val = val - 1;
$this.data('lastVal', val);
if(val >= thisTotal) val = val % (thisTotal - 1);
else if(val <= -thisTotal) val = val % (thisTotal - 1);
if(val > 0) val = thisTotal - val;
val = Math.abs(val);
$this.find('.threesixty-frame').css({display: 'none'});
$this.find('.threesixty-frame:eq(' + val + ')').css({display: 'block'});
});
};
// PRIVATE METHODS -------------------------------------------------
/**
* Initializiation, called once from constructor
* @return null
*/
ThreeSixty.prototype.init = function () {
var $this = $(this.element);
// setup main container
$el = $this;
// store data attributes for each 360
$this.each(function(){
var $this = $(this),
link = $this.data('link'),
count = $this.data('count');
data.push({'link': link, 'count': count, 'loaded': 0, '$el': $this});
total += count;
});
_disableTextSelectAndDragIE8();
this.initLoad();
};
/**
* Start loading all images
* @return null
*/
ThreeSixty.prototype.initLoad = function() {
var i = 0, len = data.length, url, j;
$el.addClass('preloading');
for(i; i < len; i++){
j = 0;
for(j; j < data[i].count; j++){
url = data[i].link.replace('{index}', j);
$('<img/>').data('index', i).attr('src', url).load(this.onLoadComplete);
}
}
};
ThreeSixty.prototype.onLoadComplete = function(e) {
var index = $(e.currentTarget).data('index'),
thisObj = data[index];
thisObj.loaded++;
if(thisObj.loaded === thisObj.count){
scope.onLoadAllComplete(index);
}
};
ThreeSixty.prototype.onLoadAllComplete = function(objIndex) {
var $this = data[objIndex].$el,
html = '',
l = data[objIndex].count,
linkTemplate = data[objIndex].link,
i = 0;
// remove preloader
$this.html('');
$this.removeClass('preloading');
// add 360 images
for(i; i < l; i++){
var display = (i === 0) ? 'block' : 'none';
html += '<img class="threesixty-frame" style="display:' + display + ';" data-index="' + i + '" src="' + linkTemplate.replace('{index}', i) + '"/>';
}
$this.html(html);
this.attachHandlers(objIndex);
};
var startY = 0,
thisTotal = 0,
$downElem = null,
lastY = 0,
lastX = 0,
lastVal = 0,
isMouseDown = false;
ThreeSixty.prototype.attachHandlers = function(objIndex) {
var that = this;
var $this = data[objIndex].$el;
// add draggable events
if(options.draggable){
// if touch events supported, use
if(typeof document.ontouchstart !== 'undefined' &&
typeof document.ontouchmove !== 'undefined' &&
typeof document.ontouchend !== 'undefined' &&
typeof document.ontouchcancel !== 'undefined'){
var elem = $this.get()[0];
elem.addEventListener('touchstart', that.onTouchStart);
elem.addEventListener('touchmove', that.onTouchMove);
elem.addEventListener('touchend', that.onTouchEnd);
elem.addEventListener('touchcancel', that.onTouchEnd);
}
}
// mouse down
$this.mousedown(function(e){
e.preventDefault();
thisTotal = $(this).data('count');
$downElem = $(this);
startY = e.screenY;
lastVal = $downElem.data('lastVal') || 0;
lastX = $downElem.data('lastX') || 0;
lastY = $downElem.data('lastY') || 0;
isMouseDown = true;
$downElem.trigger('down');
});
// arrow keys
if(options.useKeys === true){
$(document).bind('keydown', that.onKeyDown);
}
// mouse up
$(document, 'html', 'body').mouseup(that.onMouseUp);
$(document).blur(that.onMouseUp);
$('body').mousemove(function(e){
that.onMove(e.screenX, e.screenY);
});
};
ThreeSixty.prototype.onTouchStart = function(e) {
var touch = e.touches[0];
e.preventDefault();
$downElem = $(e.target).parent();
thisTotal = $downElem.data('count');
startX = touch.pageX;
startY = touch.pageY;
lastVal = $downElem.data('lastVal') || 0;
lastX = $downElem.data('lastX') || 0;
lastY = $downElem.data('lastY') || 0;
isMouseDown = true;
$downElem.trigger('down');
};
ThreeSixty.prototype.onTouchMove = function(e) {
e.preventDefault();
var touch = e.touches[0];
scope.onMove(touch.pageX, touch.pageY);
};
ThreeSixty.prototype.onTouchEnd = function(e) {
};
ThreeSixty.prototype.onMove = function(screenX, screenY){
if(isMouseDown){
var x = screenX,
y = screenY,
val = 0;
$downElem.trigger('move');
if(options.dragDirection === 'vertical'){
if(y > lastY){
val = lastVal + 1;
}else{
val = lastVal - 1;
}
}else{
if(x > lastX){
val = lastVal + 1;
}else if(x === lastX){
return;
}else{
val = lastVal - 1;
}
}
lastVal = val;
lastY = y;
lastX = x;
$downElem.data('lastY', lastY);
$downElem.data('lastX', lastX);
$downElem.data('lastVal', lastVal);
if(val >= thisTotal) val = val % (thisTotal - 1);
else if(val <= -thisTotal) val = val % (thisTotal - 1);
if(val > 0) val = thisTotal - val;
val = Math.abs(val);
$downElem.find('.threesixty-frame').css({display: 'none'});
$downElem.find('.threesixty-frame:eq(' + val + ')').css({display: 'block'});
}
};
ThreeSixty.prototype.onKeyDown = function(e) {
switch(e.keyCode){
case 37: // left
$el.prevFrame();
break;
case 39: // right
$el.nextFrame();
break;
}
};
ThreeSixty.prototype.onMouseUp = function(e) {
isMouseDown = false;
$downElem.trigger('up');
};
/**
* Disables text selection and dragging on IE8 and below.
*/
var _disableTextSelectAndDragIE8 = function() {
// Disable text selection.
document.body.onselectstart = function() {
return false;
};
// Disable dragging.
document.body.ondragstart = function() {
return false;
};
};
/**
* A really lightweight plugin wrapper around the constructor,
preventing against multiple instantiations
* @param {Object} options
* @return {jQuery Object}
*/
$.fn[pluginName] = function ( options ) {
return this.each(function () {
if (!$.data(this, 'plugin_' + pluginName)) {
$.data(this, 'plugin_' + pluginName,
new ThreeSixty( this, options ));
}
});
};
})( jQuery, window, document );
@charset "UTF-8";
@-webkit-keyframes ui-spinner-rotate-right {
/* line 58, ../../scss/_ui-spinner.scss */
0% {
-webkit-transform: rotate(0deg);
}
/* line 59, ../../scss/_ui-spinner.scss */
25% {
-webkit-transform: rotate(180deg);
}
/* line 60, ../../scss/_ui-spinner.scss */
50% {
-webkit-transform: rotate(180deg);
}
/* line 61, ../../scss/_ui-spinner.scss */
75% {
-webkit-transform: rotate(360deg);
}
/* line 62, ../../scss/_ui-spinner.scss */
100% {
-webkit-transform: rotate(360deg);
}
}
@-webkit-keyframes ui-spinner-rotate-left {
/* line 66, ../../scss/_ui-spinner.scss */
0% {
-webkit-transform: rotate(0deg);
}
/* line 67, ../../scss/_ui-spinner.scss */
25% {
-webkit-transform: rotate(0deg);
}
/* line 68, ../../scss/_ui-spinner.scss */
50% {
-webkit-transform: rotate(180deg);
}
/* line 69, ../../scss/_ui-spinner.scss */
75% {
-webkit-transform: rotate(180deg);
}
/* line 70, ../../scss/_ui-spinner.scss */
100% {
-webkit-transform: rotate(360deg);
}
}
@-moz-keyframes ui-spinner-rotate-right {
/* line 74, ../../scss/_ui-spinner.scss */
0% {
-moz-transform: rotate(0deg);
}
/* line 75, ../../scss/_ui-spinner.scss */
25% {
-moz-transform: rotate(180deg);
}
/* line 76, ../../scss/_ui-spinner.scss */
50% {
-moz-transform: rotate(180deg);
}
/* line 77, ../../scss/_ui-spinner.scss */
75% {
-moz-transform: rotate(360deg);
}
/* line 78, ../../scss/_ui-spinner.scss */
100% {
-moz-transform: rotate(360deg);
}
}
@-moz-keyframes ui-spinner-rotate-left {
/* line 82, ../../scss/_ui-spinner.scss */
0% {
-moz-transform: rotate(0deg);
}
/* line 83, ../../scss/_ui-spinner.scss */
25% {
-moz-transform: rotate(0deg);
}
/* line 84, ../../scss/_ui-spinner.scss */
50% {
-moz-transform: rotate(180deg);
}
/* line 85, ../../scss/_ui-spinner.scss */
75% {
-moz-transform: rotate(180deg);
}
/* line 86, ../../scss/_ui-spinner.scss */
100% {
-moz-transform: rotate(360deg);
}
}
@keyframes ui-spinner-rotate-right {
/* line 90, ../../scss/_ui-spinner.scss */
0% {
transform: rotate(0deg);
}
/* line 91, ../../scss/_ui-spinner.scss */
25% {
transform: rotate(180deg);
}
/* line 92, ../../scss/_ui-spinner.scss */
50% {
transform: rotate(180deg);
}
/* line 93, ../../scss/_ui-spinner.scss */
75% {
transform: rotate(360deg);
}
/* line 94, ../../scss/_ui-spinner.scss */
100% {
transform: rotate(360deg);
}
}
@keyframes ui-spinner-rotate-left {
/* line 98, ../../scss/_ui-spinner.scss */
0% {
transform: rotate(0deg);
}
/* line 99, ../../scss/_ui-spinner.scss */
25% {
transform: rotate(0deg);
}
/* line 100, ../../scss/_ui-spinner.scss */
50% {
transform: rotate(180deg);
}
/* line 101, ../../scss/_ui-spinner.scss */
75% {
transform: rotate(180deg);
}
/* line 102, ../../scss/_ui-spinner.scss */
100% {
transform: rotate(360deg);
}
}
/* line 110, ../../scss/_ui-spinner.scss */
.ui-spinner {
position: relative;
border-radius: 100%;
}
/* line 114, ../../scss/_ui-spinner.scss */
.ui-spinner .side {
width: 50%;
height: 100%;
overflow: hidden;
position: absolute;
}
/* line 120, ../../scss/_ui-spinner.scss */
.ui-spinner .side .fill {
border-radius: 999px;
position: absolute;
width: 100%;
height: 100%;
-webkit-animation-iteration-count: infinite;
-moz-animation-iteration-count: infinite;
-ms-animation-iteration-count: infinite;
-o-animation-iteration-count: infinite;
animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
-moz-animation-timing-function: linear;
-ms-animation-timing-function: linear;
-o-animation-timing-function: linear;
animation-timing-function: linear;
}
/* line 130, ../../scss/_ui-spinner.scss */
.ui-spinner .side-left {
left: 0;
}
/* line 133, ../../scss/_ui-spinner.scss */
.ui-spinner .side-left .fill {
left: 100%;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
-webkit-animation-name: ui-spinner-rotate-left;
-moz-animation-name: ui-spinner-rotate-left;
-ms-animation-name: ui-spinner-rotate-left;
-o-animation-name: ui-spinner-rotate-left;
animation-name: ui-spinner-rotate-left;
-webkit-transform-origin: 0 50%;
-moz-transform-origin: 0 50%;
-ms-transform-origin: 0 50%;
-o-transform-origin: 0 50%;
transform-origin: 0 50%;
}
/* line 142, ../../scss/_ui-spinner.scss */
.ui-spinner .side-right {
left: 50%;
}
/* line 145, ../../scss/_ui-spinner.scss */
.ui-spinner .side-right .fill {
left: -100%;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
-webkit-animation-name: ui-spinner-rotate-right;
-moz-animation-name: ui-spinner-rotate-right;
-ms-animation-name: ui-spinner-rotate-right;
-o-animation-name: ui-spinner-rotate-right;
animation-name: ui-spinner-rotate-right;
-webkit-transform-origin: 100% 50%;
-moz-transform-origin: 100% 50%;
-ms-transform-origin: 100% 50%;
-o-transform-origin: 100% 50%;
transform-origin: 100% 50%;
}
/* line 1, ../../scss/_ui.scss */
.ui {
width: 100%;
position: relative;
margin: 30px 0 0 0;
}
/* line 6, ../../scss/_ui.scss */
.ui .next {
font-size: 1em;
position: absolute;
display: inline-block;
color: rgb(0, 0, 0);
cursor: pointer;
right: 17px;
}
/* line 14, ../../scss/_ui.scss */
.ui .prev {
font-size: 1em;
position: absolute;
display: inline-block;
color: rgb(0, 0, 0);
cursor: pointer;
left: 17px;
}
/* line 26, ../../scss/_ui-spinner.scss */
.ui-spinner {
width: 46px;
height: 46px;
background: #dddddd;
}
/* line 31, ../../scss/_ui-spinner.scss */
.ui-spinner .side .fill {
background: #3c76ca;
-webkit-animation-duration: 3s;
-moz-animation-duration: 3s;
-ms-animation-duration: 3s;
-o-animation-duration: 3s;
animation-duration: 3s;
opacity: 0.8;
}
/* line 39, ../../scss/_ui-spinner.scss */
.ui-spinner:after {
content: "";
background: transparent;
position: absolute;
width: 28px;
height: 28px;
border-radius: 50%;
top: 9px;
left: 9px;
display: block;
}
/* line 11, ../../scss/main.scss */
body {
font-size: 12px;
font-family: roc-grotesk, sans-serif;
font-weight: 300;
background-color: rgb(255, 255, 255);
text-align: center;
margin: 0 auto;
width: 100%;
}
/* line 39, ../../scss/main.scss */
body .threesixty-wrapper {
margin: 0;
height: 100vh;
width: 100%;
position: relative;
}
/* line 43, ../../scss/main.scss */
body .threesixty-wrapper .threesixty {
display: block;
width: 100%;
}
/* line 26, ../../scss/_ui-spinner.scss */
body .threesixty-wrapper .threesixty .ui-spinner {
width: 50px;
height: 50px;
background: #c2fccc;
}
/* line 31, ../../scss/_ui-spinner.scss */
body .threesixty-wrapper .threesixty .ui-spinner .side .fill {
background: #55fc5a;
-webkit-animation-duration: 3s;
-moz-animation-duration: 3s;
-ms-animation-duration: 3s;
-o-animation-duration: 3s;
animation-duration: 3s;
opacity: 0.8;
}
/* line 39, ../../scss/_ui-spinner.scss */
body .threesixty-wrapper .threesixty .ui-spinner:after {
content: "";
background: transparent;
position: absolute;
width: 30px;
height: 30px;
border-radius: 50%;
top: 10px;
left: 10px;
display: block;
}
/* line 49, ../../scss/main.scss */
body .threesixty-wrapper .threesixty .ui-spinner {
margin: 270px auto;
}
/* line 54, ../../scss/main.scss */
body .threesixty-wrapper .label {
margin: 0 auto;
display: inline-block;
}
.threesixty img {
width: auto;
margin: 0 auto;
height: 80vh;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<html>
<head>
<title>ThreeSixty</title>
<link rel="stylesheet" href="https://use.typekit.net/spl8uhp.css">
</head>
<body>
<div class="threesixty-wrapper">
<div class="threesixty" data-link="https://ergoncreative-my.sharepoint.com/personal/anna_ergoncreative_com/Documents/src/Finnplay{index}.png" data-count="19">
<!-- put your preloader here -->
<div class="ui-spinner">
<span class="side side-left">
<span class="fill"></span>
</span>
<span class="side side-right">
<span class="fill"></span>
</span>
</div>
<!-- end preloader -->
</div>
<div class="ui">
<div class="next">next frame</div>
<div class="prev">previous frame</div>
</div>
<img src="assets/img/label.png" alt="" class="label"/>
</div>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
var $threeSixty = $('.threesixty');
$threeSixty.threeSixty({
dragDirection: 'horizontal',
useKeys: true,
draggable: true
});
$('.next').click(function(){
$threeSixty.nextFrame();
});
$('.prev').click(function(){
$threeSixty.prevFrame();
});
$threeSixty.on('down', function(){
$('.ui, h1, h2, .label, .examples').stop().animate({opacity:0}, 300);
});
$threeSixty.on('up', function(){
$('.ui, h1, h2, .label, .examples').stop().animate({opacity:1}, 500);
});
});
</script>
</body>
</html>
解决方案
推荐阅读
- python - Python:将文本从 HTML 或文本文档导入 Word
- nestjs - NestJS,在提供者上使用 typeorm
- javascript - 同一个 React 组件中的多个下拉菜单不起作用
- javascript - Javascript 四舍五入
- windows-10 - Arris 端口转发
- amazon-web-services - AWS CLI describe-snapshots 以打印 SnapshotId
- java - java.io.FileNotFoundException 在 java 中获取文件的路径
- c# - 将类插入列表时如何触发一些代码
- python - 为什么 Python 中的 turtle 模块在尝试访问它时似乎有一个 screen 属性会导致属性错误?
- azure - pyodbc 是否支持使用 AD 访问令牌而不是用户/密码连接到 Azure SQL DB?