import PropTypes from 'prop-types'; import React from 'react'; import bindAll from 'lodash.bindall'; import Box from '../box/box.jsx'; import styles from './loupe.css'; const zoomScale = 3; class LoupeComponent extends React.Component { constructor (props) { super(props); bindAll(this, [ 'setCanvas' ]); } componentDidUpdate () { this.draw(); } draw () { const boxSize = 6 / zoomScale; const boxLineWidth = 1 / zoomScale; const colorRingWidth = 15 / zoomScale; const ctx = this.canvas.getContext('2d'); const {color, data, width, height} = this.props.colorInfo; this.canvas.width = zoomScale * width; this.canvas.height = zoomScale * height; // In order to scale the image data, must draw to a tmp canvas first const tmpCanvas = document.createElement('canvas'); tmpCanvas.width = width; tmpCanvas.height = height; const tmpCtx = tmpCanvas.getContext('2d'); const imageData = tmpCtx.createImageData(width, height); imageData.data.set(data); tmpCtx.putImageData(imageData, 0, 0); // Scale the loupe canvas and draw the zoomed image ctx.save(); ctx.scale(zoomScale, zoomScale); ctx.drawImage(tmpCanvas, 0, 0, width, height); // Draw an outlined square at the cursor position (cursor is hidden) ctx.lineWidth = boxLineWidth; ctx.strokeStyle = 'black'; ctx.fillStyle = `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})`; ctx.beginPath(); ctx.rect((width / 2) - (boxSize / 2), (height / 2) - (boxSize / 2), boxSize, boxSize); ctx.fill(); ctx.stroke(); // Draw a thick ring around the loupe showing the current color ctx.strokeStyle = `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})`; ctx.lineWidth = colorRingWidth; ctx.beginPath(); ctx.moveTo(width, height / 2); ctx.arc(width / 2, height / 2, width / 2, 0, 2 * Math.PI); ctx.stroke(); ctx.restore(); } setCanvas (element) { this.canvas = element; } render () { const { colorInfo, ...boxProps } = this.props; const x = colorInfo.x - ((zoomScale * colorInfo.width) / 2); const y = colorInfo.y - ((zoomScale * colorInfo.height) / 2); return ( ); } } LoupeComponent.propTypes = { colorInfo: PropTypes.shape({ color: PropTypes.shape({ r: PropTypes.number, g: PropTypes.number, b: PropTypes.number, a: PropTypes.number }), data: PropTypes.instanceOf(Uint8Array), width: PropTypes.number, height: PropTypes.number, x: PropTypes.number, y: PropTypes.number }) }; export default LoupeComponent;