Привет, ребята, так что я действительно боролся с этим. По сути, я хочу визуализировать видео на холсте и позволить пользователю печатать на нем текст и, в конечном итоге, отображать его как mp4. У меня есть код на этой ручке. Но мне пришлось выложить видео за пределы холста. Есть ли способ получить видео внутри холста или нет? Можно ли сделать простое приложение, в котором вы загружаете видео и пишете текст в реальном времени и можете его скачать. Мой код пера
или просмотреть его здесь:
<style>
.section {
font-size: 17px;
line-height: 1.47059;
font-weight: 400;
letter-spacing: -0.022em;
font-family: "SF Pro Text", "SF Pro Icons", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
background-color: #000;
color: #fff;
font-style: normal;
}
.section-hero {
position: relative;
z-index: 1;
overflow: hidden;
height: 90vh;
min-height: 620px;
max-height: 980px;
}
.section-hero .hero-content {
position: relative;
z-index: 1;
height: 100%;
}
.football-hero .hero-video-container {
background-repeat: no-repeat;
}
.hero-video-container {
background-repeat: no-repeat;
position: absolute;
z-index: 1;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-size: cover;
background-position: center top;
transition: opacity 0.5s ease-in-out;
}
hero-video {
background-size: cover;
background-position: center top;
display: block;
position: absolute;
z-index: 1;
top: 0;
left: 50%;
transform: translateX(-50%);
height: 100%;
width: 100%;
min-height: 100%;
min-width: 100%;
}
.section-hero .hero-headline-wrapper {
position: absolute;
z-index: 4;
width: 100%;
top: 40%;
text-align: center;
}
.section-hero .hero-headline {
max-width: 600px;
margin-left: auto;
margin-right: auto;
}
.typography-hero-headline {
font-size: 80px;
line-height: 1;
font-weight: 600;
letter-spacing: -0.005em;
font-family: "SF Pro Display", "SF Pro Icons", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
}
html.svg-clip-path .section-hero .hero-headline {
display: none;
opacity: 0;
transform: translate3d(0, 25px, 0);
}
.visuallyhidden {
position: absolute;
clip: rect(1px 1px 1px 1px);
clip: rect(1px, 1px, 1px, 1px);
-webkit-clip-path: inset(0px 0px 99.9% 99.9%);
clip-path: inset(0px 0px 99.9% 99.9%);
overflow: hidden;
height: 1px;
width: 1px;
padding: 0;
border: 0;
}
.text-mask {
position: relative;
z-index: 1;
overflow: hidden;
-webkit-clip-path: url(#text-mask-svg-path);
clip-path: url(#text-mask-svg-path);
min-height: 160px;
}
.text-mask-screen {
position: absolute;
z-index: 1;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.text-mask-canvas-background {
display: block;
position: absolute;
height: auto;
z-index: 2;
top: 0;
left: 50%;
transform: translateX(-50%);
-webkit-filter: blur(20px) saturate(140%) brightness(300%);
filter: blur(20px) saturate(140%) brightness(300%);
opacity: 0.8;
}
.text-mask-svg {
position: relative;
z-index: 10;
width: 100%;
height: 160px;
}
.text-mask-svg-contnet {
text-anchor: middle;
font-size: 80px;
line-height: 1;
font-weight: 600;
letter-spacing: -0.005em;
font-family: "SF Pro Display", "SF Pro Icons", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
}
.text-mask {
-webkit-text-fill-color: transparent;
-webkit-background-clip: text;
background-position: 50% -146px;
background-size: 1175px 400px;
background-repeat: no-repeat;
background-image: url(https://www.apple.com/v/iphone/photography-how-to/d/images/overview/hero_football_fallback_background_large.jpg);
}
</style>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id = "app">
<input type="file" @change="processFile">
<input type="text" v-model='text1'>
<section class="section section-hero active animated">
<div class="hero-content football-hero" style="opacity: 1; transform: translate3d(0px, 0px, 0px);">
<div class="hero-video-container">
<video id="video" v-if="isVideo" class="hero-video" style="width:100%;height:100%;" autoplay playsinline muted loop :src='source'>
</video>
<img :src ='source' class='hero-video' style="width:100%;height:100%;">
</div>
<div class="hero-headline-wrapper">
<h1 class="hero-headline typography-hero-headline" data-component-list="HeroTextMaskedVideoComponent" style="display: block; opacity: 1; transform: matrix(1, 0, 0, 1, 0, 0);">
<span class="visuallyhidden">Most awesome</span>
<div role="presentation" aria-hidden="true">
{{text1}}
<div class="text-mask" aria-label="on iPhone." style="opacity: 1;">
<div class="text-mask-screen"></div>
<canvas id="canvas" class="text-mask-canvas-background"></canvas>
<svg class="text-mask-svg">
<clipPath id="text-mask-svg-path">
<text class="text-mask-svg-content" x="25%" y="50%">on video</text>
</clipPath>
</svg>
</div>
</div>
</h1>
</div>
</div>
</section>
</div>
<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var video = document.getElementById('video');
video.addEventListener('canplaythrough', function() {
var $this = this; //cache
(function loop() {
if (!$this.paused && !$this.ended) {
ctx.drawImage($this, 0, 0);
setTimeout(loop, 1000 / 30); // drawing at 30fps
}
})();
}, 0);
new Vue({
el: '#app',
data: {
source: null,
text1:"",
type: null,
isVideo: false
},
methods: {
processFile(e){
let file = e.target.files || e.dataTransfer.files;
if(file[0]){
let reader = new FileReader();
reader.readAsDataURL(file[0]);
this.type = file[0].type;
this.isVideo = false;
if(this.type.includes('mp4')){
this.isVideo = true;
}
reader.onload = e => {
this.source = e.target.result;
console.log(this.source);
};}
}
}
});
</script>