I'm trying to make a draggable div.
Javascript code Snippet:
document.getElementById('mySidenav').addEventListener('touchmove',
function(event) {
event.preventDefault();
clickX = event.touches[event.touches[0].identifier].pageX;
if(navigationOpen){
//draggable.style.width = Math.floor(clickX) + 'px';
document.getElementById('mySidenav').setAttribute("style","width:"+ clickX + "px");
}
}, false);
Now there are 2 problems:
1) The drag doesn't work until I stop moving (not necessarily ending touch)
2) There's also a bit of lag when the <div> is moving.
I check to see the movement by outputing my clickX and it works fine under 30fps
Am I doing something wrong? Is there a way to do this?
UPDATE:
I'm running this program in Cordova on Android
You didn't paste your HTML so here's just a quick example of a draggable div which works really well on touch devices.
var nodeList = document.getElementsByClassName('dragme');
for (var i = 0; i < nodeList.length; i++) {
var obj = nodeList[i];
obj.addEventListener('touchmove', function(event) {
var touch = event.targetTouches[0];
event.target.style.left = touch.pageX + 'px';
event.target.style.top = touch.pageY + 'px';
event.preventDefault();
}, false);
}
.dragme {
width: 50px;
height: 50px;
position: absolute;
background-color: grey;
border: 2px solid black;
}
<div class="dragme"></div>
There is no mouse events here so it will only work on touch but hopefully this example can be useful to you.
Fiddle to play around with: https://jsfiddle.net/thepio/fjmn0pej/
Thank you guys for the help. For some reason the solution was to delete code from CSS
.sideNav {
...
...
transition: 0.5s; /* This */
}
But now there is no fluent animation when the sideNav is closing/opening :(
Related
I want to display the div wherever the cursor is holding right click.
in my case i have this code
<div class="d-none" id="item"></div>
#item{
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
background: royalblue;
/* transform: translate(calc(287px - 50%), calc(77px - 50%)); */
}
.d-none{
display: none;
}
var myMouseX, myMouseY;
function getXYPosition(e) {
myMouseX = (e || event).clientX;
myMouseY = (e || event).clientY;
getPosition(myMouseX, myMouseY);
function getPosition(x, y) {
console.log('X = ' + x + '; Y = ' + y);
let div = document.querySelector("#item");
if (div.classList.contains('d-none')) {
div.classList.remove('d-none');
} else {
div.classList.add('d-none');
}
divX = x + "px";
divY = y + "px";
div.style.transform = `translate(calc(`+divX+` - 50%) , calc(`+divY+` - 50%))`;
}
}
window.addEventListener('click', function () {
getXYPosition()
})
or you can see my Fiddle
Its work on left click by default using window.addEventListener('click')
so how do i change from left click to holding right click a few seconds
The MouseEvent API (with its mousedown and mouseup events) lets us check the event.button property to learn which mouse button the user is activating. And we can keep track of how much time passes between mousedown and mouseup to decide what to do when the mouse button is released, such as running a custom showOrHideDiv function.
And the contextmenu event fires after a right-click (unless the relevant context menu is already visible, I guess.) We can suppress the default contextmenu behavior if necessary -- although this power should be used sparingly if at all.
Note that the technique used here is problematic in that it assumes the user will never use their keyboard to see the context menu, which will eventually cause accessibility snafus and other unpleasant surprises for users. This is why hijacking the default right-click behavior should be avoided if possible (maybe in favor of something like Shift + right-click) unless the user explictly opts in to the new behavior.
// Defines constants and adds main (`mousedown`) listener
const
div = document.querySelector("#item"),
RIGHT = 2,
DELAY = 150;
document.addEventListener('mousedown', forceDelay);
// Main listener sets subsequent listeners
function forceDelay(event){
// Right mouse button must be down to proceed
if(event.button != RIGHT){ return; }
// Enables contextmenu and disables custom response
document.removeEventListener('contextmenu', suppressContextMenu);
document.removeEventListener('mouseup', showOrHideDiv);
// After 150ms, disables contextmenu and enables custom response
setTimeout(
function(){
document.addEventListener('contextmenu', suppressContextMenu);
document.addEventListener('mouseup', showOrHideDiv);
},
DELAY
);
}
// The `contextmenu` event listener
function suppressContextMenu(event){
event.preventDefault();
}
// The `mouseup` event listener
function showOrHideDiv(event){
if(event.button != RIGHT){ return; }
const
x = event.clientX,
y = event.clientY;
div.classList.toggle('d-none'); // classList API includes `toggle`
div.style.transform = `translate(calc(${x}px - 50%), calc(${y}px - 50%))`;
}
#item{ position: absolute; top: 0; left: 0; width: 100px; height: 100px; background: royalblue; }
.d-none{ display: none; }
<div id="item" class="d-none"></div>
EDIT
Note: The script works properly when tested in a standalone HTML file using Chrome, but (at least with my laptop's touchpad) behaves strangely when run here in a Stack Overflow snippet. If you experience similar issues, you can paste it into a <script> element in an HTML file (with the CSS in a <style> element) to see it working.
Somewhere between a month ago and now, chrome seems to be incorrectly rendering a video after a translation (or maybe after frequent translations).
My chrome is version: Version 78.0.3904.97 (Official Build) (64-bit).
My OS: MacOS Catalina 10.15, however the problem also occurs on Windows.
If the actual translating is done with a library, such as velocityjs, the problem still occurs.
Below is an example that does not work properly for me. The video moves (sometimes), however other times the video gets stuck and does not move anymore. When this happens the actual element is moved and I see the cursor pointer where the video is supposed to be rendered. I can also re-drag it from there but the video is still playing somewhere else on the screen where it isn't supposed to be. Notably; the video does seem to translate/update properly if part of the video is outside of the window (either bottom or right in this example)
Steps to reproduce:
For a better experience move the snippet to fullscreen so you have more area to drag.
Click and hold the playing video.
Drag the video around in circles a bit. Doesn't need to be fast.
Drop the video by not holding the click anymore.
During the dragging you should of seen the video not following your mouse movement and the video should now be rendered at a completely different place than where you dropped it. The actual video element is in the right spot though.
console.clear();
let dragging = false;
let dragStartX = 0;
let dragStartY = 0;
const root = document.getElementById('root');
const container = document.getElementById('container');
const video = document.getElementById('video');
function onMouseDown(e) {
if (!dragging) {
dragging = true;
}
}
function onMouseMove(e) {
if (dragging) {
const diffX = (e.clientX - dragStartX);
const diffY = (e.clientY - dragStartY);
container.style.transform = 'translate(' + diffX + 'px,' + diffY + 'px)'
}
}
function onMouseUp(e) {
if (dragging) {
dragging = false;
}
}
#video {
display: flex;
max-height: 200px;
max-width: 360px;
pointer-events: none;
}
#container {
display: flex;
background-color: '#FA0050';
position: absolute;
top: 0;
left: 0;
width: fit-content;
height: fit-content;
cursor: pointer;
}
<div id='root' style='width: 100%; height: 100vh'onMouseMove='onMouseMove(event)' onMouseUp='onMouseUp(event)'>
<div
id='container'
onMouseDown='onMouseDown(event)'
>
<video
id='video'
autoplay
muted
loop
controls
src='https://s3.amazonaws.com/codecademy-content/courses/React/react_video-cute.mp4'
/>
</div>
</div>
Any help/ideas?
This now appears to be have been fixed somewhere between the question version and Chrome Version 79.0.3945.88 (Official Build) (64-bit).
I want to try the same effect of this site but am getting lost in action on how to implement this animation.
When the user starts scrolling, the images in the header zoom in, the scrolling tab(vertical) does not move, up to a point which another image shows up, and only afterward the scroll bar starts working.
How can I achieve this animation when scrolling?
At the moment, what I thought was: to get the pixel value of the DOM when am scrolling, as well as the height of the div I want to target.
While the value of the DOM is less than the height of the box, the scale value should change based on the scrolling value.
The JS looks like this:
<script>
$(window).scroll(function() {
var initial_scroll = $('html').scrollTop();
var firstbox_height = $('#firstbox').height();
// console.log(firstbox_height);
while(initial_scroll < firstbox_height){
var sum = firstbox_height + ((firstbox_height * 0.01) / 100);
$('img').css({
// "transform": "scale(" + sum + ")"
});
}
});
</script>
I seem to be going into an infinite loop.
My pen is here
Here's a working sample. It's not flawless, it bugs when you scroll just a little back and forth at the top, the text size might change in the wrong direction. Also it doesn't work when scrolling with arrow keys. But what it does is that it should give you the idea on how to proceed.
There's probably a cleaner, nicer and more concise way to do this, but this is one way.
To get a perfectly working one, I think you might have to place a transparent <div> over the one that changes, just to keep track of the position and hence the direction.
Fiddle here: https://jsfiddle.net/codesam/nedj3ubx/53/
HTML:
<body>
<div id="box">
Text
</div>
<p id="direction">
</p>
</body>
CSS:
body {
height: 200vh;
}
#box {
width: 100%;
height: 50vh;
background-color: black;
color: white;
font-size: 72px;
}
jQuery:
$(document).ready(function(){
var initialScroll = -1;
var size;
$(window).on('scroll touchmove mousewheel', function(e){
var currentScroll = $(window).scrollTop();
if (currentScroll > initialScroll) {
$("#direction").text("down");
size = parseInt($("#box").css("font-size"));
if (size > 10) {
$("#box").css("font-size", "-=2");
e.preventDefault();
e.stopPropagation();
return false;
}
}
else if (currentScroll < initialScroll) {
$("#direction").text("up");
}
else if (currentScroll == 0 && initialScroll == 0) {
size = parseInt($("#box").css("font-size"));
if (size < 72) {
$("#box").css("font-size", "+=2");
e.preventDefault();
e.stopPropagation();
return false;
}
}
initialScroll = currentScroll;
});
});
Basically I want to split a square div diagonally in two resulting in two triangles.
Each triangle has to respond to the hover event.
This is what I have so far but the problem is: if you go from one corner of the div straight to the opposite corner it doesn't re-trigger the hover event since the event is applied to the div element and not the define triangle area within.
I'm open to any suggestions, I don't even mind if I need to approach the problem from a different angle all together. There's got to be an easier solution, at least I hope!
The HTML
<div class="day_box">
</div>
The CSS
html, body { margin: 0; }
.day_box, .upper_left_hover, .lower_right_hover, .full_day {
background: url(/images/corner-sprites.png);
border: 1px solid black;
width: 25px;
height: 25px;
float: left;
margin: 100px;
}
.upper_left_hover { background-position: 75px 0; }
.lower_right_hover { background-position: 50px 0; }
.full_day { background-position: 25px 0; }
The JS
$(".day_box").hover(function(event){
var offset = $(this).offset();
var h = $(this).height() + offset.top;
if((h - event.pageY)>(event.pageX - offset.left)) {
console.log("Upper left");
$(this).toggleClass("upper_left_hover");
} else {
console.log("Lower right");
$(this).toggleClass("lower_right_hover");
}
});
The Fiddle: http://jsfiddle.net/zsay6/
You can use the mousemove event like this (adding mouseout to remove both of the classes when you leave the square):
$(".day_box").mousemove(function(event){
var offset = $(this).offset();
var h = $(this).height() + offset.top;
if((h - event.pageY)>(event.pageX - offset.left)) {
console.log("Upper left");
$(this).removeClass("lower_right_hover");
$(this).addClass("upper_left_hover");
} else if ((h - event.pageY)<(event.pageX - offset.left)) {
console.log("Lower right");
$(this).removeClass("upper_left_hover");
$(this).addClass("lower_right_hover");
}
}).mouseout(function(event)
{
$(this).removeClass("lower_right_hover upper_left_hover");
});
http://jsfiddle.net/zsay6/14/
I altered your fiddle to produce the effect you wanted... and I didn't clean it up at all (was just fiddling... haha)
Using the right-triangle formula (here), I set the given style you set up in your original fiddle. It also throws up some values in a debugging div so you can see it in action a little more clearly.
You can also use HTML map areas for that purpose:
http://www.w3schools.com/tags/tag_map.asp
On hover, change the background of the element to which the usemap is applied.
I want to create some kind of "drawing" inside an ordinary div (no canvas!). I am using the onmousemove event to trace the position of the mouse. The following code demonstrates my current situation:
CSS Rules:
#outer { width: 400px; border: 1px solid #000000; }
#inner { width: 100%; height: 20px; background: green; }
Actual JavaScript/HTML part:
var is_drawing = false;
function startdraw() {
is_drawing = true;
var div = document.getElementById("inner");
div.setAttribute("style", "cursor: crosshair");
}
function stopdraw() {
is_drawing = false;
var div = document.getElementById("inner");
div.setAttribute("style", "cursor: auto");
}
function dodraw(e) {
if (!e) {
e = window.event;
} else if (!is_drawing) {
return;
}
// Some more code to be added later
var deb = document.getElementById("deb");
deb.innerHTML = "coords -- x(" + String(e.clientX) + ") y(" + String(e.clientY) + ")";
}
</script>
<div id="outer">
<div id="inner" onmousedown="startdraw()" onmouseup="stopdraw()" onmousemove="dodraw(event)"></div>
</div>
What is expected and the actual result?
When clicking the inner div and moving the mouse while holding the mouse button, the cursor should be constantly being "crosshair". This also works perfectly with IE9(RC), and partly with Firefox 3.6 - in Firefox, this only works when loading the site and clicking the first time into the inner div. When releasing the button and clicking and moving again, the "not allowed" cursor is shown and the CSS cursor attribute has no effect at all. On Google Chrome the cursor is not even changed (having constantly an input-cursor there).
Which choices I do have? Any advice is welcome.
The only thing I can help you with is about Chrome: set onselectstart = "return false": http://jsfiddle.net/F2mCS/2/.