成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

使用Canvas怎么實(shí)現(xiàn)一個(gè)炫麗的粒子運(yùn)動(dòng)效果

使用Canvas怎么實(shí)現(xiàn)一個(gè)炫麗的粒子運(yùn)動(dòng)效果?很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。

成都創(chuàng)新互聯(lián)堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站建設(shè)、成都網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的高陽(yáng)網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

html 代碼

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Canvas 實(shí)現(xiàn)炫麗的粒子運(yùn)動(dòng)效果-云庫(kù)前端</title>
<style>
* {
    margin: 0;
    padding: 0;
}
html,
body {
    width: 100%;
    height: 100%;
}
canvas {
    display: block;
    background: #000;
}
body::-webkit-scrollbar{
    display: none;
}
.operator-box{
    position: fixed;
    top: 0;
    left: 50%;
    border: 1px solid #fff;
    background: rgba(255,255,255,0.5);
    padding: 20px 10px;
    -webkit-transform: translateX(-50%);
    transform: translateX(-50%);
}
.back-type,.back-animate{
    margin-right: 20px;
}
.flex-box{
    display: flex;
    justify-content: center;
    align-items: center;
}
#input-text{
    line-height: 35px;
    width: 260px;
    height: 35px;
    background: rgba(0, 0, 0,0.7);
    color: #fff;
    font-size: 16px;
    border: none;
    outline: none;
    text-indent: 12px;
    box-shadow: inset 0 0 12px 1px rgba(0,0,0,0.7);
}
#input-text::placeholder{
    color: #ccc;
    line-height: 55px;
    height: 55px;
}
select{
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    border: none;
    padding: 0px 20px 0px 6px;
    height: 35px;
    color: #fff;
    text-align: left;
    background: rgba(0, 0, 0,0.7) url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAICAYAAAAx8TU7AAAAOUlEQ&hellip;R4gPgWEIMAiOYBCS4C8ZDAIrBq4gigNkztQEFMi6AuQHESAPMeXiEMiWfpAAAAAElFTkSuQmCC) no-repeat 190px 12px;
    background-size: 5px 8px;
    box-shadow: inset 0 0 12px 1px rgba(0,0,0,0.7);
}
</style>
</head>
<body>
<div class="operator-box">
<div class="flex-box">
    <div class="back-type">散開(kāi)類(lèi)型:
        <select name="" id="selectType">
            <option value="back">歸位</option>
            <option value="auto">隨機(jī)</option>
        </select>
    </div>
    <div class="back-animate">散開(kāi)效果(對(duì)歸位有效):
       <select class="back-dynamics" id="selectDynamics">
           <option value="spring">dynamics.spring</option>
           <option value="bounce">dynamics.bounce</option>
           <option value="forceWithGravity">dynamics.forceWithGravity</option>
           <option value="gravity">dynamics.gravity</option>
           <option value="easeInOut">dynamics.easeInOut</option>
           <option value="easeIn">dynamics.easeIn</option>
           <option value="easeOut">dynamics.easeOut</option>
           <option value="linear">dynamics.linear</option>
       </select>
    </div>
    <div class="input-box"><input type="text" placeholder="輸入漢字后回車(chē)" id="input-text"></div>
</div>
</div>
<script src="dynamics.min.js"></script>
<script src="index.js"></script>
<script>
var iCircle = new Circle();
</script>
</body>
</html>

HTML 代碼不多,只要是幾個(gè)操作元素。這里一看就明白。不費(fèi)過(guò)多口舌。我們來(lái)看看本文的主角 JavaScript 代碼,不過(guò),在看代碼前,我們不妨先聽(tīng)聽(tīng)實(shí)現(xiàn)這個(gè)效果的思路:

  1. 首先,我們得先生成一堆群眾演員(粒子);

  2. 把每個(gè)粒子的相關(guān)參數(shù)掛到自身的一些屬性上,因?yàn)榈趥€(gè)粒子都會(huì)有自己的運(yùn)動(dòng)軌跡;

  3. 接著得讓它們各自運(yùn)動(dòng)起來(lái)。運(yùn)動(dòng)有兩種(自由運(yùn)動(dòng)和生成文字的運(yùn)動(dòng));

JavaScript 代碼中使用了三個(gè) Canvas 畫(huà)布,this.iCanvas(主場(chǎng))、this.iCanvasCalculate(用來(lái)計(jì)算文字寬度)、this.iCanvasPixel(用于畫(huà)出文字,并從中得到文字對(duì)應(yīng)的像素點(diǎn)的位置坐標(biāo))。

this.iCanvasCalculate 和 this.iCanvasPixel 這兩個(gè)無(wú)需在頁(yè)面中顯示出來(lái),只是輔助作用。

下面就獻(xiàn)上棒棒的 JS 實(shí)現(xiàn)代碼

function Circle() {
    var This = this;
    this.init();
    this.generalRandomParam();
    this.drawCircles();
    this.ballAnimate();
    this.getUserText();
    // 窗口改變大小后,生計(jì)算并獲取畫(huà)面
    window.onresize = function(){
        This.stateW = document.body.offsetWidth;
        This.stateH = document.body.offsetHeight;
        This.iCanvasW = This.iCanvas.width = This.stateW;
        This.iCanvasH = This.iCanvas.height = This.stateH;
        This.ctx = This.iCanvas.getContext("2d");
    }
}
// 初始化
Circle.prototype.init = function(){
    //父元素寬高
    this.stateW = document.body.offsetWidth;
    this.stateH = document.body.offsetHeight;
    this.iCanvas = document.createElement("canvas");
    // 設(shè)置Canvas 與父元素同寬高
    this.iCanvasW = this.iCanvas.width = this.stateW;
    this.iCanvasH = this.iCanvas.height = this.stateH;
    // 獲取 2d 繪畫(huà)環(huán)境
    this.ctx = this.iCanvas.getContext("2d");
    // 插入到 body 元素中
    document.body.appendChild(this.iCanvas);
    this.iCanvasCalculate = document.createElement("canvas");
    // 用于保存計(jì)算文字寬度的畫(huà)布
    this.mCtx =  this.iCanvasCalculate.getContext("2d");
    this.mCtx.font = "128px 微軟雅黑";
    this.iCanvasPixel = document.createElement("canvas");
    this.iCanvasPixel.setAttribute("style","position:absolute;top:0;left:0;");
    this.pCtx = null; // 用于繪畫(huà)文字的畫(huà)布
    // 隨機(jī)生成圓的數(shù)量
    this.ballNumber = ramdomNumber(1000, 2000);
    // 保存所有小球的數(shù)組
    this.balls = [];
    // 保存動(dòng)畫(huà)中最后一個(gè)停止運(yùn)動(dòng)的小球
    this.animte = null;
    this.imageData = null;
    this.textWidth = 0; // 保存生成文字的寬度
    this.textHeight = 150; // 保存生成文字的高度
    this.inputText = ""; // 保存用戶輸入的內(nèi)容
    this.actionCount = 0;
    this.ballActor = []; // 保存生成文字的粒子
    this.actorNumber = 0; // 保存生成文字的粒子數(shù)量
    this.backType = "back"; // 歸位
    this.backDynamics = ""; // 動(dòng)畫(huà)效果
    this.isPlay = false; // 標(biāo)識(shí)(在生成文字過(guò)程中,不能再生成)
}
// 渲染出所有圓
Circle.prototype.drawCircles = function () {
    for(var i=0;i<this.ballNumber;i++){
        this.renderBall(this.balls[0]);
    }
}
// 獲取用戶輸入文字
Circle.prototype.getUserText = function(){
    This = this; // 保存 this 指向
    ipu = document.getElementById("input-text");
    ipu.addEventListener("keydown",function(event){
        if(event.which === 13){ // 如果是回車(chē)鍵
            ipu.value = ipu.value.trim(); // 去頭尾空格
            var pat = /[\u4e00-\u9fa5]/; // 中文判斷
            var isChinese = pat.test(ipu.value);
            if(ipu.value.length !=0 && isChinese){
                This.inputText = ipu.value;
            }else{
                alert("請(qǐng)輸入漢字");
                return;
            }
            if(This.isPlay){
                return
            }
            This.getAnimateType();
            This.getTextPixel();
            This.isPlay = true;
        }
    });
}
// 計(jì)算文字的寬
Circle.prototype.calculateTextWidth = function () {
    this.textWidth = this.mCtx.measureText(this.inputText).width;
}
// 獲取文字像素點(diǎn)
Circle.prototype.getTextPixel = function () {
    if(this.pCtx){
        this.pCtx.clearRect(0,0,this.textWidth,this.textHeight);
    }
    this.calculateTextWidth(this.inputText);
    this.iCanvasPixel.width = this.textWidth;
    this.iCanvasPixel.height = this.textHeight;
    this.pCtx =  this.iCanvasPixel.getContext("2d");
    this.pCtx.font = "128px 微軟雅黑";
    this.pCtx.fillStyle = "#FF0000";
    this.pCtx.textBaseline = "botom";
    this.pCtx.fillText(this.inputText,0,110);
    this.imageData = this.pCtx.getImageData(0,0,this.textWidth,this.textHeight).data;
    this.getTextPixelPosition(this.textWidth,this.textHeight);
}
// 獲取文字粒子像素點(diǎn)位置
Circle.prototype.getTextPixelPosition = function (width,height) {
    var left = (this.iCanvasW - width)/2;
    var top = (this.iCanvasH - height)/2;
    var space = 4;
    this.actionCount = 0;
    for(var i=0;i<this.textHeight;i+=space){
        for(var j=0;j<this.textWidth;j+=space){
            var index = j*space+i*this.textWidth*4;
            if(this.imageData[index] == 255){
                if(this.actionCount<this.ballNumber){
                    this.balls[this.actionCount].status = 1;
                    this.balls[this.actionCount].targetX = left+j;
                    this.balls[this.actionCount].targetY = top+i;
                    this.balls[this.actionCount].backX = this.balls[this.actionCount].x;
                    this.balls[this.actionCount].backY = this.balls[this.actionCount].y;
                    this.ballActor.push(this.balls[this.actionCount]);
                    this.actionCount++;
                }
            }
        }
        this.actorNumber = this.ballActor.length;
    }
    this.animateToText();
}
// 粒子運(yùn)動(dòng)到指定位置
Circle.prototype.animateToText = function(){
    for(var i=0;i<This.actorNumber;i++){
        dynamics.animate(This.ballActor[i], {
          x: this.ballActor[i].targetX,
          y: this.ballActor[i].targetY
        },{
            type: dynamics.easeIn,
            duration: 1024,
        });
    }
    setTimeout(function(){
        This.ballbackType();
    },3000);
}
// 粒子原路返回
Circle.prototype.ballBackPosition = function(){
    for(var i=0;i<This.actorNumber;i++){
        var ball = This.ballActor[i];
        dynamics.animate(ball, {
          x: ball.backX,
          y: ball.backY
        },{
            type: dynamics[this.backDynamics],
            duration: 991,
            complete:this.changeStatus(ball)
        });
    }
}
// 獲取類(lèi)型|動(dòng)畫(huà)效果
Circle.prototype.getAnimateType = function() {
    var selectType = document.getElementById("selectType");
    var selectDynamics = document.getElementById("selectDynamics");
    this.backType = selectType.options[selectType.options.selectedIndex].value;
    this.backDynamics = selectDynamics.options[selectDynamics.options.selectedIndex].value;
}
// 復(fù)位散開(kāi)
Circle.prototype.ballbackType = function(){
    if(this.backType == "back"){
        this.ballBackPosition();
    }else{
        this.ballAutoPosition();
    }
    this.ballActor = [];
}
// 隨機(jī)散開(kāi)
Circle.prototype.ballAutoPosition = function(ball){
    for(var i=0;i<this.actorNumber;i++){
        this.changeStatus(this.ballActor[i])
    }
}
// 更改小球狀態(tài)
Circle.prototype.changeStatus = function(ball){
    ball.status = 0;
    if(this.isPlay == true){
        this.isPlay = false;
    }
}
// 隨機(jī)生成每個(gè)圓的相關(guān)參數(shù)
Circle.prototype.generalRandomParam = function(){
    for(var i=0;i<this.ballNumber;i++){
        var ball = {};
        ball.size = 1; // 隨機(jī)生成圓半徑
        // 隨機(jī)生成圓心 x 坐標(biāo)
        ball.x = ramdomNumber(0+ball.size, this.iCanvasW-ball.size);
        ball.y = ramdomNumber(0+ball.size, this.iCanvasH-ball.size);
        ball.speedX = ramdomNumber(-1, 1);
        ball.speedY = ramdomNumber(-1, 1);
        this.balls.push(ball);
        ball.status = 0;
        ball.targetX = 0;
        ball.targetY = 0;
        ball.backX = 0;
        ball.backY = 0;
    }
}
// 改變圓的位置
Circle.prototype.changeposition = function(){
    for(var i=0;i<this.ballNumber;i++){
        if( this.balls[i].status == 0){
            this.balls[i].x += this.balls[i].speedX;
            this.balls[i].y += this.balls[i].speedY;
        }
    }
}
// 畫(huà)圓
Circle.prototype.renderBall = function(ball){
    this.ctx.fillStyle = "#fff";
    this.ctx.beginPath(); // 這個(gè)一定要加
    this.ctx.arc(ball.x, ball.y, ball.size, 0, 2 * Math.PI);
    this.ctx.closePath(); // 這個(gè)一定要加
    this.ctx.fill();
}
// 小球碰撞判斷
Circle.prototype.collision = function(ball){
    for(var i=0;i<this.ballNumber;i++){
       if(ball.x>this.iCanvasW-ball.size || ball.x<ball.size){
            if(ball.x>this.iCanvasW-ball.size){
                ball.x = this.iCanvasW-ball.size;
            }else{
                ball.x = ball.size;
            }
            ball.speedX = - ball.speedX;
       }
       if(ball.y>this.iCanvasH-ball.size || ball.y<ball.size){
            if(ball.y>this.iCanvasH-ball.size){
                ball.y = this.iCanvasH-ball.size;
            }else{
                ball.y = ball.size;
            }
            ball.speedY = - ball.speedY;
       }
    }
}
// 開(kāi)始動(dòng)畫(huà)
Circle.prototype.ballAnimate = function(){
    var This = this;
    var animateFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
    (function move(){
        animte = animateFrame(move);
        This.ctx.clearRect(0, 0, This.iCanvasW, This.iCanvasH);
        This.changeposition();
        for(var i=0;i<This.ballNumber;i++){
           This.collision(This.balls[i]);
           This.renderBall(This.balls[i]);
        }
    })();
}
// 生成一個(gè)隨機(jī)數(shù)
function ramdomNumber(min, max) {
    return Math.random() * (max - min) + min;
}

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對(duì)創(chuàng)新互聯(lián)的支持。

文章名稱(chēng):使用Canvas怎么實(shí)現(xiàn)一個(gè)炫麗的粒子運(yùn)動(dòng)效果
文章路徑:http://jinyejixie.com/article32/jjigpc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供靜態(tài)網(wǎng)站、企業(yè)建站、網(wǎng)站收錄、網(wǎng)站導(dǎo)航做網(wǎng)站、動(dòng)態(tài)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運(yùn)營(yíng)
丹寨县| 武宁县| 昆明市| 龙里县| 抚顺市| 绍兴市| 海南省| 独山县| 海南省| 阿瓦提县| 新沂市| 南澳县| 文山县| 南澳县| 余庆县| 汶上县| 突泉县| 独山县| 吉安县| 陵川县| 兴仁县| 舒城县| 麻栗坡县| 天等县| 通州区| 蕲春县| 米脂县| 安溪县| 澄江县| 卓资县| 磐安县| 西峡县| 临高县| 贵港市| 措美县| 泽普县| 繁峙县| 土默特右旗| 奇台县| 金平| 玛纳斯县|