I am trying to draw a red rectangle on image but somehow my rectangle is NOT starting from coordinates where I click with my mouse. Here is the code:
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
let img = new Image();
let fileName = "";
let rect = {};
let drag = false;
// Add image to canvas
reader.addEventListener(
"load",
() => {
// Create image
img = new Image();
// Set image src
img.src = reader.result;
// On image load add to canvas
img.onload = function() {
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0, img.width, img.height);
canvas.removeAttribute("data-caman-id");
};
canvas.addEventListener('mousedown', mouseDown, false);
canvas.addEventListener('mouseup', mouseUp, false);
canvas.addEventListener('mousemove', mouseMove, false);
},
false
);
});
function mouseDown(e) {
rect.startX = e.pageX - this.offsetLeft;
rect.startY = e.pageY - this.offsetTop;
drag = true;
}
function mouseUp() { drag = false; }
function mouseMove(e) {
if (drag) {
ctx.clearRect(0, 0, 500, 500);
ctx.drawImage(img, 0, 0);
rect.w = (e.pageX - this.offsetLeft) - rect.startX;
rect.h = (e.pageY - this.offsetTop) - rect.startY;
ctx.strokeStyle = 'red';
ctx.strokeRect(rect.startX, rect.startY, rect.w, rect.h);
console.log("rect.startX: " + rect.startX + " - rect.startY: " +rect.startY)
}
}
And here is what I get in return:
I cannot show my mouse position when I take screenshot so I've labeled it on the image. Basically, I start from top left corner and rectangle seems to start drawing itself from bottom right corner. What am I doing wrong?
OK my answer is more related to the (original) question title and a little bit of jQuery fun.
Your (original) question code involves canvas and no jQuery code, just javascript.
This answer is more just a primitive jQuery approach.
Here is a very rough concept below using jQuery .on events for handling...
mousedown event to start drawing the rectangle
resize event for updating image size and offsets
mousemove event for updating rectangle draw positions
mouseup event for setting rectangle in set position
All of the above .on events (excluding resize event) run in document selector .area, which has a child img element in this example below.
Please note I have not coded this example for multiple usages of .area div, you will need go even deeper with the script logic in my example to accommodate multiple usages of .area div.
My script example code below may inspire you to get to where you want, may not.
The main key thing I am doing is converting pixel cursor positions within the image into a percentage integer. Using percentages as xy positions means the rendered result will be the same if the window or .area is resized responsively (with no javascript).
Here is a jQuery and CSS fun example below.
jsFiddle version: https://jsfiddle.net/joshmoto/w5bcx9o8/2/
See comments in code to understand what is happening...
// our updatable variable objects to use globally
let img = {};
let position = {};
// image matrix function to update img object variable
function imgMatrix() {
// our image object inside area
let $img = $('IMG', '.area');
// offset data of image
let offset = $img.offset();
// add/update object key data
img.width = $img.outerWidth();
img.height = $img.outerHeight();
img.offsetX = offset.left - $(document).scrollLeft();
img.offsetY = offset.top - $(document).scrollTop();
}
// position matrix function to update position object variable
function positionMatrix(e, mousedown = false) {
// if mousedown param is true... for use in
if (mousedown) {
// set the top/left position object data with percentage position
position.top = (100 / img.height) * ( (e.pageY - $(document).scrollTop()) - img.offsetY);
position.left = (100 / img.width) * ( (e.pageX - $(document).scrollLeft()) - img.offsetX);
}
// set the right/bottom position object data with percentage position
position.right = 100 - ((100 / img.width) * ((e.pageX - $(document).scrollLeft()) - img.offsetX));
position.bottom = 100 - ((100 / img.height) * ((e.pageY - $(document).scrollTop()) - img.offsetY));
}
// mouse move event function in area div
$(document).on('mousemove', '.area', function(e) {
// update img object variable data upon this mousemove event
imgMatrix();
// if this area has draw class
if ($(this).hasClass('draw')) {
// update position object variable data passing current event data
positionMatrix(e);
// if image x cursor drag position percent is negative to mousedown x position
if ((100 - position.bottom) < position.top) {
// update rectange x negative positions css
$('.rect', this).css({
top: (100 - position.bottom) + '%',
bottom: (100 - position.top) + '%'
});
// else if image x cursor drag position percent is positive to mousedown x position
} else {
// update rectange x positive positions css
$('.rect', this).css({
bottom: position.bottom + '%',
top: position.top + '%',
});
}
// if image y cursor drag position percent is negative to mousedown y position
if ((100 - position.right) < position.left) {
// update rectange y negative positions css
$('.rect', this).css({
left: (100 - position.right) + '%',
right: (100 - position.left) + '%'
});
// else if image y cursor drag position percent is positive to mousedown y position
} else {
// update rectange y positive positions css
$('.rect', this).css({
right: position.right + '%',
left: position.left + '%'
});
}
}
});
// mouse down event function in area div
$(document).on('mousedown', '.area', function(e) {
// remove the drawn class
$(this).removeClass('drawn');
// update img object variable data upon this mousedown event
imgMatrix();
// update position object variable data passing current event data and mousedown param as true
positionMatrix(e, true);
// update rectange xy positions css
$('.rect', this).css({
left: position.left + '%',
top: position.top + '%',
right: position.right + '%',
bottom: position.bottom + '%'
});
// add draw class to area div to reveal rectangle
$(this).addClass('draw');
});
// mouse up event function in area div
$(document).on('mouseup', '.area', function(e) {
// update img object variable data upon this mouseup event
imgMatrix();
// if this area had draw class
if ($(this).hasClass('draw')) {
// update position object variable data passing current event
positionMatrix(e);
// math trunc on position values if x and y values are equal, basically no drawn rectangle on mouseup event
if ((Math.trunc(position.left) === Math.trunc(100 - position.right)) && (Math.trunc(position.top) === Math.trunc(100 - position.bottom))) {
// remove draw and drawn classes
$(this).removeClass('draw drawn');
// else if x and y values are not equal, basically a rectange has been drawn
} else {
// add drawn class and remove draw class
$(this).addClass('drawn').removeClass('draw');
}
}
});
// on window resize function
$(window).on('resize', function(e) {
// update img object variable data upon this window resize event
imgMatrix();
});
/* area div */
.area {
overflow: hidden;
position: relative;
margin-bottom: 8px;
}
/* area div hover cursor */
.area:hover {
cursor: crosshair;
}
/* img tag in area div */
.area IMG {
display: block;
width: 100%;
pointer-events: none;
user-select: none;
}
/* rectangle div in area div */
.area .rect {
opacity: 0;
transition: all 0s ease;
position: absolute;
border: 1px solid red;
z-index: 1;
}
/* rectangle div css when in draw or drawn mode */
.area.draw .rect,
.area.drawn .rect {
opacity: 1;
}
/* below css is for fun rendering outer exclusion area of drawn rectangle div with a opaque overlay */
/* rectange exclusing pseudo elems base css */
.area.drawn .rect .exclusion-x::before,
.area.drawn .rect .exclusion-x::after,
.area.drawn .rect .exclusion-y::before,
.area.drawn .rect .exclusion-y::after {
position: absolute;
content: '';
display: block;
background: #000;
opacity: .75;
z-index: -1;
pointer-events: none;
user-select: none;
}
/* rectange outer opaque x above css */
.area.drawn .rect .exclusion-x::before {
bottom: calc(100% + 1px);
left: 50%;
transform: translateX(-50%);
height: 200vh;
width: 200vw;
}
/* rectange outer opaque x below css */
.area.drawn .rect .exclusion-x::after {
top: calc(100% + 1px);
left: 50%;
transform: translateX(-50%);
height: 200vh;
width: 200vw;
}
/* rectange outer opaque y left css */
.area.drawn .rect .exclusion-y::before {
right: calc(100% + 1px);
top: -1px;
bottom: -1px;
width: 200vw;
}
/* rectange outer opaque y right css */
.area.drawn .rect .exclusion-y::after {
left: calc(100% + 1px);
top: -1px;
bottom: -1px;
width: 200vw;
}
<div class="area">
<img src="https://dragonballsuper-france.fr/wp-content/uploads/2017/10/DIHQF2OXoAAJi4n-660x330.jpg" alt="" />
<div class="rect">
<div class="exclusion-x"></div>
<div class="exclusion-y"></div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Related
I trying to create a map framework for some games and i have a problem with recalc position of marker. Look url to test, with wheel you can resize div with image but the dot red not come back to own position. Sorry but im new on this y trying to learn more about js and css. Thanks
$('.map-live').css('width', "928px");
$('.map-live').css('height', "928px");
$('.map-live').css('background-size', "100%");
$('.map-live').bind('mousewheel DOMMouseScroll', function(event) {
var divSize = $('.map-live').css('width');
console.log(divSize);
divSize = divSize.replace('px', '')
divSize = parseInt(divSize);
console.log("oldSize: " + divSize);
var delta_px = event.originalEvent.wheelDelta > 0 ? (divSize + (divSize * 0.15)) : (divSize - (divSize * 0.15));
console.log("NewSize: " + delta_px);
$(this).css('width', delta_px + "px");
$(this).css('height', delta_px + "px");
$(this).css('background-size', "100%");
UpdatePoints();
});
$(function() {
$("#map-live").draggable();
});
document.getElementById('map-live').addEventListener('click', printPosition)
function getPosition(e) {
var rect = e.target.getBoundingClientRect();
var x = e.clientX - rect.left;
var y = e.clientY - rect.top;
return {
x,
y
}
}
function printPosition(e) {
var position = getPosition(e);
console.log('X: ' + position.x + ' Y: ' + position.y);
var divX = parseInt($('.map-live').css('width').replace('px', ''));
var divY = parseInt($('.map-live').css('height').replace('px', ''));
var vhX = (position.x / divX) * 100;
var vhY = (position.y / divY) * 100;
console.log('vhX: ' + vhX + ' vhY: ' + vhY);
}
function UpdatePoints() {
$('.point').css('top', '2.477565353101834vh');
$('.point').css('left', '2.477565353101834vh');
$('.point').css('position', 'absolute');
}
body {
margin: 0;
overflow: hidden;
}
.map-live {
position: absolute;
left: 10px;
z-index: 9;
background-image: url(https://i.ibb.co/d2y5G1y/map.jpg);
width: 222px;
height: 222px;
transition: all 0.2s linear;
}
.point {
position: absolute;
left: 2.477565353101834vh;
top: 2.477565353101834vh;
width: 10px;
height: 10px;
background-color: red;
border-radius: 50%;
}
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="map-live ui-widget-content" id="map-live">
<div class="point"></div>
</div>
jsfiddle.net/f84mto52
Someone can correct me, but I believe your use of position: absolute is what is making the <div class="point"></div> stay in place.
Your UpdatePoints is setting always the same position in the div. With 'vh' you are calculating and absolute position proportional to viewport, no to parent container.
So, you are zooming the background image but the position (x, y) will be always be (x, y), positions are not zoomed. You need to recalculate which is the new position.
So you need to calculate new position.
function UpdatePoints(){
var divW = parseInt($('.map-live').css('width').replace('px',''));
var divH = parseInt($('.map-live').css('height').replace('px',''));
var topPosition = (2.477565353101834 / 928) * divH;
var leftPosition = (2.477565353101834 / 928) * divW;
$('.point').css('top', topPosition+'vh');
$('.point').css('left', leftPosition+'vh');
$('.point').css('position', 'absolute');
}
Also, instead using 'vh' I recommend to calculate the px position instead. I have added the already calculated delta_px parameter to UpdatePoints function:
<style>
.point {
position: absolute;
left: 22.99180647678502px;
top: 22.99180647678502px;
width: 10px;
height: 10px;
background-color: red;
border-radius: 50%;
}
</style>
<script>
function UpdatePoints(delta_px){
var position = (delta_px/100)*2.477565353101834;
$('.point').css('top', position+'px');
$('.point').css('left', position+'px');
$('.point').css('position', 'absolute');
}
</script>
Also, here we are calculating the top-left position of the .point element, not the position for the center. As it is a circle, it work fine, but if you use any other shape the position translation should be calculated from its center.
I recommend to do some research about how to translate elements. You can start here:
Calculating relative position of points when zoomed in and enlarged by a rectangle!
Zoom in on a point (using scale and translate)!
How do I effectively calculate zoom scale?!
My implementation,
http://kodhus.com/kodnest/land/PpNFTgp
I am curious, as I am not able for some reason to figure this out, how to get my JavaScript to make my slider behave more natural and smoother, if someone knows, how to, or can make this, feel free. I'd be happy to understand.
JavaScript:
const thumb = document.querySelector('.thumb');
const thumbIndicator = document.querySelector('.thumb .thumb-indicator');
const sliderContainer = document.querySelector('.slider-container');
const trackProgress = document.querySelector('.track-progress');
const sliderContainerStart = sliderContainer.offsetLeft;
const sliderContainerWidth = sliderContainer.offsetWidth;
var translate;
var dragging = false;
var percentage = 14;
document.addEventListener('mousedown', function(e) {
if (e.target.classList.contains('thumb-indicator')) {
dragging = true;
thumbIndicator.classList.add('focus');
}
});
document.addEventListener('mousemove', function(e) {
if (dragging) {
console.log('moving', e)
if (e.clientX < sliderContainerStart) {
translate = 0;
} else if (e.clientX > sliderContainerWidth + sliderContainerStart) {
translate = sliderContainerWidth;
} else {
translate = e.clientX - sliderContainer.offsetLeft;
}
thumb.style.transform = 'translate(-50%) translate(' + translate + 'px)';
trackProgress.style.transform = 'scaleX(' + translate / sliderContainerWidth + ')'
}
});
function setPercentage() {
thumb.style.transform = 'translate(-50%) translate(' + percentage/100 * sliderContainerWidth + 'px)';
trackProgress.style.transform = 'scaleX(' + percentage/100 + ')';
}
function init() {
setPercentage();
}
init();
document.addEventListener('mouseup', function(e) {
dragging = false;
thumbIndicator.classList.remove('focus');
});
EDIT: Is there a way to smoothly and naturally increment by one for every slow move?
Is it possible to make to behave as if, like when one clicks the progress bar so that it jumps there?
The kodhus site is very janky in my browser, so I can't tell if your code lacks responsiveness or whether it's the site itself. I feel that your code is a bit convoluted: translate and width / height are mixed unnecessarily; no need to use a dragging boolean when that information is always stored in the classlist. The following slider performs nicely, and has a few considerations I don't see in yours:
stopPropagation when clicking the .thumb element
drag stops if window loses focus
pointer-events: none; applied to every part of the slider but the .thumb element
let applySliderFeel = (slider, valueChangeCallback=()=>{}) => {
// Now `thumb`, `bar` and `slider` are the elements that concern us
let [ thumb, bar ] = [ '.thumb', '.bar' ].map(v => slider.querySelector(v));
let changed = amt => {
thumb.style.left = `${amt * 100}%`;
bar.style.width = `${amt * 100}%`;
valueChangeCallback(amt);
};
// Pressing down on `thumb` activates dragging
thumb.addEventListener('mousedown', evt => {
thumb.classList.add('active');
evt.preventDefault();
evt.stopPropagation();
});
// Releasing the mouse button (anywhere) deactivates dragging
document.addEventListener('mouseup', evt => thumb.classList.remove('active'));
// If the window loses focus dragging also stops - this can be a very
// nice quality of life improvement!
window.addEventListener('blur', evt => thumb.classList.remove('active'));
// Now we have to act when the mouse moves...
document.addEventListener('mousemove', evt => {
// If the drag isn't active do nothing!
if (!thumb.classList.contains('active')) return;
// Compute `xRelSlider`, which is the mouse position relative to the
// left side of the slider bar. Note that *client*X is compatible with
// getBounding*Client*Rect, and using these two values we can quickly
// get the relative x position.
let { width, left } = slider.getBoundingClientRect();
// Consider mouse x, subtract left offset of slider, and subtract half
// the width of the thumb (so drags position the center of the thumb,
// not its left side):
let xRelSlider = evt.clientX - left - (thumb.getBoundingClientRect().width >> 1);
// Clamp `xRelSlider` between 0 and the slider's width
if (xRelSlider < 0) xRelSlider = 0;
if (xRelSlider > width) xRelSlider = width;
// Apply styling (using percents is more robust!)
changed(xRelSlider / width);
evt.preventDefault();
evt.stopPropagation();
});
slider.addEventListener('mousedown', evt => {
let { width, left } = slider.getBoundingClientRect();
// Clicking the slider also activates a drag
thumb.classList.add('active');
// Consider mouse x, subtract left offset of slider, and subtract half
// the width of the thumb (so drags position the center of the thumb,
// not its left side):
let xRelSlider = evt.clientX - left - (thumb.getBoundingClientRect().width >> 1);
// Apply styling (using percents is more robust!)
changed(xRelSlider / width);
evt.preventDefault();
evt.stopPropagation();
});
changed(0);
};
let valElem = document.querySelector('.value');
applySliderFeel(document.querySelector('.slider'), amt => valElem.innerHTML = amt.toFixed(3));
.slider {
position: absolute;
width: 80%; height: 4px; background-color: rgba(0, 0, 0, 0.3);
left: 10%; top: 50%; margin-top: -2px;
}
.slider > .bar {
position: absolute;
left: 0; top: 0; width: 0; height: 100%;
background-color: #000;
pointer-events: none;
}
.slider > .thumb {
position: absolute;
width: 20px; height: 20px; background-color: #000; border-radius: 100%;
left: 0; top: 50%; margin-top: -10px;
}
.slider > .thumb.active {
box-shadow: 0 0 0 5px rgba(0, 0, 0, 0.5);
}
<div class="slider">
<div class="bar"></div>
<div class="thumb"></div>
</div>
<div class="value"></div>
I have a container and and image inside that container. When the container is not in view - the image must be at translate y 0%. When the container is halfway into the viewport and past halfway - the image must be translate y 50%. The % value must be bound to the position of the container into the viewport (controlled by scrolling). The position of the container also determines the speed the image is being translated at. The problem I'm getting is that when the speed value changes, the image jerks up or down instead of changing the speed from that point onward.
Here is my script:
if (wScroll > $(".largeWindow").offset().top - ($(window).height())) {
var cont = $(".largeWindow");
var img = $(".coffee2");
var top = cont.offset().top - cont.height();
var speed;
// translate the image within the container
var moveImage = function() {
setSpeed();
var scroll = Math.floor((wScroll - top)) * speed;
return img.css("transform", "translate(-50%, " + scroll + "%)");
}
// get the position of the image within the container
var getImagePos = function() {
return img.position().top - img.height()/2;
}
var getContainerPos = function() {
var windowHeight = $(window).height();
var contPos = Math.floor(cont.offset().top + cont.height()/2) - wScroll;
return Math.floor(contPos/windowHeight * 100);
}
// set the speed the image will be translated at
var setSpeed = function() {
if (getContainerPos() < 50) {
speed = 0;
}
else if (getContainerPos() < 60 ) {
speed = 0.5
}
else if (getContainerPos() < 70 ) {
speed = 0.5
}
else {
speed = 0.8
}
}
getContainerPos();
moveImage();
getImagePos();
}
Here is the sass for the container and image:
.largeWindow
position: relative
margin: 0 auto
height: 400px
width: 400px
border-radius: 50%
overflow: hidden
background:
image: url(../images/bgTable.jpg)
size: cover
repeat: no-repeat
position: center
attachment: fixed
.coffee2
position: absolute
height: 200px
width: 200px
left: 50%
transform: translateX(-50%)
top: - 200px
background:
image: url(../images/bgCup.png)
size: contain
repeat: no-repeat
position: center
I have this jsfiddle where the white square always appear at the top upper-left hand corner.
http://jsfiddle.net/helpme128/3kwwo53t/2/
I want to make the white square appear at the centre instead.
I tried to make the code change below (x = 150, y = 150);
.directive('ngDraggable', function($document) { return {
restrict: 'A',
scope: {
dragOptions: '=ngDraggable'
},
link: function(scope, elem, attr) {
var startX, startY, x = 150, y = 150,
start, stop, drag, container;
However, it did not work. What should be the right code to get the white square to appear at the centre?
If all you want to do is have the white square start out at a certain position, then give it the position in the stylesheet.
left: 130px;
top: 130px;
Updated fiddle: http://jsfiddle.net/MrLister/3kwwo53t/6/
The JavaScript is used for dragging, not for defining the initial status.
By the way, it's 130px, not 150. Since the outer div is 300px across, and the inner square measures 40px, its offset needs to be -20px from the center.
Edit: or, if you want to be independent of the size of the container, set the container's position to relative and calculate the position like this:
left: calc(50% - 20px);
top: calc(50% - 20px);
Newer fiddle: http://jsfiddle.net/MrLister/3kwwo53t/7/
Be aware though that only modern browsers support calc.
Try this, if you don't want to hard code pixels,
#container {
width : 300px;
height: 300px;
background-color: black;
display:table-cell;
vertical-align:middle;
text-align:center;
}
.shape {
width : 40px;
height: 40px;
background-color: white;
margin-left:auto;
margin-right:auto;
}
Try this link - https://jsfiddle.net/3kwwo53t/8/
Call setPosition() in the link function after everything is set up:
.directive('ngDraggable', function($document) {
return {
restrict: 'A',
scope: {
dragOptions: '=ngDraggable'
},
link: function(scope, elem, attr) {
var startX, startY, x = 150, y = 150,
start, stop, drag, container;
var width = elem[0].offsetWidth,
height = elem[0].offsetHeight;
// Obtain drag options
if (scope.dragOptions) {
start = scope.dragOptions.start;
drag = scope.dragOptions.drag;
stop = scope.dragOptions.stop;
var id = scope.dragOptions.container;
if (id) {
container = document.getElementById(id).getBoundingClientRect();
}
}
// Bind mousedown event
elem.on('mousedown', function(e) {
e.preventDefault();
startX = e.clientX - elem[0].offsetLeft;
startY = e.clientY - elem[0].offsetTop;
$document.on('mousemove', mousemove);
$document.on('mouseup', mouseup);
if (start) start(e);
});
# The position of the element is not changed until the `setPosition` function
# is called
setPosition()
// Handle drag event
function mousemove(e) {
y = e.clientY - startY;
x = e.clientX - startX;
setPosition();
if (drag) drag(e);
}
// Unbind drag events
function mouseup(e) {
$document.unbind('mousemove', mousemove);
$document.unbind('mouseup', mouseup);
if (stop) stop(e);
}
// Move element, within container if provided
function setPosition() {
if (container) {
if (x < container.left) {
x = container.left;
} else if (x > container.right - width) {
x = container.right - width;
}
if (y < container.top) {
y = container.top;
} else if (y > container.bottom - height) {
y = container.bottom - height;
}
}
elem.css({
top: y + 'px',
left: x + 'px'
});
}
}
}
})
When using absolute positioning you can center an element using top: 50%; left: 50%; and then move back the element by the half of its width:
That way, it doesn't matter how big or small the parent container is – the .shape will always be centered.
.shape {
position: absolute;
width : 40px;
height: 40px;
top: 50%;
margin-top: -20px;
left: 50%;
margin-left: -20px;
background-color: white;
}
http://jsfiddle.net/3kwwo53t/5/
Let's say on a web page there's a black and white background that is a picture of a landscape or city. Now, in a div (whose location does not have to be fixed) on the page, you see the background in color, but only the portion of the background that is the size of the div, i.e. the div serves as a "window" into a colored view of the otherwise black and white background.
Is this possible using just basic web technologies (e.g. HTML, CSS, JS)? I gave some thought to just making the background of the div the colored portion of the background that the div is covering, but assuming the site is screen size responsive, this would not look too great when the site shifts to a smaller screen size - the colored image would not be aligned with the image any longer.
Any ideas? I appreciate any and all!
Edit - an idea: Is there a CSS property that I can use to blur/darken the entire area of the background except for that which is covered by/contained in the div?
The image is offset using negative margins equal to the absolute top and left position of the parent div with overflow: hidden;.
I think this is what you want.
http://jsfiddle.net/w17x32dg/2/
var selected = null, // Object of the element to be moved
x_pos = 0,
y_pos = 0, // Stores x & y coordinates of the mouse pointer
x_elem = 0,
y_elem = 0; // Stores top, left values (edge) of the element
var image;
// Will be called when user starts dragging an element
function _drag_init(elem) {
// Store the object of the element which needs to be moved
selected = elem;
image = document.getElementById('image');
x_elem = x_pos - selected.offsetLeft;
y_elem = y_pos - selected.offsetTop;
}
// Will be called when user dragging an element
function _move_elem(e) {
x_pos = document.all ? window.event.clientX : e.pageX;
y_pos = document.all ? window.event.clientY : e.pageY;
if (selected !== null) {
selected.style.left = (x_pos - x_elem) + 'px';
selected.style.top = (y_pos - y_elem) + 'px';
image.style.marginLeft = -(x_pos - x_elem) + 'px';
image.style.marginTop = -(y_pos - y_elem) + 'px';
}
}
// Destroy the object when we are done
function _destroy() {
selected = null;
}
// Bind the functions...
document.getElementById('color').onmousedown = function () {
_drag_init(this);
return false;
};
document.onmousemove = _move_elem;
document.onmouseup = _destroy;
body {
margin: 0;
}
img {
position: absolute;
}
#color {
cursor: move;
position: absolute;
border: 2px solid red;
width: 200px;
height: 200px;
overflow: hidden;
box-sizing: border-box;
}
<img src="http://i.imgur.com/BgewSni.jpg" />
<div id="color">
<img src="http://i.imgur.com/3Ec3jhz.jpg" id="image" />
</div>