From 11209e39f16eeb7a432b62ba9bc815c65976f29f Mon Sep 17 00:00:00 2001 From: razgraf Date: Sun, 15 Nov 2020 15:32:50 +0200 Subject: [PATCH 1/2] control for outside slider handler --- .gitignore | 2 +- dist/ReactCompareImage.d.ts | 23 +++++++++++++++++++++++ dist/bundle.js | 1 + src/ReactCompareImage.tsx | 6 ++++++ stories/index.stories.tsx | 18 ++++++++++++++++++ 5 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 dist/ReactCompareImage.d.ts create mode 100644 dist/bundle.js diff --git a/.gitignore b/.gitignore index af38950..88abc46 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ .DS_Store -dist +# dist node_modules storybook-static yarn-error.log diff --git a/dist/ReactCompareImage.d.ts b/dist/ReactCompareImage.d.ts new file mode 100644 index 0000000..e097939 --- /dev/null +++ b/dist/ReactCompareImage.d.ts @@ -0,0 +1,23 @@ +import React from 'react'; +interface IProps { + aspectRatio?: 'taller' | 'wider'; + handle?: React.ReactNode; + handleSize?: number; + hover?: boolean; + leftImage: string; + leftImageAlt?: string; + leftImageCss?: object; + leftImageLabel?: string; + onSliderPositionChange?: (position: number) => void; + rightImage: string; + rightImageAlt?: string; + rightImageCss?: object; + rightImageLabel?: string; + skeleton?: React.ReactNode; + sliderLineColor?: string; + sliderLineWidth?: number; + sliderPositionPercentage?: number; + vertical?: boolean; +} +declare const ReactCompareImage: React.FC; +export default ReactCompareImage; diff --git a/dist/bundle.js b/dist/bundle.js new file mode 100644 index 0000000..4681b00 --- /dev/null +++ b/dist/bundle.js @@ -0,0 +1 @@ +module.exports=function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}return r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="/dist/",r(r.s=1)}([function(e,t){e.exports=require("react")},function(e,t,r){"use strict";r.r(t);var n=r(0),o=r.n(n);function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t{const{aspectRatio:t,handle:r,handleSize:a,hover:l,leftImage:s,leftImageAlt:u,leftImageCss:c,leftImageLabel:d,onSliderPositionChange:p,rightImage:f,rightImageAlt:g,rightImageCss:b,rightImageLabel:h,skeleton:m,sliderLineColor:x,sliderLineWidth:v,sliderPositionPercentage:w,vertical:y}=e,O=!y,[E,j]=Object(n.useState)(w),[L,S]=Object(n.useState)(0),[I,P]=Object(n.useState)(0),[C,$]=Object(n.useState)(!1),[R,k]=Object(n.useState)(!1),[z,A]=Object(n.useState)(!1),D=Object(n.useRef)(null),M=Object(n.useRef)(null),_=Object(n.useRef)(null);Object(n.useEffect)(()=>{j(w)},[w]),Object(n.useEffect)(()=>{const e=D.current,t=new ResizeObserver(([e,...t])=>{const r=e.target.getBoundingClientRect().width;S(r)});return t.observe(e),()=>t.disconnect()},[]),Object(n.useEffect)(()=>(_.current.complete&&$(!0),()=>{$(!1)}),[s]),Object(n.useEffect)(()=>(M.current.complete&&k(!0),()=>{k(!1)}),[f]);const W=R&&C;Object(n.useEffect)(()=>{const e=e=>{const t=e||window.event,r=t.touches?t.touches[0].pageX:t.pageX,n=t.touches?t.touches[0].pageY:t.pageY,o=r-window.pageXOffset,a=n-window.pageYOffset,i=M.current.getBoundingClientRect();let l=O?o-i.left:a-i.top;const s=0+v/2,u=O?L-v/2:I-v/2;lu&&(l=u),j(O?l/L:l/I),p&&p(O?l/L:l/I)},r=t=>{A(!0),"touches"in t||t.preventDefault(),e(t),window.addEventListener("mousemove",e),window.addEventListener("touchmove",e)},n=()=>{A(!1),window.removeEventListener("mousemove",e),window.removeEventListener("touchmove",e)},o=D.current;if(W){o.addEventListener("touchstart",r),window.addEventListener("touchend",n),l?(o.addEventListener("mousemove",e),o.addEventListener("mouseleave",n)):(o.addEventListener("mousedown",r),window.addEventListener("mouseup",n));const a=_.current.naturalHeight/_.current.naturalWidth,i=M.current.naturalHeight/M.current.naturalWidth,s="taller"===t?Math.max(a,i):Math.min(a,i);P(L*s)}return()=>{o.removeEventListener("touchstart",r),window.removeEventListener("touchend",n),o.removeEventListener("mousemove",e),o.removeEventListener("mouseleave",n),o.removeEventListener("mousedown",r),window.removeEventListener("mouseup",n),window.removeEventListener("mousemove",e),window.removeEventListener("touchmove",e)}},[W,t,I,L,O,l,v,y]);const F={container:{boxSizing:"border-box",position:"relative",width:"100%",height:I+"px",overflow:"hidden"},rightImage:i({clip:O?`rect(auto, auto, auto, ${L*E}px)`:`rect(${I*E}px, auto, auto, auto)`,display:"block",height:"100%",objectFit:"cover",position:"absolute",width:"100%"},b),leftImage:i({clip:O?`rect(auto, ${L*E}px, auto, auto)`:`rect(auto, auto, ${I*E}px, auto)`,display:"block",height:"100%",objectFit:"cover",position:"absolute",width:"100%"},c),slider:{alignItems:"center",cursor:!l&&O?"ew-resize":!l&&!O&&"ns-resize",display:"flex",flexDirection:O?"column":"row",height:O?"100%":a+"px",justifyContent:"center",left:O?L*E-a/2+"px":0,position:"absolute",top:O?0:I*E-a/2+"px",width:O?a+"px":"100%"},line:{background:x,boxShadow:"0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12)",flex:"0 1 auto",height:O?"100%":v+"px",width:O?v+"px":"100%"},handleCustom:{alignItems:"center",boxSizing:"border-box",display:"flex",flex:"1 0 auto",height:"auto",justifyContent:"center",width:"auto"},handleDefault:{alignItems:"center",border:`${v}px solid ${x}`,borderRadius:"100%",boxShadow:"0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12)",boxSizing:"border-box",display:"flex",flex:"1 0 auto",height:a+"px",justifyContent:"center",width:a+"px",transform:O?"none":"rotate(90deg)"},leftArrow:{border:`inset ${.15*a}px rgba(0,0,0,0)`,borderRight:`${.15*a}px solid ${x}`,height:"0px",marginLeft:`-${.25*a}px`,marginRight:.25*a+"px",width:"0px"},rightArrow:{border:`inset ${.15*a}px rgba(0,0,0,0)`,borderLeft:`${.15*a}px solid ${x}`,height:"0px",marginRight:`-${.25*a}px`,width:"0px"},leftLabel:{background:"rgba(0, 0, 0, 0.5)",color:"white",left:O?"5%":"50%",opacity:z?0:1,padding:"10px 20px",position:"absolute",top:O?"50%":"3%",transform:O?"translate(0,-50%)":"translate(-50%, 0)",transition:"opacity 0.1s ease-out"},rightLabel:{background:"rgba(0, 0, 0, 0.5)",color:"white",opacity:z?0:1,padding:"10px 20px",position:"absolute",left:O?null:"50%",right:O?"5%":null,top:O?"50%":null,bottom:O?null:"3%",transform:O?"translate(0,-50%)":"translate(-50%, 0)",transition:"opacity 0.1s ease-out"},leftLabelContainer:{clip:O?`rect(auto, ${L*E}px, auto, auto)`:`rect(auto, auto, ${I*E}px, auto)`,height:"100%",position:"absolute",width:"100%"},rightLabelContainer:{clip:O?`rect(auto, auto, auto, ${L*E}px)`:`rect(${I*E}px, auto, auto, auto)`,height:"100%",position:"absolute",width:"100%"}};return o.a.createElement(o.a.Fragment,null,m&&!W&&o.a.createElement("div",{style:i({},F.container)},m),o.a.createElement("div",{style:i(i({},F.container),{},{display:W?"block":"none"}),ref:D,"data-testid":"container"},o.a.createElement("img",{onLoad:()=>k(!0),alt:g,"data-testid":"right-image",ref:M,src:f,style:F.rightImage}),o.a.createElement("img",{onLoad:()=>$(!0),alt:u,"data-testid":"left-image",ref:_,src:s,style:F.leftImage}),o.a.createElement("div",{style:F.slider},o.a.createElement("div",{style:F.line}),r?o.a.createElement("div",{style:F.handleCustom},r):o.a.createElement("div",{style:F.handleDefault},o.a.createElement("div",{style:F.leftArrow}),o.a.createElement("div",{style:F.rightArrow})),o.a.createElement("div",{style:F.line})),d&&o.a.createElement("div",{style:F.leftLabelContainer},o.a.createElement("div",{style:F.leftLabel},d)),h&&o.a.createElement("div",{style:F.rightLabelContainer},o.a.createElement("div",{style:F.rightLabel},h))))};s.defaultProps={aspectRatio:"taller",handle:null,handleSize:40,hover:!1,leftImageAlt:"",leftImageCss:{},leftImageLabel:null,onSliderPositionChange:()=>{},rightImageAlt:"",rightImageCss:{},rightImageLabel:null,skeleton:null,sliderLineColor:"#ffffff",sliderLineWidth:2,sliderPositionPercentage:.5,vertical:!1},t.default=s}]); \ No newline at end of file diff --git a/src/ReactCompareImage.tsx b/src/ReactCompareImage.tsx index 899ff37..f1fd02a 100644 --- a/src/ReactCompareImage.tsx +++ b/src/ReactCompareImage.tsx @@ -65,6 +65,7 @@ const ReactCompareImage: React.FC = props => { const horizontal = !vertical; // 0 to 1 + const [sliderPosition, setSliderPosition] = useState( sliderPositionPercentage, ); @@ -78,6 +79,11 @@ const ReactCompareImage: React.FC = props => { const rightImageRef = useRef(null); const leftImageRef = useRef(null); + // control the slider position from outside + useEffect(() => { + setSliderPosition(sliderPositionPercentage); + }, [sliderPositionPercentage]) + // make the component responsive useEffect(() => { const containerElement = containerRef.current; diff --git a/stories/index.stories.tsx b/stories/index.stories.tsx index bfbbb18..7a188cd 100644 --- a/stories/index.stories.tsx +++ b/stories/index.stories.tsx @@ -52,6 +52,24 @@ storiesOf('Basic', module) /> )) + .add('controlled slider position', () => { + const [position, setPosition] = useState(0); + const [value, setValue] = useState(0); + return ( +
+
+ setValue(e.target.value)} /> + +
+ +
slider position: {position}
+
+ ); + }) .add('detect slider position change', () => { const [position, setPosition] = useState(null); return ( From 21756a77c24da46fff845971a2e45bca7c04d944 Mon Sep 17 00:00:00 2001 From: razgraf Date: Sun, 15 Nov 2020 15:51:02 +0200 Subject: [PATCH 2/2] remove dist --- .gitignore | 2 +- dist/ReactCompareImage.d.ts | 23 ----------------------- dist/bundle.js | 1 - 3 files changed, 1 insertion(+), 25 deletions(-) delete mode 100644 dist/ReactCompareImage.d.ts delete mode 100644 dist/bundle.js diff --git a/.gitignore b/.gitignore index 88abc46..af38950 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ .DS_Store -# dist +dist node_modules storybook-static yarn-error.log diff --git a/dist/ReactCompareImage.d.ts b/dist/ReactCompareImage.d.ts deleted file mode 100644 index e097939..0000000 --- a/dist/ReactCompareImage.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -import React from 'react'; -interface IProps { - aspectRatio?: 'taller' | 'wider'; - handle?: React.ReactNode; - handleSize?: number; - hover?: boolean; - leftImage: string; - leftImageAlt?: string; - leftImageCss?: object; - leftImageLabel?: string; - onSliderPositionChange?: (position: number) => void; - rightImage: string; - rightImageAlt?: string; - rightImageCss?: object; - rightImageLabel?: string; - skeleton?: React.ReactNode; - sliderLineColor?: string; - sliderLineWidth?: number; - sliderPositionPercentage?: number; - vertical?: boolean; -} -declare const ReactCompareImage: React.FC; -export default ReactCompareImage; diff --git a/dist/bundle.js b/dist/bundle.js deleted file mode 100644 index 4681b00..0000000 --- a/dist/bundle.js +++ /dev/null @@ -1 +0,0 @@ -module.exports=function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}return r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="/dist/",r(r.s=1)}([function(e,t){e.exports=require("react")},function(e,t,r){"use strict";r.r(t);var n=r(0),o=r.n(n);function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t{const{aspectRatio:t,handle:r,handleSize:a,hover:l,leftImage:s,leftImageAlt:u,leftImageCss:c,leftImageLabel:d,onSliderPositionChange:p,rightImage:f,rightImageAlt:g,rightImageCss:b,rightImageLabel:h,skeleton:m,sliderLineColor:x,sliderLineWidth:v,sliderPositionPercentage:w,vertical:y}=e,O=!y,[E,j]=Object(n.useState)(w),[L,S]=Object(n.useState)(0),[I,P]=Object(n.useState)(0),[C,$]=Object(n.useState)(!1),[R,k]=Object(n.useState)(!1),[z,A]=Object(n.useState)(!1),D=Object(n.useRef)(null),M=Object(n.useRef)(null),_=Object(n.useRef)(null);Object(n.useEffect)(()=>{j(w)},[w]),Object(n.useEffect)(()=>{const e=D.current,t=new ResizeObserver(([e,...t])=>{const r=e.target.getBoundingClientRect().width;S(r)});return t.observe(e),()=>t.disconnect()},[]),Object(n.useEffect)(()=>(_.current.complete&&$(!0),()=>{$(!1)}),[s]),Object(n.useEffect)(()=>(M.current.complete&&k(!0),()=>{k(!1)}),[f]);const W=R&&C;Object(n.useEffect)(()=>{const e=e=>{const t=e||window.event,r=t.touches?t.touches[0].pageX:t.pageX,n=t.touches?t.touches[0].pageY:t.pageY,o=r-window.pageXOffset,a=n-window.pageYOffset,i=M.current.getBoundingClientRect();let l=O?o-i.left:a-i.top;const s=0+v/2,u=O?L-v/2:I-v/2;lu&&(l=u),j(O?l/L:l/I),p&&p(O?l/L:l/I)},r=t=>{A(!0),"touches"in t||t.preventDefault(),e(t),window.addEventListener("mousemove",e),window.addEventListener("touchmove",e)},n=()=>{A(!1),window.removeEventListener("mousemove",e),window.removeEventListener("touchmove",e)},o=D.current;if(W){o.addEventListener("touchstart",r),window.addEventListener("touchend",n),l?(o.addEventListener("mousemove",e),o.addEventListener("mouseleave",n)):(o.addEventListener("mousedown",r),window.addEventListener("mouseup",n));const a=_.current.naturalHeight/_.current.naturalWidth,i=M.current.naturalHeight/M.current.naturalWidth,s="taller"===t?Math.max(a,i):Math.min(a,i);P(L*s)}return()=>{o.removeEventListener("touchstart",r),window.removeEventListener("touchend",n),o.removeEventListener("mousemove",e),o.removeEventListener("mouseleave",n),o.removeEventListener("mousedown",r),window.removeEventListener("mouseup",n),window.removeEventListener("mousemove",e),window.removeEventListener("touchmove",e)}},[W,t,I,L,O,l,v,y]);const F={container:{boxSizing:"border-box",position:"relative",width:"100%",height:I+"px",overflow:"hidden"},rightImage:i({clip:O?`rect(auto, auto, auto, ${L*E}px)`:`rect(${I*E}px, auto, auto, auto)`,display:"block",height:"100%",objectFit:"cover",position:"absolute",width:"100%"},b),leftImage:i({clip:O?`rect(auto, ${L*E}px, auto, auto)`:`rect(auto, auto, ${I*E}px, auto)`,display:"block",height:"100%",objectFit:"cover",position:"absolute",width:"100%"},c),slider:{alignItems:"center",cursor:!l&&O?"ew-resize":!l&&!O&&"ns-resize",display:"flex",flexDirection:O?"column":"row",height:O?"100%":a+"px",justifyContent:"center",left:O?L*E-a/2+"px":0,position:"absolute",top:O?0:I*E-a/2+"px",width:O?a+"px":"100%"},line:{background:x,boxShadow:"0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12)",flex:"0 1 auto",height:O?"100%":v+"px",width:O?v+"px":"100%"},handleCustom:{alignItems:"center",boxSizing:"border-box",display:"flex",flex:"1 0 auto",height:"auto",justifyContent:"center",width:"auto"},handleDefault:{alignItems:"center",border:`${v}px solid ${x}`,borderRadius:"100%",boxShadow:"0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12)",boxSizing:"border-box",display:"flex",flex:"1 0 auto",height:a+"px",justifyContent:"center",width:a+"px",transform:O?"none":"rotate(90deg)"},leftArrow:{border:`inset ${.15*a}px rgba(0,0,0,0)`,borderRight:`${.15*a}px solid ${x}`,height:"0px",marginLeft:`-${.25*a}px`,marginRight:.25*a+"px",width:"0px"},rightArrow:{border:`inset ${.15*a}px rgba(0,0,0,0)`,borderLeft:`${.15*a}px solid ${x}`,height:"0px",marginRight:`-${.25*a}px`,width:"0px"},leftLabel:{background:"rgba(0, 0, 0, 0.5)",color:"white",left:O?"5%":"50%",opacity:z?0:1,padding:"10px 20px",position:"absolute",top:O?"50%":"3%",transform:O?"translate(0,-50%)":"translate(-50%, 0)",transition:"opacity 0.1s ease-out"},rightLabel:{background:"rgba(0, 0, 0, 0.5)",color:"white",opacity:z?0:1,padding:"10px 20px",position:"absolute",left:O?null:"50%",right:O?"5%":null,top:O?"50%":null,bottom:O?null:"3%",transform:O?"translate(0,-50%)":"translate(-50%, 0)",transition:"opacity 0.1s ease-out"},leftLabelContainer:{clip:O?`rect(auto, ${L*E}px, auto, auto)`:`rect(auto, auto, ${I*E}px, auto)`,height:"100%",position:"absolute",width:"100%"},rightLabelContainer:{clip:O?`rect(auto, auto, auto, ${L*E}px)`:`rect(${I*E}px, auto, auto, auto)`,height:"100%",position:"absolute",width:"100%"}};return o.a.createElement(o.a.Fragment,null,m&&!W&&o.a.createElement("div",{style:i({},F.container)},m),o.a.createElement("div",{style:i(i({},F.container),{},{display:W?"block":"none"}),ref:D,"data-testid":"container"},o.a.createElement("img",{onLoad:()=>k(!0),alt:g,"data-testid":"right-image",ref:M,src:f,style:F.rightImage}),o.a.createElement("img",{onLoad:()=>$(!0),alt:u,"data-testid":"left-image",ref:_,src:s,style:F.leftImage}),o.a.createElement("div",{style:F.slider},o.a.createElement("div",{style:F.line}),r?o.a.createElement("div",{style:F.handleCustom},r):o.a.createElement("div",{style:F.handleDefault},o.a.createElement("div",{style:F.leftArrow}),o.a.createElement("div",{style:F.rightArrow})),o.a.createElement("div",{style:F.line})),d&&o.a.createElement("div",{style:F.leftLabelContainer},o.a.createElement("div",{style:F.leftLabel},d)),h&&o.a.createElement("div",{style:F.rightLabelContainer},o.a.createElement("div",{style:F.rightLabel},h))))};s.defaultProps={aspectRatio:"taller",handle:null,handleSize:40,hover:!1,leftImageAlt:"",leftImageCss:{},leftImageLabel:null,onSliderPositionChange:()=>{},rightImageAlt:"",rightImageCss:{},rightImageLabel:null,skeleton:null,sliderLineColor:"#ffffff",sliderLineWidth:2,sliderPositionPercentage:.5,vertical:!1},t.default=s}]); \ No newline at end of file