1+ // Written by Dor Verbin, October 2021
2+ // This is based on: http://thenewcode.com/364/Interactive-Before-and-After-Video-Comparison-in-HTML5-Canvas
3+ // With additional modifications based on: https://jsfiddle.net/7sk5k4gp/13/
4+
5+ function playVids ( videoId ) {
6+ var videoMerge = document . getElementById ( videoId + "Merge" ) ;
7+ var vid = document . getElementById ( videoId ) ;
8+
9+ var position = 0.5 ;
10+ var vidWidth = vid . videoWidth / 2 ;
11+ var vidHeight = vid . videoHeight ;
12+
13+ var mergeContext = videoMerge . getContext ( "2d" ) ;
14+
15+
16+ if ( vid . readyState > 3 ) {
17+ vid . play ( ) ;
18+
19+ function trackLocation ( e ) {
20+ // Normalize to [0, 1]
21+ bcr = videoMerge . getBoundingClientRect ( ) ;
22+ position = ( ( e . pageX - bcr . x ) / bcr . width ) ;
23+ }
24+ function trackLocationTouch ( e ) {
25+ // Normalize to [0, 1]
26+ bcr = videoMerge . getBoundingClientRect ( ) ;
27+ position = ( ( e . touches [ 0 ] . pageX - bcr . x ) / bcr . width ) ;
28+ }
29+
30+ videoMerge . addEventListener ( "mousemove" , trackLocation , false ) ;
31+ videoMerge . addEventListener ( "touchstart" , trackLocationTouch , false ) ;
32+ videoMerge . addEventListener ( "touchmove" , trackLocationTouch , false ) ;
33+
34+
35+ function drawLoop ( ) {
36+ mergeContext . drawImage ( vid , 0 , 0 , vidWidth , vidHeight , 0 , 0 , vidWidth , vidHeight ) ;
37+ var colStart = ( vidWidth * position ) . clamp ( 0.0 , vidWidth ) ;
38+ var colWidth = ( vidWidth - ( vidWidth * position ) ) . clamp ( 0.0 , vidWidth ) ;
39+ mergeContext . drawImage ( vid , colStart + vidWidth , 0 , colWidth , vidHeight , colStart , 0 , colWidth , vidHeight ) ;
40+ requestAnimationFrame ( drawLoop ) ;
41+
42+
43+ var arrowLength = 0.09 * vidHeight ;
44+ var arrowheadWidth = 0.025 * vidHeight ;
45+ var arrowheadLength = 0.04 * vidHeight ;
46+ var arrowPosY = vidHeight / 10 ;
47+ var arrowWidth = 0.007 * vidHeight ;
48+ var currX = vidWidth * position ;
49+
50+ // Draw circle
51+ mergeContext . arc ( currX , arrowPosY , arrowLength * 0.7 , 0 , Math . PI * 2 , false ) ;
52+ mergeContext . fillStyle = "#FFD79340" ;
53+ mergeContext . fill ( )
54+ //mergeContext.strokeStyle = "#444444";
55+ //mergeContext.stroke()
56+
57+ // Draw border
58+ mergeContext . beginPath ( ) ;
59+ mergeContext . moveTo ( vidWidth * position , 0 ) ;
60+ mergeContext . lineTo ( vidWidth * position , vidHeight ) ;
61+ mergeContext . closePath ( )
62+ mergeContext . strokeStyle = "#AAAAAA" ;
63+ mergeContext . lineWidth = 4 ;
64+ mergeContext . stroke ( ) ;
65+
66+ // Draw arrow
67+ mergeContext . beginPath ( ) ;
68+ mergeContext . moveTo ( currX , arrowPosY - arrowWidth / 2 ) ;
69+
70+ // Move right until meeting arrow head
71+ mergeContext . lineTo ( currX + arrowLength / 2 - arrowheadLength / 2 , arrowPosY - arrowWidth / 2 ) ;
72+
73+ // Draw right arrow head
74+ mergeContext . lineTo ( currX + arrowLength / 2 - arrowheadLength / 2 , arrowPosY - arrowheadWidth / 2 ) ;
75+ mergeContext . lineTo ( currX + arrowLength / 2 , arrowPosY ) ;
76+ mergeContext . lineTo ( currX + arrowLength / 2 - arrowheadLength / 2 , arrowPosY + arrowheadWidth / 2 ) ;
77+ mergeContext . lineTo ( currX + arrowLength / 2 - arrowheadLength / 2 , arrowPosY + arrowWidth / 2 ) ;
78+
79+ // Go back to the left until meeting left arrow head
80+ mergeContext . lineTo ( currX - arrowLength / 2 + arrowheadLength / 2 , arrowPosY + arrowWidth / 2 ) ;
81+
82+ // Draw left arrow head
83+ mergeContext . lineTo ( currX - arrowLength / 2 + arrowheadLength / 2 , arrowPosY + arrowheadWidth / 2 ) ;
84+ mergeContext . lineTo ( currX - arrowLength / 2 , arrowPosY ) ;
85+ mergeContext . lineTo ( currX - arrowLength / 2 + arrowheadLength / 2 , arrowPosY - arrowheadWidth / 2 ) ;
86+ mergeContext . lineTo ( currX - arrowLength / 2 + arrowheadLength / 2 , arrowPosY ) ;
87+
88+ mergeContext . lineTo ( currX - arrowLength / 2 + arrowheadLength / 2 , arrowPosY - arrowWidth / 2 ) ;
89+ mergeContext . lineTo ( currX , arrowPosY - arrowWidth / 2 ) ;
90+
91+ mergeContext . closePath ( ) ;
92+
93+ mergeContext . fillStyle = "#AAAAAA" ;
94+ mergeContext . fill ( ) ;
95+
96+
97+
98+ }
99+ requestAnimationFrame ( drawLoop ) ;
100+ }
101+ }
102+
103+ Number . prototype . clamp = function ( min , max ) {
104+ return Math . min ( Math . max ( this , min ) , max ) ;
105+ } ;
106+
107+
108+ function resizeAndPlay ( element ) {
109+ var cv = document . getElementById ( element . id + "Merge" ) ;
110+ cv . width = element . videoWidth / 2 ;
111+ cv . height = element . videoHeight ;
112+ element . play ( ) ;
113+ element . style . height = "0px" ; // Hide video without stopping it
114+
115+ playVids ( element . id ) ;
116+ }
0 commit comments