웹 프론트엔드 HTML 튜토리얼 HTML을 사용하여 스크롤링 사격 기능을 구현하는 방법

HTML을 사용하여 스크롤링 사격 기능을 구현하는 방법

Jan 17, 2018 am 09:55 AM
html 기능


이번에는 HTML을 사용하여 스크롤 연발 기능을 구현하는 방법을 보여 드리겠습니다. HTML에서 스크롤 연발 기능을 구현할 때 주의 사항은 무엇입니까?

주요 기능은 포격 보내기, 포격의 색상, 속도 및 유형 설정 및 포격 표시입니다.

알려진 결함: 전체 화면이 될 수 없습니다.

캔버스는 적응형이 아닙니다
사용자 정의 플레이어 컨트롤이 없습니다
해당 항목을 기반으로 한 재생이 없습니다. 탄막은 당시에 표시됩니다.
탄막은 호버링할 수 없습니다.
알려진 결함은 향후 개선될 예정입니다. 인터넷에서 찾을 수 있는 사격 플레이어의 소스 코드는 일반적으로 정적 사격이 아닌 롤링 사격만 만듭니다. 여기에는 특별히 정적 사격의 구현을 추가했습니다.

캔버스는 텍스트를 그리고 텍스트 스크롤 효과를 냅니다

전체 플레이어의 핵심은 텍스트를 그리고 텍스트 스크롤에 애니메이션을 적용하는 것입니다. 캔버스에는 텍스트에 대한 좋은 애니메이션 지원이 없으며, 이는 스스로 실현할 수 있는 것입니다. ​​구현은 계속됩니다. 화면을 지운 다음 텍스트를 다시 작성합니다. 화면 지우기 및 다시 쓰기 빈도가 24fps에 도달하면 애니메이션이 원활해집니다.

먼저 HTML 파일에 videovideo 태그와 캔버스 태그를 추가하세요

<div id="barrageplayer">
    <canvas id="cv_video" width="900px" height="450px"></canvas>
    <video id="v_video" src="test.MP4" controls type="video/mp4"></video>
</div>
로그인 후 복사

캔버스 태그의 위치 스타일을 position:absolute로 설정하면 비디오와 캔버스가 겹쳐서 사격 선수처럼 보입니다. 그런 다음 캔버스에 사격 관련 콘텐츠를 추가합니다. 먼저 캔버스의 관련 정보를 얻고 캔버스의 글꼴 크기와 글꼴 스타일을 설정합니다.

var c=document.getElementById("cv_video");
//获取画布大小
var c_height=c.height;
var c_width=c.width;
//获取画布
ctx=c.getContext("2d");
//设置字体样式
ctx.font="25px DengXian";
画布信息已经获取和设置,巧妇难为无米之炊,接着我们就要构造弹幕对象,使用的构造模式是动态原型模式
//弹幕对象
function Barrage(content,color,type,speed){
    this.content=content;
    this.color=color;
    this.type=type;
    this.speed=speed;
    if(this.type=="default"){
        this.height=parseInt(Math.random()*c_height)+10;
    }else if (this.type=="static top"){
        this.height=parseInt((c_height/2)-Math.random()*c_height/2)+10;
    }else if (this.type=="static bottom"){
        this.height=parseInt((c_height/2)+Math.random()*c_height/2)+10;
    }
    if(typeof this.move!="function"){
        Barrage.prototype.move=function(){
            if(this.type=="default"){
                this.left=this.left-this.speed;
            }
        }
    }
}
로그인 후 복사

구성된 사격 개체는 콘텐츠, 색상, 이동 유형 및 speed, 정의됨 move() 메서드는 사격의 완화를 제어하는 ​​데 사용됩니다. move() 메서드가 실행될 때마다 단위 속도의 1픽셀씩 왼쪽으로 스크롤됩니다.

탄막 개체 구성이 완료된 후 테마 및 애니메이션 제작을 입력하고 코드를 직접 입력하십시오.

//循环擦写画布实现动画效果
setInterval(function(){
    ctx.clearRect(0,0,c_width,c_height);
    ctx.save();
    for(var i=0;i<msgs.length;i++){
        if(msgs[i]!=null){
            if(msgs[i].type=="default"){
                handleDefault(msgs[i]);
            }else{
                handleStatic(msgs[i]);
           }
        }
    }
},20)
로그인 후 복사

20ms마다 삭제를 수행하면 ctx.clearRect(0,0,c_width,c_height)는 현재 캔버스 전체를 지우는 것입니다. , 그런 다음 ctx.save()를 사용하여 현재 캔버스를 저장하고 사격 목록을 순회한 다음(msgs는 사격 목록이며 사격이 전송될 때마다 사격 인스턴스가 목록에 추가됨) 기본 스타일을 따릅니다. 사격 사격 또는 스틸 스타일 사격은 별도로 처리됩니다. 기본 스타일의 사격이라면 다음과 같은 방법으로 처리됩니다.

//处理默认弹幕样式
function handleDefault(barrage){
    if(barrage.left==undefined||barrage.left==null){
        barrage.left=c.width;
    }else{
         if(barrage.left<-200){
            barrage=null;
        }else{
            barrage.move()
            ctx.fillStyle=barrage.color;
            ctx.fillText(barrage.content,barrage.left,barrage.height)
            ctx.restore();
        }
    } 
}
로그인 후 복사

먼저 사격 인스턴스에 왼쪽 속성이 설정되지 않은 경우 사격 인스턴스의 경우 캔버스 너비가 할당됩니다. 캔버스를 종료하면 메모리를 절약하기 위해 null로 설정됩니다. 그렇지 않으면 사격 인스턴스의 move() 메서드를 호출하여 왼쪽 속성의 값을 변경한 다음 텍스트 색상을 설정하고 처음에 새 텍스트를 씁니다. 수평을 맞추고 캔버스를 복원합니다. 이로써 애니메이션의 한 프레임이 완성됩니다.

Static Barrage 구현 방법은 다음과 같습니다

//处理静止弹幕样式
function handleStatic(barrage){
    ctx.moveTo(c_width/2,barrage.height);
    ctx.textAlign="center";
    ctx.fillStyle=barrage.color;
    ctx.fillText(barrage.content,c_width/2,barrage.height);
    if(barrage.left==undefined||barrage.left==null){
        barrage.left=c.width;
    }else{
        if(barrage.left<-200){
            ctx.fillText("",c_width/2,barrage.height);               
            barrage=null;
            //ctx.restore();
            ctx.clearRect(0,0,c_width,c_height);       
        }else{
            barrage.left=barrage.left-6;
        }
    }
}
로그인 후 복사

먼저 캔버스의 기준점을 캔버스 중앙으로 이동합니다. 이때 새로운 캔버스가 생성되며, 원래 캔버스는 더 이상 이 캔버스에 적용할 수 없습니다. 그런 다음 텍스트 정렬을 가운데 정렬로 설정하고

텍스트 스타일을 설정한 다음 텍스트를 채웁니다. 탄막은 정적이므로 완화할 필요는 없지만, 정적 탄막도 정기적으로 사라지도록 플래그를 설정해야 합니다. 여기서 추가 속성을 차지하지 않기 위해 left 속성을 플래그로 직접 사용합니다. 또한 left 속성을 감소시키지만 left가 임계값에 도달하면 ctx.clearRect() 메서드를 사용합니다. 사격을 취소합니다. 이러한 방식으로 정적 사격 처리가 실현됩니다.

색이나 스타일 설정에 있어 어느 정도 기초가 있으신 분들은 쉽게 익힐 수 있을 텐데요. 여기서는 자세히 소개하지 않겠습니다. 그냥 실행 가능한 코드 부분만 보고 이해하시면 됩니다.

요약

이 프로젝트에서는 주로 텍스트 그리기 및 텍스트 완화 애니메이션에 캔버스를 사용합니다. 사용된 주요 방법은

canvasDom.getContext()
canvas.save()/canvas.restore()
canvas.clearRect()
canvas.moveTo()
로그인 후 복사


save() 및 Restore() 를 이해할 수 없다는 것이 밝혀졌습니다. 이해가 부족합니다. 캔버스 상태를 변경하면 현재 캔버스는 더 이상 원래 캔버스가 아니므로 캔버스 상태를 수정하기 전에 캔버스 상태를 저장하고 캔버스 상태를 전환하고 작업 완료 후 원래 캔버스로 복원하십시오. 캔버스 상태는 계속 작동합니다. 예를 들어 정적 포격을 처리하고 캔버스의 기준점을 변경하면 원래 캔버스 지우기 방법은 더 이상 현재 캔버스에 적용되지 않으며 현재 캔버스에서는 다른 지우기 방법만 사용할 수 있습니다. 그런 다음 원래 캔버스로 돌아갑니다.

실행 가능한 코드

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<style type="text/css">
    .pickdiv{
        width: 30px;
        height: 30px;
        cursor: pointer;
        border: 2px solid gray;
        display: inline-block;
    }
    #white{
        background: white;
    }
    #red{
        background:#ff6666;
    }
    #yellow{
        background:#ffff00;
    }
    #blue{
        background:#333399;
    }
    #green{
        background:#339933;
    }
    #cv_video{
        position: absolute;
        z-index: 1;
    }
    #barrageplayer{
        position: relative;
        display: block;
        width: 900px;
        height: 500px;
    }
    #v_video{
        position: absolute;
        width: 100%;
        height: 100%;
        z-index: 0;
    }
</style>
<body>
    <div id="barrageplayer">
        <canvas id="cv_video" width="900px" height="450px"></canvas>
        <video id="v_video" src="test.MP4" controls type="video/mp4"></video>
    </div>
    <div id="barrageinput">
        <div>
            <input type="text" id="smsg" placeholder="请输入弹幕内容"/>
            <button id="send"> 发送</button>
        </div>
        <div id="colorpick">
            <div class="pickdiv" id="white"></div>
            <div class="pickdiv" id="red"></div>
            <div class="pickdiv" id="yellow"></div>
            <div class="pickdiv" id="blue"></div>
            <div class="pickdiv" id="green"></div>
        </div>
        <div id="typepick">
            <input type="radio" name="type" value="default">默认
            <input type="radio" name="type" value="static top">静止顶部
            <input type="radio" name="type" value="static bottom">静止底部
        </div>
        <div id="speedpick">
            <input type="radio" name="speed" value="1">1X
            <input type="radio" name="speed" value="2">2X
            <input type="radio" name="speed" value="3">3X
        </div>
        <div id="stylepick"></div>
    </div>
    <script>
        var c=document.getElementById("cv_video");
        var typeDom=document.getElementsByName("type");
        var speedDom=document.getElementsByName("speed");
        var colorpick=document.getElementById("colorpick");
        var smsg=document.getElementById("smsg");
        var color="#white";
        var speed=1;
        var type="default";
        var msgs=[];
        //获取画布大小
        var c_height=c.height;
        var c_width=c.width;
        //获取画布
        ctx=c.getContext("2d");
        ctx.font="25px DengXian";
        //处理颜色选择
        colorpick.addEventListener(&#39;click&#39;,function(event){
            switch(event.target.id){
                case "white":
                    color="white";
                    break;
                case "red":
                    color="#ff6666";
                    break;
                case "yellow":
                    color="#ffff00";
                    break;
                case "green":
                    color="#339933";
                    break;
                case "blue":
                    color="#333399";
                    break;
            }
        })
        //处理发送弹幕
        document.getElementById("send").onclick=function(){
            var text=smsg.value;
            for(var i=0;i<typeDom.length;i++){
                if(typeDom[i].checked){
                    type=typeDom[i].value;
                    break;
                }
            }
            for(var i=0;i<speedDom.length;i++){
                if(speedDom[i].checked){
                    speed=2*parseInt(speedDom[i].value);
                    break;
                }
            }
            var tempBarrage=new Barrage(text,color,type,speed);
            msgs.push(tempBarrage);
        }
        //
        //弹幕功能部分代码
        //
        //弹幕对象
        function Barrage(content,color,type,speed){
            this.content=content;
            this.color=color;
            this.type=type;
            this.speed=speed;
            if(this.type=="default"){
                this.height=parseInt(Math.random()*c_height)+10;
            }else if (this.type=="static top"){
                this.height=parseInt((c_height/2)-Math.random()*c_height/2)+10;
            }else if (this.type=="static bottom"){
                this.height=parseInt((c_height/2)+Math.random()*c_height/2)+10;
            }
            if(typeof this.move!="function"){
                Barrage.prototype.move=function(){
                    if(this.type=="default"){
                        this.left=this.left-this.speed;
                    }
                }
            }
        }
        //循环擦写画布实现动画效果
        setInterval(function(){
            ctx.clearRect(0,0,c_width,c_height);
            ctx.save();
            for(var i=0;i<msgs.length;i++){
                if(msgs[i]!=null){
                    if(msgs[i].type=="default"){
                        handleDefault(msgs[i]);
                    }else{
                        handleStatic(msgs[i]);
                    }
                }
            }
        },20)
    //处理默认弹幕样式
    function handleDefault(barrage){
        if(barrage.left==undefined||barrage.left==null){
            barrage.left=c.width;
        }else{
            if(barrage.left<-200){
                barrage=null;
            }else{
                barrage.move()
                ctx.fillStyle=barrage.color;
                ctx.fillText(barrage.content,barrage.left,barrage.height)
                ctx.restore();
            }
        } 
    }
    //处理静止弹幕样式
    function handleStatic(barrage){
        ctx.moveTo(c_width/2,barrage.height);
        ctx.textAlign="center";
        ctx.fillStyle=barrage.color;
        ctx.fillText(barrage.content,c_width/2,barrage.height);
        if(barrage.left==undefined||barrage.left==null){
            barrage.left=c.width;
        }else{
            if(barrage.left<-200){
                ctx.fillText("",c_width/2,barrage.height);               
                barrage=null;
                //ctx.restore();
                ctx.clearRect(0,0,c_width,c_height);       
            }else{
                barrage.left=barrage.left-6;
            }
        }
    }
    </script>
</body>
</html>
로그인 후 복사

이 사례를 읽으신 후 방법을 마스터하셨다고 생각합니다. 더 흥미로운 정보를 보려면 PHP 중국어 웹사이트의 다른 관련 기사를 주목하세요!

관련 읽기:

HTML 웹 페이지에 비디오를 삽입하는 방법

HTML 텍스트 상자를 읽기 전용 효과로 만드는 방법

HTML+CSS를 사용하여 보조 메뉴를 표시하는 방법 바 위로 마우스를 스와이프하세요

위 내용은 HTML을 사용하여 스크롤링 사격 기능을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

HTML의 테이블 테두리 HTML의 테이블 테두리 Sep 04, 2024 pm 04:49 PM

HTML의 테이블 테두리 안내. 여기에서는 HTML의 테이블 테두리 예제를 사용하여 테이블 테두리를 정의하는 여러 가지 방법을 논의합니다.

HTML의 중첩 테이블 HTML의 중첩 테이블 Sep 04, 2024 pm 04:49 PM

HTML의 Nested Table에 대한 안내입니다. 여기에서는 각 예와 함께 테이블 내에 테이블을 만드는 방법을 설명합니다.

HTML 여백-왼쪽 HTML 여백-왼쪽 Sep 04, 2024 pm 04:48 PM

HTML 여백-왼쪽 안내. 여기에서는 HTML margin-left에 대한 간략한 개요와 코드 구현과 함께 예제를 논의합니다.

HTML 테이블 레이아웃 HTML 테이블 레이아웃 Sep 04, 2024 pm 04:54 PM

HTML 테이블 레이아웃 안내. 여기에서는 HTML 테이블 레이아웃의 값에 대해 예제 및 출력 n 세부 사항과 함께 논의합니다.

HTML 입력 자리 표시자 HTML 입력 자리 표시자 Sep 04, 2024 pm 04:54 PM

HTML 입력 자리 표시자 안내. 여기서는 코드 및 출력과 함께 HTML 입력 자리 표시자의 예를 논의합니다.

HTML에서 텍스트 이동 HTML에서 텍스트 이동 Sep 04, 2024 pm 04:45 PM

HTML에서 텍스트 이동 안내. 여기서는 Marquee 태그가 구문과 함께 작동하는 방식과 구현할 예제에 대해 소개합니다.

HTML 정렬 목록 HTML 정렬 목록 Sep 04, 2024 pm 04:43 PM

HTML 순서 목록에 대한 안내입니다. 여기서는 HTML Ordered 목록 및 유형에 대한 소개와 각각의 예에 대해서도 설명합니다.

HTML 온클릭 버튼 HTML 온클릭 버튼 Sep 04, 2024 pm 04:49 PM

HTML onclick 버튼에 대한 안내입니다. 여기에서는 각각의 소개, 작업, 예제 및 다양한 이벤트의 onclick 이벤트에 대해 설명합니다.

See all articles