Opacity when moving div NOT on mouse down JavaScript - javascript

I have set an opacity to a draggable div, but the problem is that i don't want to add the opacity on mouse down, only when I start move the div.
Should be connected to the X and Y but i really don't get how to.
This is what i have.
function startDrag(evt) { // To start the opacity function
this.style.opacity = "0.5";
}
And to stop in och mouse up
function changeClass() {
var diceClass = document.getElementsByClassName("draggble");
for (var i = 0; i < diceClass.length; i++) {
diceClass[i].style.opacity="1";
}
}
jsFiddle
http://jsfiddle.net/dymond/tQdFZ/6/

I moved this.style.opacity = "0.5"; from startDrag function to moveAlong function.
Demo
(function (document) {
var draggable = document.getElementsByClassName('draggable'),
draggableCount = draggable.length,
i, currZ = 1;
function startDrag(evt) {
var diffX = evt.clientX - this.offsetLeft,
diffY = evt.clientY - this.offsetTop,
that = this;
this.style.zIndex = currZ++;
function moveAlong(evt) {
that.style.left = (evt.clientX - diffX) + 'px';
that.style.top = (evt.clientY - diffY) + 'px';
that.style.opacity = "0.5";
}
function stopDrag() {
document.removeEventListener('mousemove', moveAlong);
document.removeEventListener('mouseup', stopDrag);
changeClass()
}
function changeClass() {
var diceClass = document.getElementsByClassName("draggable");
for (var i = 0; i < diceClass.length; i++) {
diceClass[i].style.opacity = "1";
}
}
document.addEventListener('mouseup', stopDrag);
document.addEventListener('mousemove', moveAlong);
}
for (i = 0; i < draggableCount; i += 1) {
draggable[i].addEventListener('mousedown', startDrag);
}
}(document));

Related

How to add fade onclick event to specific particle (data object) within canvas system?

I want to click on one of the floating particles, upon clicking it, I want the particle colour to change from light grey to blue and then fade. Particle quantity is set as 100, as particles are clicked on to fade away particle quantity decreases. I'm unfamiliar with js, just started learning about canvas and particle systems yesterday, this is code from a pen that I've changed a bit and would like to add more changes to by adding the fade onclick event. I know that the particles within canvas are under one variable that defines them altogether, I don't know how to isolate one particle in the canvas to work with as I would need to know it's exact x,y coordinates.
Would I then have to find the coordinates for all 100 particles and add elements to each individual particle- and how do I do this?
$(document).ready(function() {
var PARTICLE_QUANT = 100;
var FPS = 60;
var BOUNCE = -1;
var PARTICLE_COLOR = '#ced4d4';
var ARC_RADIUS = 12;
var Particles = function($element) {
if ($element.length === 0) {
return;
}
this.$element = $element;
this.lastTimeStamp = null;
this.particles = [];
this.init();
};
var proto = Particles.prototype;
proto.init = function() {
this.createChildren()
.layout()
.enable();
};
proto.createChildren = function() {
this.canvas = this.$element[0];
this.context = this.canvas.getContext('2d');
this.canvasWidth = this.canvas.width;
this.canvasHeight = this.canvas.height;
this.lastTimeStamp = new Date().getTime();
return this;
};
proto.layout = function() {
window.requestAnimFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame;
})();
return this;
};
proto.removeChildren = function() {
this.context = null;
this.canvasWidth = null;
this.canvasHeight = null;
this.lastTimeStamp = null;
return this;
};
proto.enable = function() {
this.createParticleData();
this.renderLoop();
};
proto.createParticleData = function() {
var i = 0;
var l = PARTICLE_QUANT;
for (; i < l; i++) {
this.particles[i] = {};
this.setParticleData(this.particles[i]);
}
};
proto.setParticleData = function(particle) {
particle.x = Math.random() * this.canvasWidth;
particle.y = Math.random() * this.canvasHeight;
particle.vx = (Math.random()) - 0.5;
particle.vy = (Math.random()) - 0.5;
};
proto.update = function() {
var i = 0;
var l = PARTICLE_QUANT;
for (; i < l; i++) {
var particle = this.particles[i];
particle.x += particle.vx;
particle.y += particle.vy;
if (particle.x > this.canvasWidth) {
particle.x = this.canvasWidth;
particle.vx *= BOUNCE;
} else if (particle.x < 0) {
particle.x = 0;
particle.vx *= BOUNCE;
}
if (particle.y > this.canvasHeight) {
particle.y = this.canvasHeight;
particle.vy *= BOUNCE;
} else if (particle.y < 0) {
particle.y = 0;
particle.vy *= BOUNCE;
}
}
};
proto.draw = function() {
var i = 0;
if (!this.context) {
return;
}
this.context.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
this.context.fillStyle = PARTICLE_COLOR;
for (; i < PARTICLE_QUANT; i++) {
var particle = this.particles[i];
this.context.save();
this.context.beginPath();
this.context.arc(particle.x, particle.y, ARC_RADIUS, 0, Math.PI * 2);
this.context.fill();
this.context.restore();
}
};
proto.renderLoop = function() {
requestAnimationFrame(this.renderLoop.bind(this));
this.update();
this.draw();
};
var particles = new Particles($('#js-particles'));
//Everything above works, it is what comes next (below), is this the right approach?
var elem = document.getElementById('js-particles'),
elemLeft = elem.offsetLeft,
elemTop = elem.offsetTop,
context = elem.getContext('2d'),
elements = [];
// Add event listener for `click` events.
elem.addEventListener('click', function(event) {
var x = event.pageX - elemLeft,
y = event.pageY - elemTop;
// Collision detection between clicked offset and element.
elements.forEach(function(element) {
if (y > element.top && y < element.top + element.height && x > element.left && x < element.left + element.width)
});
}, false);
// Add element.
elements.push({
colour: '#05EFFF',
width: 150,
height: 100,
top: 20,
left: 15
});
// Render elements.
elements.forEach(function(element) {
context.fillStyle = element.colour;
context.fillRect(element.left, element.top, element.width, element.height);
});
<canvas id="js-particles" class="particles" width="960" height="960">
<p>text appears if browser doesn 't support canvas</p>
</canvas>

Can't drop element after the drag

I'm new in JS and trying to make simple interface with pure JS, where User can dynamically add elements and move them around.
I found solutions for create elements and drag'n'drop elements, that perfectly works separatly. But when I tried to unite them, drop function stop working...
What am I doing wrong?
Template:
<head>
<title>Int Demo</title>
<script src='js/script.js'></script>
<style type="text/css">
.wrapper {width: 300px; height: 200px; background: #A3A1A1;}
.textblock {cursor: pointer; background: red;}
</style>
</head>
<body>
<div class="button" id="button">Add Textbox</div>
<div class="wrapper" id="wrapper"></div>
</body>
</html>
My JS file:
document.addEventListener("DOMContentLoaded", function() { init(); }, false);
function init() {
button = document.getElementById('button');
wrapper = document.getElementById('wrapper');
button.addEventListener('click', btnClick, false);
wrapper.ondblclick = catchIt;
}
//add element
function btnClick() {
wrapper.innerHTML += '<p class="draggable textblock">Text Here!</p>';
sessionStorage.inputBoxes = wrapper;
console.log(sessionStorage);
}
// Activate Drag'n'Drop
document.onmousedown = function(e) {
var dragElement = e.target;
if (!dragElement.classList.contains('draggable')) return;
var coords, shiftX, shiftY;
startDrag(e.clientX, e.clientY);
document.onmousemove = function(e) {
moveAt(e.clientX, e.clientY);
};
dragElement.onmouseup = function() {
finishDrag();
};
function startDrag(clientX, clientY) {
shiftX = clientX - dragElement.getBoundingClientRect().left;
shiftY = clientY - dragElement.getBoundingClientRect().top;
dragElement.style.position = 'fixed';
document.body.appendChild(dragElement);
moveAt(clientX, clientY);
};
function finishDrag() {
dragElement.style.top = parseInt(dragElement.style.top) + pageYOffset + 'px';
dragElement.style.position = 'absolute';
document.onmousemove = null;
dragElement.onmouseup = null;
}
function moveAt(clientX, clientY) {
var newX = clientX - shiftX;
var newY = clientY - shiftY;
// bottom offset
var newBottom = newY + dragElement.offsetHeight;
if (newBottom > document.documentElement.clientHeight) {
var docBottom = document.documentElement.getBoundingClientRect().bottom;
var scrollY = Math.min(docBottom - newBottom, 10);
if (scrollY < 0) scrollY = 0;
window.scrollBy(0, scrollY);
newY = Math.min(newY, document.documentElement.clientHeight - dragElement.offsetHeight);
}
// top offset
if (newY < 0) {
var scrollY = Math.min(-newY, 10);
if (scrollY < 0) scrollY = 0;
window.scrollBy(0, -scrollY);
newY = Math.max(newY, 0);
}
if (newX < 0) newX = 0;
if (newX > document.documentElement.clientWidth - dragElement.offsetHeight) {
newX = document.documentElement.clientWidth - dragElement.offsetHeight;
}
dragElement.style.left = newX + 'px';
dragElement.style.top = newY + 'px';
}
return false;
}
I changed
dragElement.onmouseup = function() {
finishDrag();
};
into
document.onmouseup = function() {
finishDrag();
};
and it started working for me. This does mean that the end user will have to keep the mouse button pressed down to continue dragging and that the element will be placed immediately on mouse button up. But I'm assuming that this is the desired functionality, or do you want the drop to happen only on a second mouse click?

Return false/ clear timeout is not walking for scroll animation

The last div at the bottom of the site locks to the bottom of the page and will not let me scroll back up without refreshing. The clear timeout is not working.
What do I need to change to resolve this issue?
Here is my js:
function autoScrollTo(el){
var sliderPx = document.getElementById('nav').style.top;
var sliderPos = sliderPx;
var targetPos = document.getElementById(el).offsetTop;
if(sliderPos < targetPos){
scrollDown(el);
} else {
scrollUp(el)
}
}
var scrollAmount = 0;
var distance = 38;
var speed = 16;
function scrollDown(el){
var offsetY = window.pageYOffset;
var targetY = document.getElementById(el).offsetTop;
var timeLooper = setTimeout ('scrollDown(\''+el+'\')', speed);
if(offsetY < targetY){
scrollAmount = offsetY+distance;
window.scroll(0, scrollAmount);
} else {
clearTimeout(timeLooper);
}
}
function scrollUp(el){
var currentY = window.pageYOffset;
var targetY = document.getElementById(el).offsetTop;
var looper = setTimeout ('scrollUp(\''+el+'\')', speed);
if(currentY > targetY){
scrollY = currentY-distance;
window.scroll(0, scrollY);
} else {
clearTimeout(looper);
}
}
Here is my HTML:
<div id="nav">
<ul>
<li>SERVICES</li>
<li>CONTACT</li>
</ul>
<div class="clearFix"></div>
</div><!--/nav-->
To be honest, you should rethink your solution, work with JQuery (animate), and change the scrolling logic, however I changed some things, and added a flag, which catches your infinite scrolling...just a quick workaround, but seriously, start over, or you will not have a decent cross-browser scrolling solution!
function autoScrollTo(el){
console.log(el);
var scrollPos = document.documentElement.scrollTop;
var targetPos = document.getElementById(el).offsetTop;
console.log(scrollPos + "," + targetPos);
if(scrollPos < targetPos){
scrollDown(el);
} else {
scrollUp(el)
}
}
var scrollAmount = 0;
var distance = 38;
var speed = 16;
var lastPosition;
function scrollDown(el){
var offsetY = document.documentElement.scrollTop;
var targetY = document.getElementById(el).offsetTop;
var timeLooper = setTimeout ('scrollDown(\''+el+'\')', speed);
if(offsetY < targetY && lastPosition != offsetY){
console.log(offsetY + "," + targetY);
scrollAmount = offsetY+distance;
window.scroll(0, scrollAmount);
} else {
console.log("end down");
clearTimeout(timeLooper);
}
lastPosition = offsetY;
}
function scrollUp(el){
var currentY = document.documentElement.scrollTop;
var targetY = document.getElementById(el).offsetTop;
var looper = setTimeout ('scrollUp(\''+el+'\')', speed);
if(currentY > targetY && lastPosition != currentY){
scrollY = currentY-distance;
window.scroll(0, scrollY);
} else {
console.log("end up");
clearTimeout(looper);
}
lastPosition = currentY;
}

Simple drag and drop code

Im struggling with seemingly a simple javascript exercise, writing a vanilla drag and drop. I think Im making a mistake with my 'addeventlisteners', here is the code:
var ele = document.getElementsByClassName ("target")[0];
var stateMouseDown = false;
//ele.onmousedown = eleMouseDown;
ele.addEventListener ("onmousedown" , eleMouseDown , false);
function eleMouseDown () {
stateMouseDown = true;
document.addEventListener ("onmousemove" , eleMouseMove , false);
}
function eleMouseMove (ev) {
do {
var pX = ev.pageX;
var pY = ev.pageY;
ele.style.left = pX + "px";
ele.style.top = pY + "px";
document.addEventListener ("onmouseup" , eleMouseUp , false);
} while (stateMouseDown === true);
}
function eleMouseUp () {
stateMouseDown = false;
document.removeEventListener ("onmousemove" , eleMouseMove , false);
document.removeEventListener ("onmouseup" , eleMouseUp , false);
}
Here's a jsfiddle with it working: http://jsfiddle.net/fpb7j/1/
There were 2 main issues, first being the use of onmousedown, onmousemove and onmouseup. I believe those are only to be used with attached events:
document.body.attachEvent('onmousemove',drag);
while mousedown, mousemove and mouseup are for event listeners:
document.body.addEventListener('mousemove',drag);
The second issue was the do-while loop in the move event function. That function's being called every time the mouse moves a pixel, so the loop isn't needed:
var ele = document.getElementsByClassName ("target")[0];
ele.addEventListener ("mousedown" , eleMouseDown , false);
function eleMouseDown () {
stateMouseDown = true;
document.addEventListener ("mousemove" , eleMouseMove , false);
}
function eleMouseMove (ev) {
var pX = ev.pageX;
var pY = ev.pageY;
ele.style.left = pX + "px";
ele.style.top = pY + "px";
document.addEventListener ("mouseup" , eleMouseUp , false);
}
function eleMouseUp () {
document.removeEventListener ("mousemove" , eleMouseMove , false);
document.removeEventListener ("mouseup" , eleMouseUp , false);
}
By the way, I had to make the target's position absolute for it to work.
you can try this fiddle too, http://jsfiddle.net/dennisbot/4AH5Z/
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>titulo de mi pagina</title>
<style>
#target {
width: 100px;
height: 100px;
background-color: #ffc;
border: 2px solid blue;
position: absolute;
}
</style>
<script>
window.onload = function() {
var el = document.getElementById('target');
var mover = false, x, y, posx, posy, first = true;
el.onmousedown = function() {
mover = true;
};
el.onmouseup = function() {
mover = false;
first = true;
};
el.onmousemove = function(e) {
if (mover) {
if (first) {
x = e.offsetX;
y = e.offsetY;
first = false;
}
posx = e.pageX - x;
posy = e.pageY - y;
this.style.left = posx + 'px';
this.style.top = posy + 'px';
}
};
}
</script>
</head>
<body>
<div id="target" style="left: 10px; top:20px"></div>
</body>
</html>
I've just made a simple drag.
It's a one liner usage, and it handles things like the offset of the mouse to the top left corner of the element, onDrag/onStop callbacks, and SVG elements dragging
Here is the code.
// simple drag
function sdrag(onDrag, onStop) {
var startX = 0;
var startY = 0;
var el = this;
var dragging = false;
function move(e) {
el.style.left = (e.pageX - startX ) + 'px';
el.style.top = (e.pageY - startY ) + 'px';
onDrag && onDrag(el, e.pageX, startX, e.pageY, startY);
}
function startDragging(e) {
if (e.currentTarget instanceof HTMLElement || e.currentTarget instanceof SVGElement) {
dragging = true;
var left = el.style.left ? parseInt(el.style.left) : 0;
var top = el.style.top ? parseInt(el.style.top) : 0;
startX = e.pageX - left;
startY = e.pageY - top;
window.addEventListener('mousemove', move);
}
else {
throw new Error("Your target must be an html element");
}
}
this.addEventListener('mousedown', startDragging);
window.addEventListener('mouseup', function (e) {
if (true === dragging) {
dragging = false;
window.removeEventListener('mousemove', move);
onStop && onStop(el, e.pageX, startX, e.pageY, startY);
}
});
}
Element.prototype.sdrag = sdrag;
and to use it:
document.getElementById('my_target').sdrag();
You can also use onDrag and onStop callbacks:
document.getElementById('my_target').sdrag(onDrag, onStop);
Check my repo here for more details:
https://github.com/lingtalfi/simpledrag
this is how I do it
var MOVE = {
startX: undefined,
startY: undefined,
item: null
};
function contentDiv(color, width, height) {
var result = document.createElement('div');
result.style.width = width + 'px';
result.style.height = height + 'px';
result.style.backgroundColor = color;
return result;
}
function movable(content) {
var outer = document.createElement('div');
var inner = document.createElement('div');
outer.style.position = 'relative';
inner.style.position = 'relative';
inner.style.cursor = 'move';
inner.style.zIndex = 1000;
outer.appendChild(inner);
inner.appendChild(content);
inner.addEventListener('mousedown', function(evt) {
MOVE.item = this;
MOVE.startX = evt.pageX;
MOVE.startY = evt.pageY;
})
return outer;
}
function bodyOnload() {
document.getElementById('td1').appendChild(movable(contentDiv('blue', 100, 100)));
document.getElementById('td2').appendChild(movable(contentDiv('red', 100, 100)));
document.addEventListener('mousemove', function(evt) {
if (!MOVE.item) return;
if (evt.which!==1){ return; }
var dx = evt.pageX - MOVE.startX;
var dy = evt.pageY - MOVE.startY;
MOVE.item.parentElement.style.left = dx + 'px';
MOVE.item.parentElement.style.top = dy + 'px';
});
document.addEventListener('mouseup', function(evt) {
if (!MOVE.item) return;
var dx = evt.pageX - MOVE.startX;
var dy = evt.pageY - MOVE.startY;
var sty = MOVE.item.style;
sty.left = (parseFloat(sty.left) || 0) + dx + 'px';
sty.top = (parseFloat(sty.top) || 0) + dy + 'px';
MOVE.item.parentElement.style.left = '';
MOVE.item.parentElement.style.top = '';
MOVE.item = null;
MOVE.startX = undefined;
MOVE.startY = undefined;
});
}
bodyOnload();
table {
user-select: none
}
<table>
<tr>
<td id='td1'></td>
<td id='td2'></td>
</tr>
</table>
While dragging, the left and right of the style of the parentElement of the dragged element are continuously updated. Then, on mouseup (='drop'), "the changes are committed", so to speak; we add the (horizontal and vertical) position changes (i.e., left and top) of the parent to the position of the element itself, and we clear left/top of the parent again. This way, we only need JavaScript variables for pageX, pageY (mouse position at drag start), while concerning the element position at drag start, we don't need JavaScript variables for that (just keeping that information in the DOM).
If you're dealing with SVG elements, you can use the same parent/child/commit technique. Just use two nested g, and use transform=translate(dx,dy) instead of style.left=dx, style.top=dy

Div does not follow drag-bar when moving

Im trying to add a drag handle to an div , but the div doesn't move, just the handel.
But if I change the position to position absolute to the div that are supposed to move, I can actually move around the div, but from everywhere and not just the drag handle.
Any tips ? I created a jsfiddle for this.
http://jsfiddle.net/dymond/tQdFZ/11/
Some code.
var draggable = document.getElementsByClassName('hand'),
draggableCount = draggable.length,
i, currZ = 1;
function startDrag(evt) {
var diffX = evt.clientX - this.offsetLeft,
diffY = evt.clientY - this.offsetTop,
that = this;
this.style.opacity = "0.5";
this.style.zIndex = currZ++;
function moveAlong(evt) {
that.style.left = (evt.clientX - diffX) + 'px';
that.style.top = (evt.clientY - diffY) + 'px';
}
function stopDrag() {
document.removeEventListener('mousemove', moveAlong);
document.removeEventListener('mouseup', stopDrag);
changeClass()
}
function changeClass() {
var diceClass = document.getElementsByClassName("hand");
for (var i = 0; i < diceClass.length; i++) {
diceClass[i].style.opacity = "1";
}
}
document.addEventListener('mouseup', stopDrag);
document.addEventListener('mousemove', moveAlong);
}
for (i = 0; i < draggableCount; i += 1) {
draggable[i].addEventListener('mousedown', startDrag);
}
Try setting css:
.draggable { position: absolute; ...
and change js:
function moveAlong(evt) {
that.parentNode.style.left = (evt.clientX - diffX) + 'px';
that.parentNode.style.top = (evt.clientY - diffY) + 'px';
}
Since you want to move the parentNode, by draging the handle..

Categories

Resources