HTML Filters: Titles, Scrolling Credits, Stopwatches, Gauges etc

Hi Elusien, just a quick note to say I’m really keen to experiment with the webfvx animations but spare time is very short at the moment (due to pressures of work!) so I have been unable to get to “play” with the code for the past few days. I really appreciate your help with the webfx framework. Will be in touch when I get chance to experiment. I do have more animations which I hope can be adapted with webfx and I’ll send the code to you when I’ve found time to get to it.
Thanks again
Jon

“work”, let me think, I used to know what that was. I seem to remember it came before “retirement”. If you need any assistance just let me know.

1 Like

I just found a short span of free time in which I made a new HTML video title animation. I wrote the code using CSS and Elusien’s webvfx framework.

I opened the html file in an Overlay HTML filter applied to a clip created by selecting “open other > color” (set to a duration of 10 seconds, the same as the html code (see where it says"10:60" on the code below - which means 10 seconds long at 60 frames per second).

I am happy to report that IT WORKS!!

The exported video from Shotcut looks like THIS:

There are still problems to overcome - the text and animated dots are not centred (although I centred them manually in my Chrome browser when I created the animation. It was all centered when viewed on my desktop screen). I suspect the shotcut screen has a different resolution to my browser (?).

I am really happy that this appears to work and I will be working and experimenting with on more animations when I can find some time.

THANK you, Elusien, for your brilliant work on your webfx framework. Any comments/ suggestions would be gratefully received!

Here is the HTML code. Feel free to copy /paste and experiment. Make sure that Elusien’s file “webvfx.js” is downloaded and located in the same folder as the html file.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   
<html 
    <head>
	
	</head>
                
        <title>Webvfx test</title>
		
		<style> 
		
		body {
  background-color: #167489; 
 
}

div {overflow: visible; 
font-family: arial; 
position: absolute;
opacity: 0;

	}


#title01 {
		font-size:150px;
		color:white;
	}
	
	#title02 {
		font-size:60px;
		color:white;
		left:630px; 
		top: 400px;
	}
	
	
	#square01 {
height: 8px;
width: 8px;
background-color: white;
}

#square02 {
height: 8px;
width: 8px;
background-color: white;
}

#square03 {
height: 8px;
width: 8px;
background-color: white;
}

#square04 {
height: 8px;
width: 8px;
background-color: white;
}

#square05 {
height: 8px;
width: 8px;
background-color: white;
}

#square06 {
height: 8px;
width: 8px;
background-color: white;
}

#square07 {
height: 8px;
width: 8px;
background-color: white;
}

#square08 {
height: 8px;
width: 8px;
background-color: white;
}

#square09 {
height: 8px;
width: 8px;
background-color: white;
}

</style>

		<body>	
		
<div id="title01" data-control="8:60" class='webvfx' data-animate='{start: 0, end: 0.4, ease: "easeInOutSine",
	  0% : {opacity:0; left:530px; top: 200px;},
	100% : {opacity:1; left:530px; top: 200px;}
}'>Bournville</div>

<div id="square01"  class='webvfx' data-animate='{start: 0.2, end: 0.4, ease: "easeInOutSine",
	  0% : {opacity:0; left:0px; top: 380px;},
	100% : {opacity:1; left:1180px; top: 380px;}
}'></div>

<div id="square02"  class='webvfx' data-animate='{start: 0.2, end: 0.4, ease: "easeInOutSine",
	  0% : {opacity:0; left:0px; top: 380px;},
	100% : {opacity:1; left:1098px; top: 380px;}
}'></div>

<div id="square03"  class='webvfx' data-animate='{start: 0.2, end: 0.4, ease: "easeInOutSine",
	  0% : {opacity:0; left:0px; top: 380px;},
	100% : {opacity:1; left:1016px; top: 380px;}
}'></div>

<div id="square04"  class='webvfx' data-animate='{start: 0.2, end: 0.4, ease: "easeInOutSine",
	  0% : {opacity:0; left:0px; top: 380px;},
	100% : {opacity:1; left:934px; top: 380px;}
}'></div>

<div id="square05"  class='webvfx' data-animate='{start: 0.2, end: 0.4, ease: "easeInOutSine",
	  0% : {opacity:0; left:0px; top: 380px;},
	100% : {opacity:1; left:852px; top: 380px;}
}'></div>

<div id="square06"  class='webvfx' data-animate='{start: 0.2, end: 0.4, ease: "easeInOutSine",
	  0% : {opacity:0; left:0px; top: 380px;},
	100% : {opacity:1; left:770px; top: 380px;}
}'></div>

<div id="square07"  class='webvfx' data-animate='{start: 0.2, end: 0.4, ease: "easeInOutSine",
	  0% : {opacity:0; left:0px; top: 380px;},
	100% : {opacity:1; left:688px; top: 380px;}
}'></div>

<div id="square08"  class='webvfx' data-animate='{start: 0.2, end: 0.4, ease: "easeInOutSine",
	  0% : {opacity:0; left:0px; top: 380px;},
	100% : {opacity:1; left:606px; top: 380px;}
}'></div>

<div id="square09"  class='webvfx' data-animate='{start: 0.2, end: 0.4, ease: "easeInOutSine",
	  0% : {opacity:0; left:0px; top: 380px;},
	100% : {opacity:1; left:520px; top: 380px;}
}'></div>

<div id="title02"  class='webvfx' data-animate='{start: 0.4, end: 0.7, ease: "easeInOutSine",
	  0% : {opacity:0; transform: scale(0.96, 0.96);},
	100% : {opacity:1; transform: scale(1, 1);}
	
}'>Heaven On Earth</div>


</body>
<script src="WebVfx.js"></script>
</html>

Looking good.

The easiest way to get it centred is to enclose the DIVs within a centred DIV whose height and width have just the correct dimensions (height x width) to encompass them.

To get a centred DIV make it a child of the “<body>” element and specify it as “position: absolute”. Then specify “top” and “left” to be “50%” and set the top-margin to MINUS half the height and the left-margin to MINUS half the width e.g.:

<div id='centred'></div>

#centred {height: 200px; width: 800px; padding: 0;
      top: 50%; left:50%; position: absolute;
      margin: -100px 0 0 -400px;
      background-color:#f00;
      }

Obviously you’ll have to change the left & top values of the animated divs to be relative to the centred div, not the <body> element.

Hi Elusien, that’s fantastic - thank you for the centering advice and html code. I’ll try it out but it won’t be until the weekend if I;m lucky (sadly I haven’t quite reached the dizzy heights of retirement yet, like yourself…):tired_face:

My immediate thoughts - I can see that the above code will centre the text, but I’m wondering how to handle the moving small squares to keep the centred effect, which are positioned using exact pixels measured from the left. Would I have to use lots of trial and error to position each square exactly, or is there an easier way? (I wondered if I could use a relative position in percentage (say left:36%; left:34%) etc…? Would that be compatible with webvfx?

Another idea I had to centre the animation in shotcut was to make the HTML background color of the body transparent, apply the overlay HTML filter to a transparent clip placed on a second video track, (with a coloured clip on V1) then use the size/position filter to move the whole animation into a centre position. Do you think this would work?

Looking forward to having a play with it.

Any advice on any of this would be gratefully received. Thanks again,
Jon

Jonray,

My framework can handle the animation of anything that has a number in it e.g.

  • 100px animated to 222.75px;
  • 10em to 15.5em
  • 0.5 to 0.83
  • 100% to 55.832%
  • #FFF to #0a7e92
  • rgba(256, 128, 53, 1) to rgba(113, 205, 177, 0.554)
  • hsl(30, 100%, 40.5%) to hsl(75, 90.7%, 82%)

Regarding the small square DIVs etc, the “left” position will be relative to the left-hand side of the centred div. If you have “overflow: hidden” specified for the centred div, then the small squares will not appear outside that box. Position 0px will be right up against the edge of the centred box.

The default is “overflow: visible”, so then, if you have left: -50px, the squares would be visible, even when they are outside the centred box.

Once you have everything set positioned correctly relative to the centred box it should then also be positioned correctly in the browser and in Shotcut. the size of the browser page or resolution of the Shotcut frames shouldn’t in theory matter.

Using percentages is a good idea, as it allows the animation to grow in size to match any resolution you use.

I haven’t thought of using the size/position filter of Shotcut to achieve centring, it might be worth trying it to see if it makes it easier to do.

Once again, thank you for your speedy and comprehensive reply, Elusien, I look forward to experimenting! I will post on the forum soon to report how I get on…

Hi Elusien,
I wondered if you could help me? I’ve made great progress getting to use your HTML WebVfx framework, and solved the problem of centering the text, using your invaluable advice (3 posts above): actually I did it by wrapping the animation divs in a container div and setting the css to :
#container {
height: 1080px;
width: 1920px; /* (the default resolution in shotcut) /
padding: 0;
top: 50%;
left:50%;
position: absolute;
margin: -540px 0 0 -960px; /
(half the height/width) */
background-color:#63a2d8;
opacity:1;
}

THEN: I set the main title div (“Bournville”) to width:100%; text-align:center; (and the same for the sub-title div). This centres the text nicely.

I’ve tweaked my “Bournville” animation accordingly and also made a few extra changes - but I’ve hit a problem.

When viewed in Chrome (with data-control=“8:60”) the animation looks like this (this is a screen capture):

But when imported into Shotcut’s HTML Overlay filter and exported, it comes out much slower:

Is there an easy way of speeding up the exported animation? I tried reducing the length of the clip which the HTML Overlay filter was applied to - in the timeline, but it didn’t seem to make any difference. The only way I could get it to speed up was to change the start and end times of each div. - but I don’t really understand what I’m doing with this aspect.
Also am I right in thinking that (for example) a start time of 0.1 would equate to 1 second in Shotcut and so on (ie ten times the value)?

Thanks. I hope to find a little more time today and over the weekend to experiment further…
Thanks
Jon.

Oops, I just tried to post the full html code of the above animation but it didn’t work. Perhaps I reached the maximum character limit? Is there a good way of attaching .txt files to posts on here?
Thanks!
Jon

Just trying to attach the .txt file of the above animation.Video Title Animation by Jon Raybould HTML and WEBVFX - Bournville fade in with moving white boxes.txt (3.7 KB)
Did it work OK? I used the upload button.

Just read your posts. I’ll have a look. The animation ON THE EXPORTED VIDEO should only last as long as the clip is. So if the clip is 10 seconds long it should only be 10 seconds long on the exported video.

It will vary when you look at the clip IN REALTIME depending on how much work Shotcut has to do to show the frames.

Can I double-check that the video you posted above was the exported video file and not a video capture of the Shotcut application with the setting “Realtime (frame dropping)” unset?

The uploading worked by the way, so I can have a look at it on my Surface Pro after dinner tonight.

Regarding the query about a time of 0.1, this equates to 10% (0.1) of the length of the clip to which the filter is applied. So for a 10 second clip it means 1 second, for a 60 second clip it equates to 6 seconds.

Just ran your WebVfx Overlay HTML filter in Shotcut on a 10 second clip. The display in Shotcut took about 18 seconds to run, but the exported clip took 10 seconds, as expected.

As I said earlier, the Shotcut display will take a varying amount of time to run the clip, unless you tick the setting "Realtime (Dropping Frames), in which case it will take 10 seconds, but will appear to be jerky as frames get dropped in order to run the clip in real-time. The exported video is always correct (10 seconds).

I created the 10 second clip by using:

  • File -> Open Other -> Color -> OK

Then I used the slider to whittle it down to 10 seconds before adding it to the timeline. Then I rewound the clip to get the play/record head to the beginning of the clip and I then applied the filter.

Great, thanks for your replies, Elusien. Yes, firstly, the first video I posted above was a screen capture, using ShareX, of the html rendered in Chrome. I just started ShareX recording and double-clicked the html file so it opened up in Chrome, capturing the whole process. I then edited the resulting mp4 using Shotcut by cropping the edges out. Maybe I shouldn’t have cropped it, to make it clear.

Ah, that might be where I was going wrong. I may not have done this, and I think it could be important. I’ll have a play with that.

Thanks for your help - this is really helpful. Meantime, I did some work on a couple more animations this afternoon. I’ll post them and I’d value your comments, but Is it OK with you if I start a new thread with this since I feel I’ve hi-jacked your thread far too much already!!?
Regards
Jon
PS Thanks for the heads-up about the “Realtime (Dropping frames)” setting. I just checked - it’s on by default in my version. That would answer my next question about why the Shotcut display was very choppy and fragmented.

A - HA! Success! Thank you. Here is the animation applied to a 10-second clip:

… and the same animation applied to a 20 - second clip:

  • much slower, although I don’t think the second clip appears exactly twice as slow as the first (just an observation without actually timing it). [EDIT -actually I think it IS going half- speed - the dots finish their travel at 3 seconds in the first slip and at 6 seconds in the second clip ].

I think your advice about applying the filter whilst the playhead is at the beginning of the clip is probably crucial.

Here’s another animated video title I just created. I did it to experiment with making the HTML background transparent to see if it would work over a movie clip. Woo Hoo - it works!

Here it is:

https://streamable.com/emzaa

The animation consists of fade-ins, fade-outs, and the main Scotland title has animated letter-spacing which perhaps I could have made more obvious. After the title shows, the whole text and line fades out. I did this in HTML by wrapping the content of the animation in a div called “Section” and applying a fade-out to the whole section.

I attach the full code as a .txt file in case anyone would like to experiment with it. Note - you’ll have to download a font called “Adequate” for the “Scotland” text to appear as it is in my video. Unless you change the font in the HTML code.

Text file:Scotland Land of Mountains HTML WbVfx experiment by Jon Raybould with fade out HTML.txt (2.1 KB)

Jon, very professional-looking. I’m glad to see you’re making good use of the framework I developed.

I am looking at one or two other things at the moment that might be useful to do with 3-D and so-on. I’ll post in a new thread when it’s ready for people to experiment with.

Brilliant, will look forward to seeing that.

@Elusien how would I use this for a css/jquery carousel? the css uses @keyframes for the rotation. I am able to view the html fine in browser but running with qmelt to with the html as a filter it doesnt animate at all. Not sure about how to use this with the current html/css I have. Should I be replacing items where transition: ease-out; is?

I assume you are trying to port the code shown here:

There are several problems:

Firstly, the images are provided using using HTTPS, which Shotcut does not support. Either copy the images in a local directory on your computer and use these or find images that are supplied using HTTP.

Secondly, CSS animations like “transform” won’t work, you have to use “-webkit-transform” syntax instead.

Thirdly, some CSS directives, such as “perspective: 1000px” won’t work even if you use the “-webkit-” syntax, as they are not (yet) supported in Shotcut.

Lastly, Shotcut does not handle CSS-only animations well. Simply taking an example that works in a browser and using that as a simple Overlay HTML filter is highly unlikely to work the same as it does in the browser and is more than likely going to hang Shotcut.

Your best bet is to convert the CSS-only animation to a Javascript one and use WebVfx to integrate it tightly into the video frames, but even then, with certain key CSS directives being supported you are limited to what you can do.

See: www.elusien.co.uk/shotcut

I’ve modified the HTML/CSS of the example to (almost) work, but as I said, key directives have to implemented before it will work properly.

I’ll have a look at improving this using my framework, but I’m a bit busy just now, so it will be a little while.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style> 
/* 3D Slideshow */ 
* {
	margin: 0;
	padding: 0;
}

html, body {
	max-width: 100%;
	overflow-x: hidden;
	overflow-y: auto;
	background-color: #6adecd;
}

#slideshow {
	margin: 0 auto;
	padding-top: 50px;
	height: 600px;
	width: 100%;
	background-color: #6adecd;
	box-sizing: border-box;
}

.slideshow-title {
	font-family: 'Allerta Stencil';
	font-size: 62px;
	color: #fff;
	margin: 0 auto;
	text-align: center;
	margin-top: 25%;
	letter-spacing: 3px;
	font-weight: 300;
}

.sub-heading {
	padding-top: 50px;
	font-size: 18px;
} .sub-heading-two {
	font-size: 15px;
} .sub-heading-three {
	font-size: 13px;
} .sub-heading-four {
	font-size: 11px;
} .sub-heading-five {
	font-size: 9px;
} .sub-heading-six {
	font-size: 7px;
} .sub-heading-seven {
	font-size: 5px;
} .sub-heading-eight {
	font-size: 3px;
} .sub-heading-nine {
	font-size: 1px;
}

.entire-content {
	margin: auto;
	width: 190px;
	perspective: 1000px;
	-webkit-perspective: 1000px;
	position: relative;
	padding-top: 80px;
}

.content-carrousel {
	width: 100%;
	position: absolute;
	float: right;
	animation: rotar 15s infinite linear;
	transform-style: preserve-3d;
	-webkit-animation: rotar 15s infinite linear;
	-webkit-transform-style: preserve-3d;
}

.content-carrousel:hover {
	animation-play-state: paused;
	cursor: pointer;
}

.content-carrousel figure {
	width: 100%;
	height: 120px;
	border: 1px solid #3b444b;
	overflow: hidden;
	position: absolute;
}

.content-carrousel figure:nth-child(1) {
	transform: rotateY(0deg) translateZ(300px); 
	-webkit-transform: rotateY(0deg) translateZ(300px); 
} .content-carrousel figure:nth-child(2) {
	transform: rotateY(40deg) translateZ(300px); 
	-webkit-transform: rotateY(40deg) translateZ(300px); 
} .content-carrousel figure:nth-child(3) {
	transform: rotateY(80deg) translateZ(300px); 
	-webkit-transform: rotateY(80deg) translateZ(300px); 
} .content-carrousel figure:nth-child(4) {
	transform: rotateY(120deg) translateZ(300px); 
	-webkit-transform: rotateY(120deg) translateZ(300px); 
} .content-carrousel figure:nth-child(5) {
	transform: rotateY(160deg) translateZ(300px); 
	-webkit-transform: rotateY(160deg) translateZ(300px); 
} .content-carrousel figure:nth-child(6) {
	transform: rotateY(200deg) translateZ(300px); 
	-webkit-transform: rotateY(200deg) translateZ(300px); 
} .content-carrousel figure:nth-child(7) {
	transform: rotateY(240deg) translateZ(300px); 
	-webkit-transform: rotateY(240deg) translateZ(300px); 
} .content-carrousel figure:nth-child(8) {
	transform: rotateY(280deg) translateZ(300px); 
	-webkittransform: rotateY(280deg) translateZ(300px); 
} .content-carrousel figure:nth-child(9) {
	transform: rotateY(320deg) translateZ(300px); 
	-webkit-transform: rotateY(320deg) translateZ(300px); 
} .content-carrousel figure:nth-child(10) {
	transform: rotateY(360deg) translateZ(300px); 
	-webkit-transform: rotateY(360deg) translateZ(300px); 
} 

.shadow {
	position: absolute;
	box-shadow: 0px 0px 20px 0px #000;
	border-radius: 1px;
}

.content-carrousel img {
	image-rendering: auto;
	transition: all 300ms;
	-webkit-transition: all 300ms;
	width: 100%;
	height: 100%;
}

.content-carrousel img:hover {
	transform: scale(1.2);
	transition: all 300ms;
	-webkit-transform: scale(1.2);
	-webkit-transition: all 300ms;
}

@keyframes rotar {
	from {
		transform: rotateY(0deg);
		-webkit-transform: rotateY(0deg);
	} to {
		transform: rotateY(360deg);
		-webkit-transform: rotateY(360deg);
	}
}

</style>
</head>
<body>
<!-- 3D Slideshow Section --> 
<section id="slideshow">
			<div class="entire-content">
				<div class="content-carrousel">
<!--					<figure class="shadow"><img src="https://images.pexels.com/photos/758733/pexels-photo-758733.jpeg?w=940&h=650&auto=compress&cs=tinysrgb"/></figure>
					<figure class="shadow"><img src="https://images.pexels.com/photos/21261/pexels-photo.jpg?w=940&h=650&auto=compress&cs=tinysrgb"/></figure>
					<figure class="shadow"><img src="https://images.pexels.com/photos/567973/pexels-photo-567973.jpeg?w=940&h=650&auto=compress&cs=tinysrgb"/></figure>
					<figure class="shadow"><img src="https://images.pexels.com/photos/776653/pexels-photo-776653.jpeg?w=940&h=650&auto=compress&cs=tinysrgb"/></figure>
					<figure class="shadow"><img src="https://images.pexels.com/photos/54630/japanese-cherry-trees-flowers-spring-japanese-flowering-cherry-54630.jpeg?w=940&h=650&auto=compress&cs=tinysrgb"/></figure>
					<figure class="shadow"><img src="https://images.pexels.com/photos/131046/pexels-photo-131046.jpeg?w=940&h=650&auto=compress&cs=tinysrgb"/></figure>
					<figure class="shadow"><img src="https://images.pexels.com/photos/302515/pexels-photo-302515.jpeg?w=940&h=650&auto=compress&cs=tinysrgb"/></figure>
					<figure class="shadow"><img src="https://images.pexels.com/photos/301682/pexels-photo-301682.jpeg?w=940&h=650&auto=compress&cs=tinysrgb"/></figure>
					<figure class="shadow"><img src="https://images.pexels.com/photos/933054/pexels-photo-933054.jpeg?w=940&h=650&auto=compress&cs=tinysrgb"/></figure>
		</div>
	</div> -->
			<figure class="shadow"><img src='http://trips.elusien.co.uk/2017c-New_Zealand/images/Day10a+Gannet_Colony.JPG'      ></figure>                                              
			<figure class="shadow"><img src='http://trips.elusien.co.uk/2017c-New_Zealand/images/Day10b+Gannets.JPG'            ></figure>
			<figure class="shadow"><img src='http://trips.elusien.co.uk/2017c-New_Zealand/images/Day10d+Bethells_Beach_Cave.JPG'></figure>
			<figure class="shadow"><img src='http://trips.elusien.co.uk/2017c-New_Zealand/images/Day10e+Karakare_Falls.JPG'     ></figure>

</section>
</body>
</html>

This gives me something to work with. Any help is appreciated as well. And what you have done so far is ten times better than what I had. Each image was stacked only showing one initially. Thanks again