123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- let webcam;
-
- class PagePhotograph extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- isCameraEnable: false,
- isPhotoReady: false,
- myImage: null,
- loading: false,
- };
-
- this.refVideo = React.createRef();
- this.refCamvas = React.createRef();
- this.refFileInput = React.createRef();
- this.refVideoContainer = React.createRef();
- }
-
- goNext = (base64) => {
- this.props.next(base64);
- }
-
- goBack = () => {
- this.props.back();
- }
-
- onLoadedmetadata = () => {
- const { refVideoContainer, refVideo } = this;
- refVideoContainer.current.style = '';
- refVideo.current.width = refVideo.current.videoWidth;
- refVideo.current.height = refVideo.current.videoHeight;
- refVideo.current.defaultMuted = true;
- refVideo.current.muted = true;
- refVideo.current.play();
- const VIDEO__Width = refVideo.current.videoWidth;
- const VIDEO__Height = refVideo.current.videoHeight;
- console.log('videoContainer', refVideoContainer.current.clientHeight);
- const _scale = refVideoContainer.current.clientHeight / Math.min(VIDEO__Width, VIDEO__Height);
- this.setState({isCameraEnable: true});
- console.log('isCameraEnable',this.state.isCameraEnable);
- $(refVideoContainer.current).css({
- width: VIDEO__Width,
- height: VIDEO__Height,
- top: '50%',
- left: '50%',
- 'margin-top': VIDEO__Height * -0.5,
- 'margin-left': VIDEO__Width * -0.5,
- });
- gsap.set(refVideoContainer.current, {
- scaleX: _scale,
- scaleY: _scale,
- transformOrigin: 'center center',
- });
- }
-
- initWebcam = () => {
- const { refVideo, refCamvas } = this;
- this.setState({isCameraEnable: false});
- webcam = new Webcam(refVideo.current, 'user', refCamvas.current);
- webcam
- .start()
- .then(() => {})
- .catch((error) => {
- webcam.stop();
- console.log(error);
- alert('妳的瀏覽器不支援相機哦! 請改用左下方按鍵上傳照片,或設定瀏覽器開啟相機。');
- });
- }
-
- onSnapshot = () => {
- const { refVideoContainer } = this;
- const { isCameraEnable } = this.state;
- if (!isCameraEnable) {
- return;
- }
- this.setState({loading: true});
- webcam
- .snap()
- .then(async (base64) => {
- this.setState({myImage: base64});
- const image = await ImageLoader(base64);
- const canvas = Image2Canvas(image, window.innerWidth / window.innerHeight * refVideoContainer.current.clientHeight, refVideoContainer.current.clientHeight);
- const detectSrc = canvas.toDataURL('image/jpg', 1.0);
- const detectImage = await ImageLoader(detectSrc);
- detectFace(detectImage).then(() => {
- this.setState({loading: false});
- this.goNext(detectSrc);
- }).catch((error) => {
- this.setState({loading: false});
- console.log('DetectFace Error\nName:'+error.name+'\nMessage:'+error.message);
- alert(error.message);
- this.onRemake();
- });
- })
- .catch((error) => {
- this.setState({loading: false});
- console.log(`Snapshot Error\nName: ${error.name}\nMessage: ${error.message}`);
- });
- }
-
- flipCamera = () => {
- this.setState({isCameraEnable: false});
- webcam.flip();
- webcam.start();
- }
-
- onRemake = () => {
- this.setState({myImage: ''});
- this.setState({isPhotoReady: false});
- this.setState({isCameraEnable: false});
- this.initWebcam();
- }
-
- onFileChange = (event) => {
- const file = event.target.files[0];
- if (file) {
- const reader = new FileReader();
- reader.onload = (e) => {
- const image = new Image();
- image.onload = () => {
- const canvas = document.createElement('canvas');
- canvas.width = image.width < 640 ? image.width : 640;
- canvas.height = (image.height / image.width) * canvas.width;
- const context = canvas.getContext('2d');
- context.drawImage(image, 0, 0, canvas.width, canvas.height);
- const base64 = canvas.toDataURL('image/jpg', 1.0);
- ImageLoader(base64).then((_img) => {
- this.setState({myImage: base64});
- this.setState({isPhotoReady: true});
- this.setState({loading: true});
- detectFace(_img).then(() => {
- this.setState({loading: false});
- this.goNext(base64);
- }).catch((error) => {
- this.setState({loading: false});
- console.log('DetectFace Error\nName:'+error.name+'\nMessage:'+error.message);
- alert(error.message);
- });
- });
- };
- image.src = e.target.result;
- };
- reader.readAsDataURL(file);
- } else {
- console.log('failed');
- }
- }
-
- componentDidMount() {
- this.refVideo.current.addEventListener('loadedmetadata', this.onLoadedmetadata);
- this.initWebcam();
- }
-
- componentWillUnmount() {
- this.refVideo.current.removeEventListener("loadedmetadata", this.onLoadedmetadata);
- if (webcam) {
- webcam.stop();
- webcam = null;
- }
- }
-
- render() {
- const { goBack, onFileChange, onSnapshot, flipCamera, refVideo, refCamvas, refFileInput, refVideoContainer } = this;
- const { isPhotoReady, myImage, isCameraEnable, loading} = this.state;
- return (
- <div class="photographPage">
- <div class="photographPage__header">
- <div class="btn__back" onClick={goBack}>
- <img src="https://d1xzlli46wohoc.cloudfront.net/assets/images/btn-back.png" alt="" />
- </div>
- </div>
- <div class="photographPage__body">
- <div ref={refVideoContainer} class="video__container">
- <video ref={refVideo} autoPlay={true} muted playsInline></video>
- <canvas id='canvas' ref={refCamvas} ></canvas>
- </div>
- {
- (isPhotoReady) ? (
- <img class="photographPage__userImage" src={myImage} />
- ) : ('')
- }
- <div class="photographPage__facemasker">
- <img src="https://d1xzlli46wohoc.cloudfront.net/assets/images/masker.png" alt="" />
- <div class="photographPage__facemaskerText">請在明亮環境,將臉部對準虛線範圍<br/>確保臉部合成準確,請避免頭髮遮蔽五官!</div>
- </div>
- </div>
- <div class="photographPage__toolbar">
- <img src="https://d1xzlli46wohoc.cloudfront.net/assets/images/tollbar-bg.png" alt="" />
- <div class="photographPage__toolbar__wrapper">
- <div class="btn__insert">
- <img src="https://d1xzlli46wohoc.cloudfront.net/assets/images/icon-insert-photo.png" alt="" />
- <input ref={refFileInput} type="file" accept="image/jpg, image/jpeg, image/png" onChange={onFileChange}/>
- </div>
- <div className={"btn__camera " + (isCameraEnable ? 'is__show' : 'is__hidden')} onClick={onSnapshot}>
- <img src="https://d1xzlli46wohoc.cloudfront.net/assets/images/icon-camera.png" alt="" />
- </div>
- <div className={"btn__flip__camera " + (isCameraEnable ? 'is__show' : 'is__hidden')} onClick={flipCamera}>
- <img src="https://d1xzlli46wohoc.cloudfront.net/assets/images/icon-flip-camera.png" alt="" />
- </div>
- </div>
- </div>
- <LoaderComponent show={loading}></LoaderComponent>
- </div>
- );
- }
- }
-
-
|