react-js-x-ray
Version:
X-Ray for ReactJS
294 lines (264 loc) • 10.2 kB
JavaScript
/**
* X-Ray by Amur
* https://github.com/AmurKhoyetsyan/X-Ray
*/
;
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
import React, { Component } from 'react';
import './xray.css';
export default class XRay extends Component {
constructor(props) {
super(props);
_defineProperty(this, "componentDidMount", () => {
this.updateWidthHeight();
window.addEventListener('resize', this.updateWidthHeight);
});
_defineProperty(this, "getDiameter", () => {
let {
diameter,
resize
} = this.state;
let getMaxResWidth = this.getMaxResize(resize);
let newDiameter = this.matchesWindow(resize);
if (this.state.responsive) {
if (window.matchMedia(`(min-width: ${getMaxResWidth + 1}px)`).matches) {
return newDiameter > diameter ? newDiameter : diameter;
} else {
return newDiameter;
}
} else {
return diameter;
}
});
_defineProperty(this, "updateWidthHeight", () => {
let {
firstImage,
lastImage
} = this.state;
if(!firstImage && !lastImage){
this.loadImages(this.firstImg).then(()=>{
this.setState({firstImage: true});
this.loadImages(this.lastImg).then(()=>{
this.setState({lastImage: true});
this.updateResize();
}).catch((error)=>{
console.log('error', error);
});
}).catch((error)=>{
console.log('error', error);
});
}else{
this.updateResize();
}
});
_defineProperty(this, 'loadImages', (img) => {
return new Promise(function(resolve, reject){
img.onload = (e) => {
resolve(img);
};
img.onerror = (e)=> {
reject(new Error(`Failed to load image's URL: ${url}`));
};
});
});
_defineProperty(this, 'updateResize', () => {
let {
beyond,
firstImage,
lastImage
} = this.state;
if(firstImage && lastImage){
let naturalWidth = this.firstImg.naturalWidth;
let naturalHeight = this.firstImg.naturalHeight;
let percent = naturalWidth / naturalHeight;
let width = this.firstImg.clientWidth;
let height = Math.round(width / percent);
let dim = this.getDiameter();
let sensor;
if (beyond) {
sensor = {
width: width + dim,
height: height + dim,
top: -(dim / 2),
left: -(dim / 2)
};
} else {
sensor = {
width: width,
height: height,
top: 0,
left: 0
};
}
this.setState({
width,
height,
dim,
sensor
});
}
});
_defineProperty(this, "getMaxResize", diameter => {
let newDiameter = diameter[0].screen;
for (let i = 0; i < diameter.length; i++) {
if (diameter[i].screen > newDiameter) {
newDiameter = diameter[i].screen;
}
}
return newDiameter;
});
_defineProperty(this, "matchesWindow", diameter => {
let newDiameter = diameter[0].diameter;
for (let i = 0; i < diameter.length; i++) {
if (window.matchMedia(`(max-width: ${diameter[i].screen}px)`).matches) {
newDiameter = diameter[i].diameter;
}
}
return newDiameter;
});
_defineProperty(this, "HoverSensor", event => {
let positionX = event.nativeEvent.layerX;
let positionY = event.nativeEvent.layerY;
let {
sensor,
dim,
beyond
} = this.state;
let position = {
startY: 0,
endY: sensor.height,
startX: 0,
endX: sensor.width
};
let coefficient = dim / 2;
let zoomPosition;
if (beyond) {
zoomPosition = dim / 2;
} else {
zoomPosition = 0;
}
if (positionY >= position.startY + coefficient && positionY <= position.endY - coefficient) {
this.zoom.style.top = `${positionY - coefficient - zoomPosition}px`;
this.lastImg.style.top = `${-positionY + coefficient + zoomPosition}px`;
} else if (positionY < position.startY + coefficient) {
this.zoom.style.top = `${position.startY - zoomPosition}px`;
this.lastImg.style.top = `${position.startY + zoomPosition}px`;
} else if (positionY > position.endY - coefficient) {
this.zoom.style.top = `${position.endY - dim - zoomPosition}px`;
this.lastImg.style.top = `${-position.endY + dim + zoomPosition}px`;
}
if (positionX >= position.startX + coefficient && positionX <= position.endX - coefficient) {
this.zoom.style.left = `${positionX - coefficient - zoomPosition}px`;
this.lastImg.style.left = `${-positionX + coefficient + zoomPosition}px`;
} else if (positionX < position.startX + coefficient) {
this.zoom.style.left = `${position.startX - zoomPosition}px`;
this.lastImg.style.left = `${position.startX + zoomPosition}px`;
} else if (positionX > position.endX - coefficient) {
this.zoom.style.left = `${position.endX - dim - zoomPosition}px`;
this.lastImg.style.left = `${-position.endX + dim + zoomPosition}px`;
}
});
_defineProperty(this, "move", event => {
let {
transform
} = this.state;
if (transform) {
this.setState({
transform: false
});
}
this.HoverSensor(event);
});
this.state = {
firstImage: false,
lastImage: false,
backgroundColor: this.props.backgroundColor || 'transparent',
transform: true,
images: this.props.images,
cursor: this.props.cursor || false,
diameter: this.props.diameter || 150,
beyond: this.props.beyond || false,
width: null,
height: null,
dim: null,
type: this.props.type || 'circle',
sensor: {
width: null,
height: null,
top: null,
left: null
},
responsive: this.props.responsive || false,
resize: this.props.resize || [{
screen: 1199,
diameter: 130
}, {
screen: 991,
diameter: 100
}, {
screen: 767,
diameter: 80
}, {
screen: 575,
diameter: 50
}]
};
this.move = this.move.bind(this);
}
render() {
let {
images,
cursor,
transform,
width,
height,
dim,
sensor,
type,
backgroundColor
} = this.state;
let parentClass = cursor ? 'x-ray-photo-parent' : 'x-ray-photo-parent cursor-none';
let parentTransform = transform ? 'x-ray-last-photo transform' : 'x-ray-last-photo';
let lastImage = transform ? 'x-ray-last-photo-img transform' : 'x-ray-last-photo-img';
let lastStyle = {
width: `${dim}px`,
height: `${dim}px`,
backgroundColor
};
return React.createElement("div", {
className: parentClass
}, React.createElement("img", {
ref: img => {
this.firstImg = img;
},
src: images[0],
alt: "first-photo",
className: "x-ray-first-photo"
}), React.createElement("div", {
ref: zoom => {
this.zoom = zoom;
},
className: parentTransform,
style: lastStyle
}, type === 'magnifyingGlass' ? React.createElement("div", {
className: "magnifyingGlass"
}) : null, React.createElement("div", {
className: "x-ray-last-photo-img-parent"
}, React.createElement("img", {
ref: img => {
this.lastImg = img;
},
style: {
width: `${width}px`,
height: `${height}px`
},
src: images[1],
alt: "last-photo",
className: lastImage
}))), React.createElement("div", {
className: "x-ray-sensor",
style: sensor,
onMouseMove: this.move
}));
}
}