I am having some problems involving full screening in video elements:
I have a code which tracks X and Y cords as mouse moves over video elem:
<video id="video" preload=auto autoplay controls>
<source src = "http://upload.wikimedia.org/wikipedia/commons/7/79/Big_Buck_Bunny_small.ogv">
</video>
function getElementCSSSize(el) {
var cs = getComputedStyle(el);
var w = parseInt(cs.getPropertyValue("width"), 10);
var h = parseInt(cs.getPropertyValue("height"), 10);
return {width: w, height: h}
}
function mouseHandler(event) {
var size = getElementCSSSize(this);
var scaleX = this.videoWidth / size.width;
var scaleY = this.videoHeight / size.height;
var rect = this.getBoundingClientRect(); // absolute position of element
var x = ((event.clientX - rect.left) * scaleX + 0.5)|0; // round to integer
var y = ((event.clientY - rect.top ) * scaleY + 0.5)|0;
console.log("x " + x);
console.log("y " + y);
}
video.addEventListener("mousemove", mouseHandler);
Now, it works perfectly well when the video is viewed on normal mode;
if for example the video is 237x132,
then max left is 0x, and max top is 0y.
The problem occurs in full mode;
there are black borders on top and bottom as you can see:
https://i.imgsafe.org/452a426.jpg
now, this is true to every video I checked.
So in my script above, for some reason it counts the
black borders as part of the video; the x is ok, but
the y is not; the y starts at the top corner of
the video, upon the black border.
I need to be very precice here, and to completely ignore somehow the black borders - the y should start at the real pixel and end at the real pixel.
So, every type of movie that is played in full mode should is supposed to ignore the black borders.
Thank you so much for your time.
function mouseHandler(event) {
var rect = this.getBoundingClientRect();
if (!('height' in rect)) {//for IE8
rect.height = rect.bottom - rect.top;
rect.width = rect.right - rect.left;
}
var actualVideoHeight = rect.height;
var actualVideoWidth = rect.width;
var borderTop = 0;
var borderLeft = 0;
var onBottomBorder = false;
var onRightBorder = false;
var videoRatio = this.videoWidth / this.videoHeight;
var elementRatio = rect.width / rect.height;
if (videoRatio > elementRatio) {//video is wider than element
actualVideoHeight = this.videoHeight * rect.width / this.videoWidth;//actual height of video without borders
borderTop = (rect.height - actualVideoHeight) / 2;//calculate size of top border
if (event.clientY > actualVideoHeight + borderTop) {//check if mouse in on bottom border
onBottomBorder = true;
}
} else if (videoRatio < elementRatio) {//element is wider than video
actualVideoWidth = this.videoWidth * rect.height / this.videoHeight;//actual width of video without borders
borderLeft = (rect.width - actualVideoWidth) / 2;//calculate size of left border
if (event.clientX > Math.round(actualVideoWidth + borderLeft)) {//check if mouse in on right border
//onRightBorder = true;
}
}
var x = Math.round((event.clientX - rect.left - borderLeft) * (this.videoWidth / actualVideoWidth)); //scale and round to integer
var y = Math.round((event.clientY - rect.top - borderTop) * this.videoHeight / actualVideoHeight);
/*
x will be negative if mouse is on left border
y will be negative if mouse is on top border
onRightBorder will be true if mouse is on right border
onBottomBorder will be true if mouse is on bottom border
*/
if (y > 0 && x > 0 && !onRightBorder && !onBottomBorder) {
console.log('x ' + x);
console.log('y ' + y);
}
}
Related
I've used a pretty standard image zoom effect from the following example: https://www.w3schools.com/howto/howto_js_image_magnifier_glass.asp
The HTML + CSS + JS is pretty much exactly what is used in the example above.
This works perfectly on 1 image. However when multiple images are used it only works on the first image.
I'm pretty sure it's to do with using getElementById instead of querySelectorAll for some things (possibly var img and var result) hence why it's only applying to the first instance of #myimage.
Can anyone help me run this code but loop it over ALL images (with #myimage as the ID)?
Much appreciated!
Original code below:
JAVASCRIPT:
// enable image zoom
function imageZoom(imgID, resultID) {
var img, lens, result, cx, cy;
img = document.getElementById(imgID);
result = document.getElementById(resultID);
/* Create lens: */
lens = document.createElement("DIV");
lens.setAttribute("class", "img-zoom-lens");
/* Insert lens: */
img.parentElement.insertBefore(lens, img);
/* Calculate the ratio between result DIV and lens: */
cx = result.offsetWidth / lens.offsetWidth;
cy = result.offsetHeight / lens.offsetHeight;
/* Set background properties for the result DIV */
result.style.backgroundImage = "url('" + img.src + "')";
result.style.backgroundSize = (img.width * cx) + "px " + (img.height * cy) + "px";
/* Execute a function when someone moves the cursor over the image, or the lens: */
lens.addEventListener("mousemove", moveLens);
img.addEventListener("mousemove", moveLens);
/* And also for touch screens: */
lens.addEventListener("touchmove", moveLens);
img.addEventListener("touchmove", moveLens);
function moveLens(e) {
var pos, x, y;
/* Prevent any other actions that may occur when moving over the image */
e.preventDefault();
/* Get the cursor's x and y positions: */
pos = getCursorPos(e);
/* Calculate the position of the lens: */
x = pos.x - (lens.offsetWidth / 2);
y = pos.y - (lens.offsetHeight / 2);
/* Prevent the lens from being positioned outside the image: */
if (x > img.width - lens.offsetWidth) {x = img.width - lens.offsetWidth;}
if (x < 0) {x = 0;}
if (y > img.height - lens.offsetHeight) {y = img.height - lens.offsetHeight;}
if (y < 0) {y = 0;}
/* Set the position of the lens: */
lens.style.left = x + "px";
lens.style.top = y + "px";
/* Display what the lens "sees": */
result.style.backgroundPosition = "-" + (x * cx) + "px -" + (y * cy) + "px";
}
function getCursorPos(e) {
var a, x = 0, y = 0;
e = e || window.event;
/* Get the x and y positions of the image: */
a = img.getBoundingClientRect();
/* Calculate the cursor's x and y coordinates, relative to the image: */
x = e.pageX - a.left;
y = e.pageY - a.top;
/* Consider any page scrolling: */
x = x - window.pageXOffset;
y = y - window.pageYOffset;
return {x : x, y : y};
}
}
imageZoom("myimage", "myresult");
HTML:
<img src='https://via.placeholder.com/250' id="myimage">
<div id="myresult" class="img-zoom-result"></div>
Something like this?
function magnify(img, zoom) {
var glass, w, h, bw;
/* Create magnifier glass: */
glass = document.createElement("DIV");
glass.setAttribute("class", "img-magnifier-glass");
/* Insert magnifier glass: */
img.parentElement.insertBefore(glass, img);
/* Set background properties for the magnifier glass: */
glass.style.backgroundImage = "url('" + img.src + "')";
glass.style.backgroundRepeat = "no-repeat";
glass.style.backgroundSize = (img.width * zoom) + "px " + (img.height * zoom) + "px";
bw = 3;
w = glass.offsetWidth / 2;
h = glass.offsetHeight / 2;
/* Execute a function when someone moves the magnifier glass over the image: */
glass.addEventListener("mousemove", moveMagnifier);
img.addEventListener("mousemove", moveMagnifier);
/*and also for touch screens:*/
glass.addEventListener("touchmove", moveMagnifier);
img.addEventListener("touchmove", moveMagnifier);
function moveMagnifier(e) {
var pos, x, y;
/* Prevent any other actions that may occur when moving over the image */
e.preventDefault();
/* Get the cursor's x and y positions: */
pos = getCursorPos(e);
x = pos.x;
y = pos.y;
/* Prevent the magnifier glass from being positioned outside the image: */
if (x > img.width - (w / zoom)) {x = img.width - (w / zoom);}
if (x < w / zoom) {x = w / zoom;}
if (y > img.height - (h / zoom)) {y = img.height - (h / zoom);}
if (y < h / zoom) {y = h / zoom;}
/* Set the position of the magnifier glass: */
glass.style.left = (x - w) + "px";
glass.style.top = (y - h) + "px";
/* Display what the magnifier glass "sees": */
glass.style.backgroundPosition = "-" + ((x * zoom) - w + bw) + "px -" + ((y * zoom) - h + bw) + "px";
}
function getCursorPos(e) {
var a, x = 0, y = 0;
e = e || window.event;
/* Get the x and y positions of the image: */
a = img.getBoundingClientRect();
/* Calculate the cursor's x and y coordinates, relative to the image: */
x = e.pageX - a.left;
y = e.pageY - a.top;
/* Consider any page scrolling: */
x = x - window.pageXOffset;
y = y - window.pageYOffset;
return {x : x, y : y};
}
}
[…document.querySelectorAll(“#myimage”)].forEach( img => {
magnify(img,3);
})
I have a parent div that displays a graph that can be rotated.
I want to place dots at mouse clicks. This is my place function:
module.exports.place = function (event, id) {
let div = document.createElement("div");
div.className = "container-fluid";
div.id = id;
let avakio_wrapper = document.getElementById("avakio");
avakio_wrapper.appendChild(div);
let parentPosition = getPosition(event.currentTarget);
xPosition = event.clientX - parentPosition.x - div.clientWidth / 2;
yPosition = event.clientY - parentPosition.y - div.clientHeight / 2;
div.style.left = xPosition + "px";
div.style.top = yPosition + "px";
}
When the graph isn't rotated it works as expected, though when i rotate the graph it places the dot first under mouse click and then it applies the rotation transform and moves it. I have screenshots showing what i describe. The red dot is showing the click position. I appreciate any help.
UPDATE!!!!
Here is an implementation of my code:
// Calculate clicking pos based of top-left corner of div
xPosition = event.clientX - parentPosition.x - dot.clientWidth / 2;
yPosition = event.clientY - parentPosition.y - dot.clientHeight / 2;
let centerx = parentDiv.clientWidth / 2;
let centery = parentDiv.clientHeight / 2;
// Find Rotation angle
let rot = parentDiv.style.getPropertyValue("transform");
if (rot != "") {
rot = rot.split("(")[1].split("deg")[0];
} else {
rot = 0;
}
// Perform Invert Rotation
xPosition = centerx - xPosition;
yPosition = centery - yPosition;
let xRot =
xPosition * Math.cos(rot * (Math.PI / 180)) +
yPosition * Math.sin(rot * (Math.PI / 180));
let yRot =
-xPosition * Math.sin(rot * (Math.PI / 180)) +
yPosition * Math.cos(rot * (Math.PI / 180));
// Calculate again based top-left corner
dot.style.left = centerx - xRot + "px";
dot.style.top = centery - yRot + "px";
However i run on some issues. When the parent div is rotated the dots are placed some pixels off based on the rotation angle. I have some screenshots of different rotation angles. I' ve done the maths on paper for many days but still can't figure out what causing it.
Here an application of the math.
They still move a bit (I think that is because of calculus imprecision). I'm kinda stuck here, maybe some will be able to fix it.
function rotate() {
let parent = document.getElementById("parent")
let rot = document.getElementById("value").value
let transform = parent.style.transform
transform = "rotate("+ (Number(transform.substr(7,transform.length-11)) + Number(rot)) +"deg)"
parent.style.transform = transform
let dots = document.getElementsByClassName("dot")
for (i = 0; i < dots.length; i++)
dotpos(parent, dots[i],rot)
}
function dotpos(parent,dot,rot) {
rot = rot * (Math.PI/180) //convert to radian
let xCenter = parent.offsetWidth /2
let yCenter = parent.offsetHeight /2
let x = xCenter - Number(dot.style.left.substring(0, dot.style.left.length - 2))
let y = yCenter - Number(dot.style.top.substring(0, dot.style.top.length - 2))
let xRot = x*Math.cos(rot)+y*Math.sin(rot)
let yRot = -x*Math.sin(rot)+y*Math.cos(rot)
dot.style.left = xCenter -xRot + "px"
dot.style.top = yCenter -yRot + "px"
}
#parent {
height: 100px;
width : 100px;
background-color: grey;
}
.dot {
height: 5px;
width : 5px;
border-radius: 5px;
background-color: red;
}
<div id="parent" style = "transform:rotate(0deg)">
<div class ="dot" style="position:relative;left:15px;top:30px;"></div>
<div class ="dot" style="position:relative;left:60px;top:50px;"></div>
</div>
<form>
<input type="text" id="value"><br>
</form>
<button onclick="rotate()">rotate</button>
What I want:
I have a div and I want to move it around the canvas but limit it to canvas width and height
What I have:
I'm using p5.dom.js library
P5js code:
let dragging = false;
let offsetX, offsetY, onsetX, onsetY;
let canvasWidth, canvasHeight;
let currentDragDiv;
function setup() {
canvasWidth = windowWidth < 400 ? 400 : windowWidth;
canvasHeight = windowHeight < 400 ? 400 : windowHeight;
canvas = createCanvas(canvasWidth, canvasHeight)
.mousePressed(createDiv);
}
function draw() {
background(200);
if(dragging){
if(mouseX + onsetX < canvasWidth && mouseX + offsetX > 0){
currentDragDiv.position(mouseX + offsetX, currentDragDiv.y);
}
if(mouseY + onsetY < canvasHeight && mouseY + offsetY > 0 ){
currentDragDiv.position(currentDragDiv.x, mouseY + offsetY);
}
}
}
function createDiv(){
let div = createDiv("")
.mousePressed(function(){ dragDiv(div); })
.mouseReleased(function(){ dropDiv(div); })
.position(mouseX, mouseY);
}
function dropDiv(){
dragging = false;
currentDragDiv = null;
}
function dragDiv(d){
currentDragDiv = d;
dragging = true;
offsetX = currentDragDiv.x - mouseX;
offsetY = currentDragDiv.y - mouseY;
onsetX = currentDragDiv.width + offsetX;
onsetY = currentDragDiv.height + offsetY;
}
The Problem:
This code is working great but if the user moves the mouse too quickly, the div doesn't go until the border of the canvas things like this happens (I dragged and moved the div very fast to the right and it stoped in the middle of screen). This problem makes the variable onsetX and onsetY goes wrong and mess up a lit bit deppending on how much the div is away from the canvas border.
Is it possible to remove this "error" and make the div go until the border of canvas?
Observations:
I removed some of the code that I think it's not necessary for this question.
The variables onsetX and onsetY are the oposite of offsetX and offsetY, it's the position of the border from the mouse position, but because english isn't my native language, I didn't know how to name the variable. Recommendations would be good.
In your current code the dragging is completely omitted, if the border of the canvas is exceeded:
if(mouseX + onsetX < canvasWidth && mouseX + offsetX > 0){
currentDragDiv.position(mouseX + offsetX, currentDragDiv.y);
}
if (mouseY + onsetY < canvasHeight && mouseY + offsetY > 0 ){
currentDragDiv.position(currentDragDiv.x, mouseY + offsetY);
}
Instead of that you have to limit the dragging to the range from 0 to canvasWidth respectively 0 to canvasHeight. This means you have to "clamp" the dragging to this range:
function draw() {
let newX, newY;
background(200);
if(dragging){
newX = mouseX + offsetX;
if ( newX > canvasWidth ) {
newX = canvasWidth - currentPostIt.width;
}
if ( newX < 0 ) {
newX = 0;
}
newY = mouseY + offsetY;
if ( newY > canvasHeight ) {
newY = canvasHeight - currentPostIt.height;
}
if ( newY < 0 ) {
newY = 0;
}
currentDragDiv.position(newX, newY);
}
}
so I was working on something on the side and I was trying to create a pop-up zoom window (div) using the JavaScript function on this page: https://www.w3schools.com/howto/howto_js_image_zoom.asp
I tried several things and looked at many questions on here but couldn't figure it out. I can paste the code here too if needed or more explanation on what I am trying to do. Any suggestions would be greatly appreciated!
Update:
http://jsfiddle.net/gb0xcuwz/23/
Just added a little css (which is self-explanatory)
(I hope this is what you wanted)
Old answer:
(keeping it in case someone wants it)
Okay so you provided this: http://jsfiddle.net/gb0xcuwz/5 in the comment.
I made some changes based on hit and trial method (it that a phrase?) and came up with this : http://jsfiddle.net/gb0xcuwz/16/
Here's a code snippet also :
function imageZoom(imgID, resultID) {
var img, lens, result, cx, cy;
img = document.getElementById(imgID);
result = document.getElementById(resultID);
//create lens:
lens = document.createElement("img");
lens.setAttribute("class", "img-zoom-lens");
//insert lens:
img.parentElement.insertBefore(lens, img);
//calculate the ratio between result DIV and lens:
cx = 300 / lens.offsetWidth;
cy = 300 / lens.offsetHeight;
//set background properties for the result DIV:
lens.style.backgroundImage = "url('" + img.src + "')";
lens.style.backgroundSize = (img.width * cx) + "px " + (img.height * cy) + "px";
//execute a function when someone moves the cursor over the image, or the lens:
lens.addEventListener("mousemove", moveLens);
img.addEventListener("mousemove", moveLens);
//and also for touch screens:
lens.addEventListener("touchmove", moveLens);
img.addEventListener("touchmove", moveLens);
//img.addEventListener("mouseenter", result);
function moveLens(e) {
var pos, x, y;
//prevent any other actions that may occur when moving over the image:
e.preventDefault();
//get the cursor's x and y positions:
pos = getCursorPos(e);
//calculate the position of the lens:
x = pos.x - (lens.offsetWidth / 2);
y = pos.y - (lens.offsetHeight / 2);
//prevent the lens from being positioned outside the image:
if (x > img.width - lens.offsetWidth) {x = img.width - lens.offsetWidth;}
if (x < 0) {x = 0;}
if (y > img.height - lens.offsetHeight) {y = img.height - lens.offsetHeight;}
if (y < 0) {y = 0;}
//set the position of the lens:
lens.style.left = x + "px";
lens.style.top = y + "px";
//display what the lens "sees":
lens.style.backgroundPosition = "-" + (x * cx + lens.offsetWidth) + "px -" + (y * cy + lens.offsetHeight) + "px";
}
function getCursorPos(e) {
var a, x = 0, y = 0;
e = e || window.event;
//get the x and y positions of the image:
a = img.getBoundingClientRect();
//calculate the cursor's x and y coordinates, relative to the image:
x = e.pageX - a.left;
y = e.pageY - a.top;
//consider any page scrolling:
x = x - window.pageXOffset;
y = y - window.pageYOffset;
return {x : x, y : y};
}
}
document.addEventListener("DOMContentLoaded", function(){
imageZoom("myimage", "myresult");
})
* {box-sizing: border-box;}
.img-zoom-container {
position: relative;
}
.img-zoom-lens {
position: absolute;
border: 3px solid #A9A9A9;
width: 100px;
height: 100px;
}
<body>
<h1>Picture</h1>
<p>Mouse over the image:</p>
<div class="img-zoom-container">
<img id="myimage" src="https://i.imgur.com/50dDbmr.jpg" width="300" height="200">
</div>
</body>
I am using this color wheel picker, and I'm trying to add a div as the dragger instead of having it embedded in the canvas. I got it working thanks to these answers.
The problem is, the dragger is a bit off from the cursor. The obvious solution would be to just subtract from the draggers left and top position. Like this:
dragger.style.left = (currentX + radiusPlusOffset - 13) + 'px';
dragger.style.top = (currentY + radiusPlusOffset - 13) + 'px';
Another problem comes up when I subtract 13. If you drag the dragger all the way to the right or bottom, it doesn't go all the way. If you drag it all the way to the left or top, it goes passed the canvas's border.
Basically what I'm trying to achieve, is to have the dragger at the cursor pointers exact location, and the draggable shouldn't go passed the canvas's border. How can I achieve that?
JSFiddle
var b = document.body;
var c = document.getElementsByTagName('canvas')[0];
var a = c.getContext('2d');
var wrapper = document.getElementById('wrapper');
var dragger = document.createElement('div');
dragger.id = 'dragger';
wrapper.appendChild(dragger);
wrapper.insertBefore(dragger, c);
document.body.clientWidth; // fix bug in webkit: http://qfox.nl/weblog/218
(function() {
// Declare constants and variables to help with minification
// Some of these are inlined (with comments to the side with the actual equation)
var doc = document;
doc.c = doc.createElement;
b.a = b.appendChild;
var width = c.width = c.height = 400,
label = b.a(doc.c("p")),
input = b.a(doc.c("input")),
imageData = a.createImageData(width, width),
pixels = imageData.data,
oneHundred = input.value = input.max = 100,
circleOffset = 0,
diameter = width - circleOffset * 2,
radius = diameter / 2,
radiusPlusOffset = radius + circleOffset,
radiusSquared = radius * radius,
two55 = 255,
currentY = oneHundred,
currentX = -currentY,
wheelPixel = circleOffset * 4 * width + circleOffset * 4;
// Math helpers
var math = Math,
PI = math.PI,
PI2 = PI * 2,
sqrt = math.sqrt,
atan2 = math.atan2;
// Setup DOM properties
b.style.textAlign = "center";
label.style.font = "2em courier";
input.type = "range";
// Load color wheel data into memory.
for (y = input.min = 0; y < width; y++) {
for (x = 0; x < width; x++) {
var rx = x - radius,
ry = y - radius,
d = rx * rx + ry * ry,
rgb = hsvToRgb(
(atan2(ry, rx) + PI) / PI2, // Hue
sqrt(d) / radius, // Saturation
1 // Value
);
// Print current color, but hide if outside the area of the circle
pixels[wheelPixel++] = rgb[0];
pixels[wheelPixel++] = rgb[1];
pixels[wheelPixel++] = rgb[2];
pixels[wheelPixel++] = d > radiusSquared ? 0 : two55;
}
}
a.putImageData(imageData, 0, 0);
// Bind Event Handlers
input.onchange = redraw;
dragger.onmousedown = c.onmousedown = doc.onmouseup = function(e) {
// Unbind mousemove if this is a mouseup event, or bind mousemove if this a mousedown event
doc.onmousemove = /p/.test(e.type) ? 0 : (redraw(e), redraw);
}
// Handle manual calls + mousemove event handler + input change event handler all in one place.
function redraw(e) {
// Only process an actual change if it is triggered by the mousemove or mousedown event.
// Otherwise e.pageX will be undefined, which will cause the result to be NaN, so it will fallback to the current value
currentX = e.pageX - c.offsetLeft - radiusPlusOffset || currentX;
currentY = e.pageY - c.offsetTop - radiusPlusOffset || currentY;
// Scope these locally so the compiler will minify the names. Will manually remove the 'var' keyword in the minified version.
var theta = atan2(currentY, currentX),
d = currentX * currentX + currentY * currentY;
// If the x/y is not in the circle, find angle between center and mouse point:
// Draw a line at that angle from center with the distance of radius
// Use that point on the circumference as the draggable location
if (d > radiusSquared) {
currentX = radius * math.cos(theta);
currentY = radius * math.sin(theta);
theta = atan2(currentY, currentX);
d = currentX * currentX + currentY * currentY;
}
label.textContent = b.style.background = hsvToRgb(
(theta + PI) / PI2, // Current hue (how many degrees along the circle)
sqrt(d) / radius, // Current saturation (how close to the middle)
input.value / oneHundred // Current value (input type="range" slider value)
)[3];
dragger.style.left = (~~currentX + radiusPlusOffset - 13) + 'px';
dragger.style.top = (~~currentY + radiusPlusOffset - 13) + 'px';
// Reset to color wheel and draw a spot on the current location.
// Draw the current spot.
// I have tried a rectangle, circle, and heart shape.
/*
// Rectangle:
a.fillStyle = '#000';
a.fillRect(currentX+radiusPlusOffset,currentY+radiusPlusOffset, 6, 6);
*/
// Circle:
/*a.beginPath();
a.strokeStyle = 'white';
a.arc(~~currentX+radiusPlusOffset,~~currentY+radiusPlusOffset, 4, 0, PI2);
a.stroke();*/
// Heart:
//a.font = "1em arial";
//a.fillText("♥", currentX + radiusPlusOffset - 4, currentY + radiusPlusOffset + 4);
}
// Created a shorter version of the HSV to RGB conversion function in TinyColor
// https://github.com/bgrins/TinyColor/blob/master/tinycolor.js
function hsvToRgb(h, s, v) {
h *= 6;
var i = ~~h,
f = h - i,
p = v * (1 - s),
q = v * (1 - f * s),
t = v * (1 - (1 - f) * s),
mod = i % 6,
r = [v, q, p, p, t, v][mod] * two55,
g = [t, v, v, q, p, p][mod] * two55,
b = [p, p, t, v, v, q][mod] * two55;
return [r, g, b, "rgb(" + ~~r + "," + ~~g + "," + ~~b + ")"];
}
// Kick everything off
redraw(0);
/*
// Just an idea I had to kick everything off with some changing colors…
// Probably no way to squeeze this into 1k, but it could probably be a lot smaller than this:
currentX = currentY = 1;
var interval = setInterval(function() {
currentX--;
currentY*=1.05;
redraw(0)
}, 7);
setTimeout(function() {
clearInterval(interval)
}, 700)
*/
})();
#c {
border: 7px solid black;
border-radius: 50%;
}
#wrapper {
width: 400px;
height: 400px;
position: relative;
cursor: pointer;
}
#wrapper:active {
//cursor: none;
}
#dragger {
width: 8px;
height: 8px;
border-radius: 50%;
display: block;
position: absolute;
border: 2px solid black;
}
<div id='wrapper'>
<canvas id="c"></canvas>
</div>
You're just subtracting in the wrong place.
Instead of subtracting from the elements position, subtract directly from the mouse pointers position.
This code actually moves the element, offsetting it relative to the pointer, and making it appear to be outside the borders of the color picker
dragger.style.left = (~~currentX + radiusPlusOffset - 13) + 'px';
dragger.style.top = (~~currentY + radiusPlusOffset - 13) + 'px';
... which is not what you really want, you want the calculated numbers for the pointer to be exactly center of the dragger element, so you should extract from the pointers position instead, that way the limits of the dragger isn't affected, and it stays within the borders of the color picker
currentX = e.pageX - c.offsetLeft - radiusPlusOffset -13 || currentX;
currentY = e.pageY - c.offsetTop - radiusPlusOffset -13 || currentY;
FIDDLE