Implement click and drag to rotate 3D object - vue.js - javascript

I have a button, which I click to activate the rotation function. After that, every time I hover over the object with the mouse, the object rotates as I want it to.
Now I want to change this and make the object rotate just by clicking it and moving the mouse (while still holding the mouse button). When I realease the mouse button I want it to stop rotating.
My code:
HTML:
<div class="model__3d" ref="panel3d">
<a class="button" #click.prevent="rotatemouse()">360</a>
Code js:
rotatemouse() {
document.querySelector('.model__3d').addEventListener('mousedown', () =>{
document.onmousemove = handleMouseMove;
});
//document.onmouseup = function () {
document.querySelector('.model__3d').addEventListener('mouseup', () =>{
document.onmousemove = null;
});
//function handleMouseMove(event) {
document.querySelector('.model__3d').addEventListener('mousemove', (event) =>{
let eventDoc, doc, body;
event = event || window.event;
if (event.pageX == null && event.clientX != null) {
eventDoc = (event.target && event.target.ownerDocument) || document;
doc = eventDoc.documentElement;
body = eventDoc.body;
event.pageX = event.clientX +
(doc && doc.scrollLeft || body && body.scrollLeft || 0) -
(doc && doc.clientLeft || body && body.clientLeft || 0);
event.pageY = event.clientY +
(doc && doc.scrollTop || body && body.scrollTop || 0) -
(doc && doc.clientTop || body && body.clientTop || 0 );
}
if(maxX == 0){
maxX = event.pageX;
}
if(maxY == 0){
maxY = event.pageY;
}
if(event.pageX > maxX){
console.log("Right");
this.model.rotation.y = this.model.rotation.y + 0.08;
maxX = event.pageX;
}
else {
console.log("Left");
this.model.rotation.y = this.model.rotation.y - 0.08;
maxX = event.pageX;
}
if(event.pageY > maxY){
console.log("Up");
if(this.model.rotation.x < 0.32)
this.model.rotation.x = this.model.rotation.x + 0.08;
console.log(this.model.rotation.x);
maxY = event.pageY;
}
else {
console.log("Down");
if(this.model.rotation.x > -0.25)
this.model.rotation.x = this.model.rotation.x - 0.08;
console.log(this.model.rotation.x);
maxY = event.pageY;
}
});
}
Thanks!

You can have the desired behaviour by using a combination of
#mousemove, #mousedown, #mouseup
new Vue({
el: '#app',
data: {
captureToggle: false,
x: 0,
y: 0
},
methods: {
mo: function(evt) {
if (this.captureToggle) {
this.x = evt.x
this.y = evt.y
}
},
captureOn: function() {
this.captureToggle = true
},
captureOff: function() {
this.captureToggle = false
}
}
})
#app {
margin: 50px;
}
.mouseArea {
height: 100px;
width: 300px;
border: solid thin;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>
<div id="app">
<div class="mouseArea" #mousedown="captureOn" #mouseup="captureOff" #mousemove="mo"></div>
<div>x : {{x}}</div>
<div>y : {{y}}</div>
</div>

Related

Using pure javascript get the element visibility in viewport in percentage

I am trying to get the visibility of the element from viewport in percentage (number %).
Below is the code which I tired, but something is missing.
function calculateVisibilityForDiv(div$) {
var windowHeight = window.innerWidth ||
document.documentElement.clientWidth,
docScroll = window.scrollTop || document.body.scrollTop,
divPosition = div$.offsetTop,
divHeight = div$.offsetHeight || div$.clientHeight,
hiddenBefore = docScroll - divPosition,
hiddenAfter = (divPosition + divHeight) - (docScroll +
windowHeight);
if ((docScroll > divPosition + divHeight) || (divPosition > docScroll +
windowHeight)) {
return 0;
} else {
var result = 100;
if (hiddenBefore > 0) {
result -= (hiddenBefore * 100) / divHeight;
}
if (hiddenAfter > 0) {
result -= (hiddenAfter * 100) / divHeight;
}
return result;
}
}
var getOffset = function(elem) {
var box = { top: 0, left: 0 };
if(typeof elem.getBoundingClientRect !== "undefined") box =
elem.getBoundingClientRect();
return {
x: box.left + (window.pageXOffset || document.scrollLeft || 0) -
(document.clientLeft || 0),
y: box.top + (window.pageYOffset || document.scrollTop || 0) -
(document.clientTop || 0)
};
},
I am trying to get the DOM element visibility percentage from document viewport.
I've modified few lines to work code and it's working fine.
Check below fiddle
https://jsfiddle.net/darjiyogen/q16c1m7s/1/
'use strict';
var results = {};
function display() {
var resultString = '';
$.each(results, function(key) {
resultString += '(' + key + ': ' + Math.round(results[key]) + '%)';
});
$('p').text(resultString);
}
function calculateVisibilityForDiv(div$) {
debugger;
div$ = div$[0];
var windowHeight = window.innerHeight || document.documentElement.clientHeight,
docScroll = window.scrollTop || document.body.scrollTop,
divPosition = div$.offsetTop,
divHeight = div$.offsetHeight || div$.clientHeight,
hiddenBefore = docScroll - divPosition,
hiddenAfter = (divPosition + divHeight) - (docScroll + windowHeight);
if ((docScroll > divPosition + divHeight) || (divPosition > docScroll + windowHeight)) {
return 0;
} else {
var result = 100;
if (hiddenBefore > 0) {
result -= (hiddenBefore * 100) / divHeight;
}
if (hiddenAfter > 0) {
result -= (hiddenAfter * 100) / divHeight;
}
return result;
}
}
var getOffset = function(elem) {
var box = {
top: 0,
left: 0
};
if (typeof elem.getBoundingClientRect !== "undefined") box = elem.getBoundingClientRect();
return {
x: box.left + (window.pageXOffset || document.scrollLeft || 0) - (document.clientLeft || 0),
y: box.top + (window.pageYOffset || document.scrollTop || 0) - (document.clientTop || 0)
};
};
function calculateAndDisplayForAllDivs() {
$('div').each(function() {
var div$ = $(this);
results[div$.attr('id')] = calculateVisibilityForDiv(div$);
});
display();
}
$(document).scroll(function() {
calculateAndDisplayForAllDivs();
});
$(document).ready(function() {
calculateAndDisplayForAllDivs();
});
div {
height: 300px;
width: 300px;
border-width: 1px;
border-style: solid;
}
p {
position: fixed;
left: 320px;
top: 4px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="div1">div1</div>
<div id="div2">div2</div>
<div id="div3">div3</div>
<div id="div4">div4</div>
<p id="result"></p>

Horizontal scrolling of a div using mouse and touch

Let's say I have a white-space: nowrap; div with overflow: hidden;. Its content is, of course, much longer than the div is, and needs to be scrolled to get revealed.
I was using this library, but it does not work for mobile devices with touch input. Do you know any alternative or ways to implement this feature?
Finally, my wish is fullfilled. Here I modified dragscroll.js library to enable touch support.
/* Modified dragscroll.js by Undust4able */
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define(['exports'], factory);
} else if (typeof exports !== 'undefined') {
factory(exports);
} else {
factory((root.dragscroll = {}));
}
}(this, function (exports) {
var _window = window;
var _document = document;
var mousemove = 'mousemove';
var mouseup = 'mouseup';
var mousedown = 'mousedown';
var touchmove = 'touchmove';
var touchup = 'touchend';
var touchdown = 'touchstart';
var EventListener = 'EventListener';
var addEventListener = 'add'+EventListener;
var removeEventListener = 'remove'+EventListener;
var dragged = [];
var reset = function(i, el) {
for (i = 0; i < dragged.length;) {
el = dragged[i++];
el = el.container || el;
el[removeEventListener](mousedown, el.md, 0);
_window[removeEventListener](mouseup, el.mu, 0);
_window[removeEventListener](mousemove, el.mm, 0);
el[removeEventListener](touchdown, el.td, 0);
_window[removeEventListener](touchup, el.tu, 0);
_window[removeEventListener](touchmove, el.tm, 0);
}
// cloning into array since HTMLCollection is updated dynamically
dragged = [].slice.call(_document.getElementsByClassName('dragscroll'));
for (i = 0; i < dragged.length;) {
(function(el, lastClientX, lastClientY, pushed, scroller, cont){
(cont = el.container || el)[addEventListener](
mousedown,
cont.md = function(e) {
if (!el.hasAttribute('nochilddrag') ||
_document.elementFromPoint(
e.pageX, e.pageY
) == cont
) {
pushed = 1;
lastClientX = e.clientX;
lastClientY = e.clientY;
e.preventDefault();
}
}, 0
);
(cont = el.container || el)[addEventListener](
touchdown,
cont.td = function(e) {
if (!el.hasAttribute('nochilddrag') ||
_document.elementFromPoint(
e.pageX, e.pageY
) == cont
) {
pushed = 1;
e.preventDefault();
e = e.targetTouches[0];
lastClientX = e.clientX;
lastClientY = e.clientY;
}
}, 0
);
_window[addEventListener](
mouseup, cont.mu = function() {pushed = 0;}, 0
);
_window[addEventListener](
touchup, cont.tu = function() {pushed = 0;}, 0
);
_window[addEventListener](
mousemove,
cont.mm = function(e) {
if (pushed) {
(scroller = el.scroller||el).scrollLeft -=
(- lastClientX + (lastClientX=e.clientX));
scroller.scrollTop -=
(- lastClientY + (lastClientY=e.clientY));
}
}, 0
);
_window[addEventListener](
touchmove,
cont.tm = function(e) {
if (pushed) {
e = e.targetTouches[0];
(scroller = el.scroller||el).scrollLeft -=
(- lastClientX + (lastClientX=e.clientX));
scroller.scrollTop -=
(- lastClientY + (lastClientY=e.clientY));
}
}, 0
);
})(dragged[i++]);
}
}
if (_document.readyState == 'complete') {
reset();
} else {
_window[addEventListener]('load', reset, 0);
}
exports.reset = reset;
}));
Make a container div with overflow-y: hidden;overflow-x: scroll; and set it to whatever pre-determined height you want.
Then have your inner div that will house the content set to position:absolute; and set its width to whatever size you need the accommodate your content.
The content will scroll with the mouse and by touch.
Sounds kinda like you're going for a netflix style side scroller - check out this codepen I've done up that shows what I was just talking about.
http://codepen.io/hoonin_hooligan/pen/aZBxRG

Javascript | Creating a popup that triggers just before the page is closed

I have already created a popup overlay and currently have it set to when you click a button. However, I want it so that when you have initially scrolled down on the website and then go to move your cursor towards the top of the page (towards the navigation for example) then the popup window will appear.
Javascript
// Initialize Variables
var closePopup = document.getElementById("popupclose");
var overlay = document.getElementById("overlay");
var popup = document.getElementById("popup");
var button = document.getElementById("button");
// Close Popup Event
closePopup.onclick = function() {
overlay.style.display = 'none';
popup.style.display = 'none';
};
// Show Overlay and Popup
button.onclick = function() {
overlay.style.display = 'block';
popup.style.display = 'block';
}
I have created a JSFiddle with all my current code.
https://jsfiddle.net/1ud9crou/
With jQuery, you could do:
var isOnTop = false;
$(window).on('mousemove', function(e) {
mouseIsOnTop = e.pageY < 20;
if (mouseIsOnTop) {
button.onclick();
}
});
Otherwise, with bare Javascript (if you need IE support):
(function() {
document.onmousemove = handleMouseMove;
function handleMouseMove(event) {
var dot, eventDoc, doc, body, pageX, pageY;
event = event || window.event;
// if pageX/Y aren't available and clientX/Y are, calculate pageX/Y
if (event.pageX == null && event.clientX != null) {
eventDoc = (event.target && event.target.ownerDocument) || document;
doc = eventDoc.documentElement;
body = eventDoc.body;
event.pageX = event.clientX +
(doc && doc.scrollLeft || body && body.scrollLeft || 0) -
(doc && doc.clientLeft || body && body.clientLeft || 0);
event.pageY = event.clientY +
(doc && doc.scrollTop || body && body.scrollTop || 0) -
(doc && doc.clientTop || body && body.clientTop || 0 );
}
mouseIsOnTop = event.pageY < 20;
if (mouseIsOnTop) {
button.onclick();
}
}
})();
UPDATE: to detect if user scrolled from top:
var userDidScrollABit = false;
window.onscroll = function() {
var body = document.body;
var document = document.documentElement;
document = (document.clientHeight) ? document : body;
if (document.scrollTop > 20) {
userDidScrollABit = true;
}
};

Using fixPageXY(e) and onmousemove() and the image wont move?

Is there something im missing here? I just want to select the image by clicking on it, it should drag with the mouse(no mouse key held down) until its clicked onto I different part of the screen. Ive used function fixPageXY(e) with a onmousemove function, followed a tutorial and still nothing.
<script type="text/javascript">
function fixPageXY(e) {
if (e.pageX == null && e.clientX != null ) {
var html = document.documentElement;
var body = document.body;
e.pageX = e.clientX + (html.scrollLeft || body && body.scrollLeft || 0);
e.pageX -= html.clientLeft || 0;
e.pageY = e.clientY + (html.scrollTop || body && body.scrollTop || 0);
e.pageY -= html.clientTop || 0;
}
}
}
document.getElementById('ball').onmousedown = function() {
this.style.position = 'absolute';
var self = this;
document.onmousemove = function(e) {
e = e || event;
fixPageXY(e);
// put ball center under mouse pointer. 25 is half of width/height
self.style.left = e.pageX-25+'px';
self.style.top = e.pageY-25+'px';
}
this.onmouseup = function() {
document.onmousemove = null;
}
}
</script>
My image is simply,
<body onload="onmousemove();onmouseup();">
<img id="ball" src="ball.png" style="width:100px;height:100px;"/>
</body>
Im using google chrome, could this be an issue? many thanks for your help in advance.
There were a few syntax errors within your code, which if you are running Chrome you can just hit F12 on your keyboard and it will bring up the console allowing you to read whatever errors may be there. Here's a fiddle with just a few tweaks made to your code that allows it to run smoothly... and by tweaks, I mean there was an extra closing bracket after defining the function and the functions you called in body onload cannot me accessed that way so I deleted that and it worked.
This code work fine :
function fixPageXY(e) {
if(e.pageX == null && e.clientX != null ) {
var html = document.documentElement, body = document.body;
e.pageX = e.clientX + (html.scrollLeft || body && body.scrollLeft || 0);
e.pageX -= html.clientLeft || 0;
e.pageY = e.clientY + (html.scrollTop || body && body.scrollTop || 0);
e.pageY -= html.clientTop || 0;
}
}
document.getElementById("ball2").onmousedown = function () {
this.style.position = "absolute";
var self = this;
document.onmousemove = function (e) {
e = e || event;
fixPageXY (e);
self.style.left = e.pageX-25+'px';
self.style.top = e.pageY-25+'px';
}
this.onmouseup = function () {
document.onmousemove = null;
}
}
document.getElementById("ball2").ondragstart = function () { return false; }

Centering a DIV in viewport with JavaScript

I am trying to center a DIV in screen using below code but it is not working for me. Someone please suggest me to make it work
var hnw = {};
hnw.w = 0;
hnw.h = 0;
if (!window.innerWidth) {
if (!(document.documentElement.clientWidth == 0)) {
hnw.w = document.documentElement.clientWidth;
hnw.h = document.documentElement.clientHeight;
}
else {
hnw.w = document.body.clientWidth;
hnw.h = document.body.clientHeight;
}
}
else {
hnw.w = window.innerWidth;
hnw.h = window.innerHeight;
}
var midEle = document.createElement('div');
var _x = 0;
var _y = 0;
var offsetX = 0;
var offsetY = 0;
if (!window.pageYOffset) {
if (!(document.documentElement.scrollTop == 0)) {
offsetY = document.documentElement.scrollTop;
offsetX = document.documentElement.scrollLeft;
}
else {
offsetY = document.body.scrollTop;
offsetX = document.body.scrollLeft;
}
}
else {
offsetX = window.pageXOffset;
offsetY = window.pageYOffset;
}
midEle.style.width = "300px";
midEle.style.height = "300px";
midEle.innerHTML = "Some Text";
midEle.style.display = "block";
var _x_w = parseInt(midEle.style.width, 10), _y_h = parseInt(midEle.style.height, 10);
_x = ((hnw.w - _x_w) / 2) + offsetX;
_y = ((hnw.h - _y_h) / 2) + offsetY;
console.log(_x, " ", _y);
midEle.style.position = "absolute";
midEle.style.left = _x;
midEle.style.top = _y;
document.body.appendChild(midEle);
Can't this be done with CSS instead?
Javascript:
var midEle = document.createElement('div');
midEle.className = 'centered';
document.body.appendChild(midEle);
​CSS:
​.centered{
background-color: red;
height: 300px;
width: 300px;
margin: -150px 0 0 -150px;
top: 50%;
left: 50%;
position: fixed;
}​
http://jsfiddle.net/FkEyy/3/
By setting the margins to the negative half of the elements height and width, and setting top and left values to 50%, you'll center the element. This is a common way of centering content with CSS :)
For left and top style properties px was missing. Values must be either px or %
Change
midEle.style.left = _x;
midEle.style.top = _y;
To
midEle.style.left = _x+"px";
midEle.style.top = _y+"px";
Demo: http://jsfiddle.net/muthkum/AFkKt/
Here is a demo if you want to center something in the browser viewport using vanilla JavaScript.
http://jsfiddle.net/CDtGR/5/
<html>
<!--measure size of elements,
get absolute position of elements,
get viewport size and scrollposition-->
<script>
var mesr =
{
Metrics: {
px: 1,
measureUnits: function(target) {
if(typeof(target) == 'undefined')
target = document.getElementsByTagName('body')[0];
mesr.Metrics.measureUnit("em", target);
mesr.Metrics.measureUnit("pt", target);
mesr.Metrics.measureUnit("%", target);
},
measureUnit: function(unit, target) {
if(typeof(target.Metrics) == 'undefined')
target.Metrics = {};
var measureTarget = target;
if(target.tagName == 'IMG' && typeof(target.parentNode) != 'undefined')
measureTarget = target.parentNode;
var measureElement = document.createElement("div");
measureElement.style.width = "1"+unit;
measureElement.style.cssFloat = "left";
measureElement.style.styleFloat = "left";
measureElement.style.margin = "0px";
measureElement.style.padding = "0px";
measureTarget.appendChild(measureElement);
target.Metrics[unit] = measureElement.offsetWidth;
measureElement.parentNode.removeChild(measureElement);
return target.Metrics[unit];
},
getUnitPixels: function(unitString, target) {
if(typeof(target) == 'undefined')
target = document.getElementsByTagName('body')[0];
if(typeof(target.Metrics) == 'undefined')
mesr.Metrics.measureUnits(target);
var unit = unitString.replace(/[0-9\s]+/ig,'').toLowerCase();
var size = Number(unitString.replace(/[^0-9]+/ig,''));
if(typeof(target.Metrics[unit]) == 'undefined')
return 0;
var metricSize = target.Metrics[unit];
var pixels = Math.floor(Number(metricSize * size));
return pixels;
}
},
getElementOffset: function(target) {
var pos = [target.offsetLeft,target.offsetTop];
if(target.offsetParent != null) {
var offsetPos = mesr.getElementOffset(target.offsetParent);
pos = [
pos[0] + offsetPos[0],
pos[1] + offsetPos[1]
];
}
return pos;
},
getElementPosition: function(target) {
var offset = mesr.getElementOffset(target);
var x = offset[0] +
mesr.Metrics.getUnitPixels(target.style.paddingLeft, target) +
mesr.Metrics.getUnitPixels(target.style.borderLeftWidth, target);
var y = offset[1] +
mesr.Metrics.getUnitPixels(target.style.paddingTop, target) +
mesr.Metrics.getUnitPixels(target.style.borderTopWidth, target);
return [x,y];
},
getElementSize: function(target) {
var size = [target.offsetWidth, target.offsetHeight];
size[0] -= mesr.Metrics.getUnitPixels(target.style.paddingLeft, target) +
mesr.Metrics.getUnitPixels(target.style.paddingRight, target) +
mesr.Metrics.getUnitPixels(target.style.borderLeftWidth, target) +
mesr.Metrics.getUnitPixels(target.style.borderRightWidth, target);
size[1] -= mesr.Metrics.getUnitPixels(target.style.paddingTop, target) +
mesr.Metrics.getUnitPixels(target.style.paddingBottom, target) +
mesr.Metrics.getUnitPixels(target.style.borderTopWidth, target) +
mesr.Metrics.getUnitPixels(target.style.borderBottomWidth, target);
return size;
},
getViewPortSize: function () {
var myWidth = 0, myHeight = 0;
if( typeof( window.innerWidth ) == 'number' ) {
myWidth = window.innerWidth;
myHeight = window.innerHeight;
} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
myWidth = document.documentElement.clientWidth;
myHeight = document.documentElement.clientHeight;
} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
myWidth = document.body.clientWidth;
myHeight = document.body.clientHeight;
}
return [myWidth, myHeight];
},
getViewPortScrollPosition: function () {
var scrOfX = 0, scrOfY = 0;
if( typeof( window.pageYOffset ) == 'number' ) {
scrOfY = window.pageYOffset;
scrOfX = window.pageXOffset;
} else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
scrOfY = document.body.scrollTop;
scrOfX = document.body.scrollLeft;
} else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
scrOfY = document.documentElement.scrollTop;
scrOfX = document.documentElement.scrollLeft;
}
return [ scrOfX, scrOfY ];
},
attachEvent : function(target, eventList, func) {
if(typeof (target) == "undefined" || target == null)
return;
var events = eventList.split(",");
for(var i=0;i<events.length;i++) {
var event = events[i];
if(typeof(target.addEventListener) != 'undefined') {
target.addEventListener(event, func);
} else if(typeof(target.attachEvent) != 'undefined') {
target.attachEvent('on'+event,func);
} else {
console.log("unable to attach event listener");
}
}
}
}
</script>
<!--positioning-->
<script>
function position(){
var viewPortSize = mesr.getViewPortSize();
var viewPortScrollPos = mesr.getViewPortScrollPosition();
var size = mesr.getElementSize(document.getElementById('apa'));
document.getElementById('apa').style.left = Math.floor((viewPortSize[0]/2)-(size[0]/2)+viewPortScrollPos[0])+"px";
document.getElementById('apa').style.top = Math.floor((viewPortSize[1]/2)-(size[1]/2)+viewPortScrollPos[1])+"px";
}
mesr.attachEvent(window,"resize,scroll,load",position);
mesr.attachEvent(document,"load",position);
</script>
<body>
<div id="apa" style="position:absolute;">some text</div>
</body>
</html>

Categories

Resources