I'm new with JS.
https://codepen.io/Maartinshh/pen/VbGOvm
Here's my code:
html
<img id="imgZoom" width="200px" height="200px" onmousemove="zoomIn(event)" onmouseout="zoomOut()" src="https://media.licdn.com/mpr/mpr/shrink_200_200/AAEAAQAAAAAAAA20AAAAJDZhZjAwOTE3LTExMDQtNDE5OC05NDdhLWUxYTU0ODJiZTdkYQ.png">
<div id="overlay" onmousemove="zoomIn(event)"></div>
css
#overlay {
border: 1px solid black;
width: 450px;
height: 450px;
position: absolute;
display: inline-block;
background-image: url('https://media.licdn.com/mpr/mpr/shrink_200_200/AAEAAQAAAAAAAA20AAAAJDZhZjAwOTE3LTExMDQtNDE5OC05NDdhLWUxYTU0ODJiZTdkYQ.png');
background-repeat: no-repeat;
}
js
function zoomIn(event) {
var element = document.getElementById("overlay");
element.style.display = "inline-block";
var img = document.getElementById("imgZoom");
var posX = event.offsetX ? (event.offsetX) : event.pageX - img.offsetLeft;
var posY = event.offsetY ? (event.offsetY) : event.pageY - img.offsetTop;
element.style.backgroundPosition = (-posX * 1) + "px " + (-posY * 1) + "px";
}
function zoomOut() {
var element = document.getElementById("overlay");
element.style.display = "none";
}
Problem that occurs: If you see, then when I mouseover picture on left side, the right side (zoomed) picture, doesn't really follow correctly with zoom. What am I doing wrong?
Also, how can I change zoom level (zoom closer)?
Thanks in advance.
You need to do some calculations to add extra offset to place img at center of the div
var offY = (element.clientHeight -img.clientHeight)/2;
var offX = (element.clientWidth -img.clientWidth)/2;
edited codepen here
Related
I am trying to transform this element into a standard web component using Lit. (https://www.w3schools.com/howto/howto_js_image_comparison.asp)
I totally new to Lit and to web components and am struggling to select elements from the shadow DOM. Right now, I am stuck with the var x inside the initComparisons() function. I am aware that the document object does not exist in the shadow dom and must be replaced by renderRoot, however, I am not sure either If I am selecting the elements the right way or what does replace the window object... Do you notice something wrong with this code? I am stuck at the first lines of the initComparisons() function as x always returns null no matter what I do....
Any help will be appreciated.
Thank you very much.
import {
LitElement,
css,
html,
} from "https://cdn.jsdelivr.net/gh/lit/dist#2/all/lit-all.min.js";
export class Comparator extends LitElement {
static properties = {
baseImage: "",
imageWidth: "",
imageHeight: "",
altImage: "",
};
// Define scoped styles right with your component, in plain CSS
static styles = css`
* {
box-sizing: border-box;
}
.img-comp-container {
position: relative;
height: 200px; /*should be the same height as the images*/
}
.img-comp-img {
position: absolute;
width: auto;
height: auto;
overflow: hidden;
}
.img-comp-img img {
display: block;
vertical-align: middle;
}
.img-comp-slider {
position: absolute;
z-index: 11;
cursor: ew-resize;
/*set the appearance of the slider:*/
width: 40px;
height: 40px;
background-color: #2196f3;
opacity: 0.7;
border-radius: 50%;
}
.border-slider {
position: absolute;
z-index: 10;
cursor: ew-resize;
/*set the appearance of the slider:*/
width: 5px;
height: 130%;
background-color: red;
opacity: 1;
}
.border-slider::after {
content: url("./separator.svg");
position: absolute;
width: 30px;
height: 30px;
background: red;
top: calc(50% - 15px);
left: calc(50% - 15px);
}
`;
constructor() {
super();
// Declare reactive defaults
this.baseImage = "https://api.lorem.space/image/house?w=800&h=600";
this.altImage = "https://api.lorem.space/image/house?w=800&h=600";
this.imageWidth = "800px";
this.imageHeight = "600px";
}
connectedCallback() {
super.connectedCallback();
this.initComparisons();
}
// Render the UI as a function of component state
render() {
return html`
<div class="img-comp-container">
<div class="img-comp-img">
<img
src="${this.baseImage}"
width="${this.imageWidth}"
height="${this.imageHeight}"
/>
</div>
<div id="img-comp-overlay" class="img-comp-img">
<img
src="${this.altImage}"
width="${this.imageWidth}"
height="${this.imageHeight}"
/>
</div>
</div>
`;
}
//HELPER FUCTIONS GO HERE
initComparisons() {
var x, i;
/*find all elements with an "overlay" class:*/
x = this.renderRoot.querySelector("#img-comp-overlay");
for (i = 0; i < x.length; i++) {
/*once for each "overlay" element:
pass the "overlay" element as a parameter when executing the compareImages function:*/
compareImages(x[i]);
}
function compareImages(img) {
var slider,
img,
clicked = 0,
w,
h;
/*get the width and height of the img element*/
w = img.offsetWidth;
h = img.offsetHeight;
/*set the width of the img element to 50%:*/
img.style.width = w / 2 + "px";
/*create slider:*/
slider = this.renderRoot.createElement("DIV");
slider.setAttribute("class", "border-slider");
/*insert slider*/
img.parentElement.insertBefore(slider, img);
/*position the slider in the middle:*/
slider.style.top = h / 2 - slider.offsetHeight / 2 + "px";
slider.style.left = w / 2 - slider.offsetWidth / 2 + "px";
/*execute a function when the mouse button is pressed:*/
slider.addEventListener("mousedown", slideReady);
/*and another function when the mouse button is released:*/
this.renderRoot.addEventListener("mouseup", slideFinish);
/*or touched (for touch screens:*/
slider.addEventListener("touchstart", slideReady);
/*and released (for touch screens:*/
window.addEventListener("touchend", slideFinish);
function slideReady(e) {
/*prevent any other actions that may occur when moving over the image:*/
e.preventDefault();
/*the slider is now clicked and ready to move:*/
clicked = 1;
/*execute a function when the slider is moved:*/
window.addEventListener("mousemove", slideMove);
window.addEventListener("touchmove", slideMove);
}
function slideFinish() {
/*the slider is no longer clicked:*/
clicked = 0;
}
function slideMove(e) {
var pos;
/*if the slider is no longer clicked, exit this function:*/
if (clicked == 0) return false;
/*get the cursor's x position:*/
pos = getCursorPos(e);
/*prevent the slider from being positioned outside the image:*/
if (pos < 0) pos = 0;
if (pos > w) pos = w;
/*execute a function that will resize the overlay image according to the cursor:*/
slide(pos);
}
function getCursorPos(e) {
var a,
x = 0;
e = e.changedTouches ? e.changedTouches[0] : e;
/*get the x positions of the image:*/
a = img.getBoundingClientRect();
/*calculate the cursor's x coordinate, relative to the image:*/
x = e.pageX - a.left;
/*consider any page scrolling:*/
x = x - window.pageXOffset;
return x;
}
function slide(x) {
/*resize the image:*/
img.style.width = x + "px";
/*position the slider:*/
slider.style.left = img.offsetWidth - slider.offsetWidth / 2 + "px";
}
}
}
}
customElements.define("image-compare", Comparator);
connectedCallback() is likely too early to call this.initComparison() as the elements might not have been populated within the shadowroot. That happens on first render so you can grab those elements in firstUpdated() instead.
I am making a game and I am using div's instead of canvas.rect's and I want one div to always be inside of another div. I ran into this problem when I made a test script that looked like this.
var mousex, mousey;
function mousepos(e){
mousex = e.clientX;
mousey = e.clientY;
document.getElementById("xy").innerText = mousex + " , " + mousey;
}
function testdiv(){
document.getElementById("testdiv").style.left = mousex;
document.getElementById("testdiv").style.top = mousey;
setTimeout(testdiv, 30);
}
#city{
border: 1px dotted white;
background-color: lightgreen;
height: 500;
width: 500;
resize: both;
overflow: hidden;
max-height: 500px;
max-width: 500px;
min-height: 100px;
min-width: 100px;
}
#xy{
color: white;
}
#testdiv{
background-color: white;
position: absolute;
width: 100px;
height: 100px;
}
#body{
background-color: black;
}
<body id="body" onload="testdiv()">
<center>
<div id="city" onmousemove="mousepos(event);">
<div id="testdiv"></div>
</div>
<p id="xy"></p>
</center>
</body>
The code detects your mouse X and mouse Y when your mouse is over the big green div, then it puts the white div's left corner on your mouse X and mouse Y. My problem is that when my mouse is draging the white div down or right, I can drag it off of the green div.
Is there a way I could fix this problem?
Since there are no supported parent selectors in the current JS.
You could either use Jquery or CSS, I am listing both Javascript options, and CSS options
Option 1: $("a.active").parents('li').css("property", "value");
Option 2: Sibling Combination to match any ParentElement
element that is preceded by an ChildElement element.
// Just change the parent and child elemets below
ParentElement ~ ChildElement {
property: value;
}
You can make a check before changing the child div position, if its new position is outside of where you want it to be, you can skip it.
Something like:
if (mouse.x > parent_div_width){
return;
}
else {
child_div_Xpos = mouse.x
}
You can to try this code:
var mousex, mousey;
function mousepos(e) {
mousex = e.clientX;
mousey = e.clientY;
document.getElementById("xy").innerText = mousex + " , " + mousey;
}
var coordCity = document.getElementById("city").getBoundingClientRect();
var elem = document.getElementById("testdiv");
let i = 0
function testdiv() {
elem.style.left = mousex + 'px';
elem.style.top = mousey + 'px';
var coord = elem.getBoundingClientRect();
if(coord.left < coordCity.left ||
coord.right > coordCity.right ||
coord.bottom > coordCity.bottom ||
coord.top < coordCity.top) {
console.log('rect is out');
};
i++;
if(i === 100) {
return;
}
setTimeout(testdiv, 50);
}
And you need add in css px to value of width and height:
#city{
border: 1px dotted white;
background-color: lightgreen;
height: 500px;
width: 500px;
resize: both;
overflow: hidden;
max-height: 500px;
max-width: 500px;
min-height: 100px;
min-width: 100px;
}
And always save youre nodes to variable, because it does youre code faster, I use variable i for stop test. You can use another solution.
I created next app:
https://codepen.io/piotrazsko/pen/VrrZBq
I figured out a simple, more understandable way to do this.
I created a variables for the testdiv's width, height, x, y, x offset from
mouse, and y offset from mouse.
var divw = 50;
var divh = 50;
var divofx = 25;
var divofy = 25;
Then I made a variable for the city divs width.
var cityw = 500;
Then, I used screen.width / 2 to find the center of the screen.
var centerx = screen.width / 2;
Then, I made the size of the testdiv changeable at any time by putting the code below into the main function :
document.getElementById("testdiv").style.width = divw;
document.getElementById("testdiv").style.height = divh;
Then I used the width variable to find the edges of the city div.
Then, based off of the edges, I made some simple collision detecting if statements. I also did not need to change the Y mutch since it pretty mutch stays the same.
if(mousex + divw > centerx + (cityw / 2)){
mousex = centerx + (cityw / 2) - divw;
}
else{
document.getElementById("testdiv").style.left = mousex;
}
if(mousey > (cityw - divh) + 10){
mousey = (cityw - divh) + 10;
}
else{
document.getElementById("testdiv").style.top = mousey;
}
if(mousex < centerx - cityw / 2){
mousex = centerx - cityw / 2;
}
if(mousey < 8){
mousey = 8;
}
setTimeout(testdiv, 1);
Now the whole program looks like:
<html>
<head>
<style>
#city{
border: 1px dotted white;
background-color: lightgreen;
height: 500;
width: 500;
overflow: none;
max-height: 500px;
max-width: 500px;
min-height: 100px;
min-width: 100px;
}
#xy{
color: white;
}
#testdiv{
background-color: white;
position: absolute;
width: 100px;
height: 100px;
}
#body{
background-color: black;
}
</style>
<script>
var mousex, mousey;
var divw = 50;
var divh = 50;
var divofx = 25;
var divofy = 25;
var cityw = 500;
function mousepos(e){
mousex = e.clientX - divofx;
mousey = e.clientY - divofy;
document.getElementById("xy").innerText = mousex + " , " + mousey;
}
function testdiv(){
var centerx = screen.width / 2;
document.getElementById("city").style.width = cityw;
document.getElementById("testdiv").style.width = divw;
document.getElementById("testdiv").style.height = divh;
if(mousex + divw > centerx + (cityw / 2)){
mousex = centerx + (cityw / 2) - divw;
}
else{
document.getElementById("testdiv").style.left = mousex;
}
if(mousey > (cityw - divh) + 10){
mousey = (cityw - divh) + 10;
}
else{
document.getElementById("testdiv").style.top = mousey;
}
if(mousex < centerx - cityw / 2){
mousex = centerx - cityw / 2;
}
if(mousey < 8){
mousey = 8;
}
setTimeout(testdiv, 1);
}
</script>
</head>
<body id="body" onload="testdiv()" onmousemove="mousepos(event);">
<center>
<div id="city" onmousemove="mousepos(event);">
<div id="testdiv"></div>
</div>
<p id="xy"></p>
</center>
</body>
</html>
I am trying to create(and position) rectangle divs on a parent div. The created div should be positioned relative. Here is a working jsfiddle example -> Just draw some rectangles by holding mouse button.
var newRect = null;
var offset = $('#page').offset();
function point(x, y) {
this.x = x;
this.y = y;
}
function rect(firstPoint) {
this.firstPoint = firstPoint;
this.div = document.createElement("div");
this.div.style.position = "relative";
this.div.style.border = "solid 1px grey";
this.div.style.top = this.firstPoint.y+"px";
this.div.style.left = this.firstPoint.x+"px";
this.div.style.width = "0px";
this.div.style.height = "0px";
$("#page").append(this.div);
}
$("#page").mousedown(function (e) {
if(e.which == 1) {
var x = e.pageX - offset.left;
var y = e.pageY - offset.top;
newRect = new rect(new point(x, y));
}
});
$("#page").mousemove(function (e) {
if(newRect) {
newRect.div.style.width = Math.abs(newRect.firstPoint.x-(e.pageX - offset.left))+"px";
newRect.div.style.height = Math.abs(newRect.firstPoint.y-(e.pageY - offset.top))+"px";
}
});
$("#page").mouseup(function (e) {
if(e.which == 1 && newRect != null) {
if(Math.abs(newRect.firstPoint.x-(e.pageX - offset.left)) < 10) {
$("#"+newRect.div.id).remove();
newRect = null;
return;
}
$("#"+newRect.div.id).on('mousedown', function (e) {
e.stopImmediatePropagation();
});
newRect = null;
}
});
#page{
width: 210mm;
height: 297mm;
border:solid 2px #6D6D6D;
cursor: crosshair;
background-color: white;
float:left;
background-repeat: no-repeat;
background-size: contain;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="page">
</div>
After drawing the first rectangle, which is positioned correctly, each rectangle is positioned false. I think that there is something wrong with the calculation of the position... maybe someone can give me a hint.
Change
this.div.style.position = "relative";
to
this.div.style.position = "absolute";
Bonus: Here's a version that allows you to draw in any direction: https://jsfiddle.net/g4z7sf5c/5/
I simply added this code to the mousemove function:
if (e.pageX < newRect.firstPoint.x) {
newRect.div.style.left = e.pageX + "px";
}
if (e.pageY < newRect.firstPoint.y) {
newRect.div.style.top = e.pageY + "px";
}
The essence of the title is described and presented in my example.
My task is to make the pseudo shape. You need to hover on the canvas element (triangle), canvas accepted property {pointer-events:all}, and the care with this element {pointer-events:none}. How this can be done using the framework konvajs.
/*NON GIST*/
var stage=new Konva.Stage({container:'container',width:300,height:300})
,layer=new Konva.Layer()
,triangle=new Konva.RegularPolygon({x:80,y:120,sides:3,radius:80,fill:'#00D2FF',stroke:'black',strokeWidth:4})
,text=new Konva.Text({x:10,y:10,fontFamily:'Calibri',fontSize:24,text:'',fill:'black'});
function writeMessage(message){text.setText(message);layer.draw();}
/*GIST*/
triangle.on('mouseout', function() {
$('#container').css('pointer-events',/*!*/'none');
writeMessage('Mouseout triangle');
});
/*! How do I know if the events are not tracked on the canvas?*/
triangle.on('mousemove', function() {
$('#container').css('pointer-events',/*!*/'all');
var mousePos = stage.getPointerPosition();
var x = mousePos.x - 190;
var y = mousePos.y - 40;
writeMessage('x: ' + x + ', y: ' + y);
});
/*/GIST/*/
layer.add(triangle);
layer.add(text);
stage.add(layer);
body{
margin: 0;
padding: 0;
overflow: hidden;
background-color: #F0F0F0;}
#container{
position:absolute;
z-index:1;
}
.lower-dom-element{
position:absolute;
z-index:0;
padding:20px;
background:#0e0;
top: 90px;
left: 0px;}
<script src="https://cdn.rawgit.com/konvajs/konva/0.9.0/konva.min.js"></script>
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<div id="container"></div>
<div class="lower-dom-element">
If the POINTER-EVENTS on me, then canvas POINTER-EVENTS:NONE, and vice versa.
If the events are not on the triangle, then the event with me.
</div>
PS: sorry for my english.
var $con = $('#container');
$(document.body).mousemove(function(event) {
var x = event.clientX, y = event.clientY;
var offset = $con.offset();
// manually check intersection
if (layer.getIntersection({x: x - offset.left, y: y - offset.top})){
$con.css('pointer-events',/*!*/'all');
} else {
$con.css('pointer-events',/*!*/'none');
}
});
Demo: http://jsfiddle.net/vfp22dye/3/
I have div that behaves a little strange,
When I move it the first time its working good, but the second time the position starts to bug
I have position: absolute in the main div, but thats all.
Any idea how to clean from bugging ?
http://jsfiddle.net/dymond/tQdFZ/14/ <-- the jsfiddle
javascript.
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.parentNode.style.left = (evt.clientX - diffX) + 'px';
that.parentNode.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);
}
Css
**.draggable {
position: absolute;
width: 100px;
height: 100px;
background: red;
}
.hand{
cursor : move;
width: 98px;
min-height: 16px;
background: yellow;
border:1px solid black;
}
textarea{
padding-top:20px;
resize : none;
overflow : hidden;
background : transparent;
width:95px;
border:none;
}
offsetLeft and offsetTop of this is always 0 because this refers to .hand not .dragabble so this:
var diffX = evt.clientX - this.offsetLeft,
diffY = evt.clientY - this.offsetTop,
Should be this:
var diffX = evt.clientX - this.parentNode.offsetLeft,
diffY = evt.clientY - this.parentNode.offsetTop,
Updated Fiddle: http://jsfiddle.net/knoxzin1/tQdFZ/15/