成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

炫酷粒子表白 | 聽說女神都想談戀愛了!

venmos / 2616人閱讀

摘要:最近聽女神說想談戀愛了,嘿嘿,一定不能放過這個(gè)機(jī)會(huì),給她來個(gè)不一樣的表白。我們只需要判斷不為就可以得到需要的字體形狀數(shù)據(jù)了。能不能再給力一點(diǎn)說好的粒子系統(tǒng),現(xiàn)在只是簡(jiǎn)單的畫了一點(diǎn)。還有什么好玩的上面是將粒子擺成文字。

最近聽女神說想談戀愛了,?(? ? ?) 嘿嘿,一定不能放過這個(gè)機(jī)會(huì),給她來個(gè)不一樣的表白。

那么咱們就一起來把這個(gè)粒子系統(tǒng)玩出花來吧

演示地址:
https://es2049.studio/work-sh...

如何將一系列的粒子組成一句表白呢?

實(shí)現(xiàn)原理其實(shí)很簡(jiǎn)單,Canvas 中有個(gè) getImageData 的方法,可以得到一個(gè)矩形范圍所有像素點(diǎn)數(shù)據(jù)。那么我們就試試來獲取一個(gè)文字的形狀吧。

第一步,用 measureText 的方法來計(jì)算出文字適當(dāng)?shù)某叽绾臀恢谩?/p>

// 創(chuàng)建一個(gè)跟畫布等比例的 canvas
const width = 100;
const height = ~~(width * this.height / this.width); // this.width , this.height 說整個(gè)畫布的尺寸
const offscreenCanvas    =document.createElement("canvas");
const offscreenCanvasCtx    =offscreenCanvas.getContext("2d");
offscreenCanvas.setAttribute("width", width);
offscreenCanvas.setAttribute("height", height);

// 在這離屏 canvas 中將我們想要的文字 textAll 繪制出來后,再計(jì)算它合適的尺寸
offscreenCanvasCtx.fillStyle = "#000";
offscreenCanvasCtx.font = "bold 10px Arial";
constmeasure=offscreenCanvasCtx.measureText(textAll); // 測(cè)量文字,用來獲取寬度
const size = 0.8;
// 寬高分別達(dá)到屏幕0.8時(shí)的size

const fSize=Math.min(height * size * 10 / lineHeight, width * size * 10 / measure.width);  // 10像素字體行高 lineHeight=7 magic
offscreenCanvasCtx.font = `bold ${fSize}px Arial`;

// 根據(jù)計(jì)算后的字體大小,在將文字?jǐn)[放到適合的位置,文字的坐標(biāo)起始位置在左下方
const measureResize    =offscreenCanvasCtx.measureText(textAll);
// 文字起始位置在左下方
let left = (width - measureResize.width) / 2;
const bottom=(height + fSize / 10 * lineHeight) / 2;
offscreenCanvasCtx.fillText(textAll, left, bottom);

咱們可以 appendChild 到 body 里看眼

同學(xué)們注意,我要開始變形了 [推眼鏡] 。
getImageData 獲取的像素?cái)?shù)據(jù)是一個(gè) Uint8ClampedArray (值是 0 - 255 的數(shù)組),4 個(gè)數(shù)一組分別對(duì)應(yīng)一個(gè)像素點(diǎn)的 R G B A 值。我們只需要判斷 i * 4 + 3 不為 0 就可以得到需要的字體形狀數(shù)據(jù)了。

// texts 所有的單詞分別獲取 data ,上文的 textAll 是 texts 加一起
Object.values(texts).forEach(item => {
    offscreenCanvasCtx.clearRect(0, 0, width, height);
    offscreenCanvasCtx.fillText(item.text, left, bottom);
    left += offscreenCanvasCtx.measureText(item.text).width;
    const data = offscreenCanvasCtx.getImageData(0, 0, width, height);
    const points = [];
        // 判斷第 i * 4 + 3 位是否為0,獲得相對(duì)的 x,y 坐標(biāo)(使用時(shí)需乘畫布的實(shí)際長(zhǎng)寬, y 坐標(biāo)也需要取反向)
    for (let i = 0, max = data.width * data.height; i < max; i++) {
        if (data.data[i * 4 + 3]) {
            points.push({
                x: (i % data.width) / data.width,                
                y: (i / data.width) / data.height
           });
       }
   }
        // 保存到一個(gè)對(duì)象,用于后面的繪制
    geometry.push({
        color: item.hsla,        
        points
    });
})

制定場(chǎng)景,繪制圖形

文字圖形的獲取方式以及搞定了,那么咱們就可以把內(nèi)容整體輸出了。咱們定義一個(gè)簡(jiǎn)單的腳本格式。

// hsla 格式方便以后做色彩變化的擴(kuò)展
const color1 = {h:197,s:"100%",l:"50%",a:"80%"};
const color2 = {h:197,s:"100%",l:"50%",a:"80%"};
// lifeTime 禎數(shù)
const Actions = [
    {lifeTime:60,text:[{text:3,hsla:color1}]},   
    {lifeTime:60,text:[{text:2,hsla:color1}]},  
    {lifeTime:60,text:[{text:1,hsla:color1}], 
    {lifeTime:120,text:[     
        {text:"I",hsla:color1},
        {text:"??",hsla:color2},
        {text:"Y",hsla:color1},
        {text:"O",hsla:color1},  
        {text:"U",hsla:color1}
   ]},
];

根據(jù)預(yù)設(shè)的腳本解析出每個(gè)場(chǎng)景的圖形,加一個(gè) tick 判斷是否到了 lifeTime 切換到下一個(gè)圖形重新繪制圖形。

function draw() {
    this.tick++;
    if (this.tick >= this.actions[this.actionIndex].lifeTime) {
        this.nextAction();
   }
    this.clear();    
    this.renderParticles(); // 繪制點(diǎn)    
    this.raf = requestAnimationFrame(this.draw);
}

    function nextAction() {
        ....//切換場(chǎng)景 balabala..
        this.setParticle(); // 隨機(jī)將點(diǎn)設(shè)置到之前得到的 action.geometry.points 上
    }

這樣咱們基本的功能已經(jīng)完成了。

能不能再給力一點(diǎn)

說好的粒子系統(tǒng),現(xiàn)在只是 context.arc 簡(jiǎn)單的畫了一點(diǎn)。那咱們就來加個(gè)粒子系統(tǒng)吧。

class PARTICLE {
    // x,y,z 為當(dāng)前的坐標(biāo),vx,vy,vz 則是3個(gè)方向的速度
    constructor(center) {
        this.center = center; 
        this.x = 0;
        this.y = 0;        
        this.z = 0;        
        this.vx = 0;        
        this.vy = 0;        
        this.vz = 0;
   }
    // 設(shè)置這些粒子需要運(yùn)動(dòng)到的終點(diǎn)(下一個(gè)位置)
    setAxis(axis) {
        this.nextX = axis.x;        
        this.nextY = axis.y;        
        this.nextZ = axis.z;        
        this.color = axis.color;
   }
    step() {
        // 彈力模型 距離目標(biāo)越遠(yuǎn)速度越快
        this.vx += (this.nextX - this.x) * SPRING;
        this.vy += (this.nextY - this.y) * SPRING;
        this.vz += (this.nextZ - this.z) * SPRING;
            // 摩擦系數(shù) 讓粒子可以趨向穩(wěn)定
       this.vx *= FRICTION;
       this.vy *= FRICTION;
       this.vz *= FRICTION;
        
        this.x += this.vx;        
        this.y += this.vy;        
        this.z += this.vz;
   }
    getAxis2D() {
        this.step();
        // 3D 坐標(biāo)下的 2D 偏移,暫且只考慮位置,不考慮大小變化
        const scale = FOCUS_POSITION / (FOCUS_POSITION + this.z);
        return {
            x: this.center.x + (this.x * scale),
            y: this.center.y - (this.y * scale),
       };
   }
}

大功告成!

既然是 3D 的粒子,其實(shí)這上面還有不是文章可做,同學(xué)們可以發(fā)揮想象力來點(diǎn)更酷炫的。

還有什么好玩的

上面是將粒子擺成文字。那咱們當(dāng)然也可以直接寫公式擺出個(gè)造型。

// Actions 中用 func 代替 texts
{
    lifeTime: 100,
    func: (radius) => {
        const i = Math.random() * 1200;
        let x = (i - 1200 / 2) / 300;
        let y = Math.sqrt(Math.abs(x)) - Math.sqrt(Math.cos(x)) * Math.cos(30 * x);
        return {
        x: x * radius / 2,
        y: y * radius / 2,
        z: ~~(Math.random() * 30),
        color: color3
       };
   }
}

再把剛才文字轉(zhuǎn)換形狀的方法用一下

{
    lifeTime: Infinity,
        func: (width, height) => {
            if(!points.length){
                const img = document.getElementById("tulip");
                    constoffscreenCanvas = document.createElement("canvas");
                    constoffscreenCanvasCtx = offscreenCanvas.getContext("2d");

                const imgWidth = 200;
                const imgHeight = 200;
                offscreenCanvas.setAttribute("width", imgWidth);
                offscreenCanvas.setAttribute("height", imgHeight);
                offscreenCanvasCtx.drawImage( img, 0, 0, imgWidth, imgHeight);
                let imgData=offscreenCanvasCtx.getImageData( 0, 0, imgWidth, imgHeight);
                for ( let i = 0, max = imgData.width * imgData.height; i < max; i++) {
                    if (imgData.data[i * 4 + 3]) {
                        points.push({
                            x: (i % imgData.width) / imgData.width,
                            y: (i / imgData.width) / imgData.height
                       });
                   }
               }
           }

            
    const p= points[~~(Math.random() * points.length)]
            const radius = Math.min(width * 0.8, height * 0.8);
            return {
                    x: p.x * radius - radius / 2,
                    y: (1 - p.y) * radius - radius / 2,
                    z: ~~(Math.random() * 30),
                    color: color3
           };
       }
}

完美

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/99899.html

相關(guān)文章

  • 炫酷粒子表白,雙十一脫單靠它!

    摘要:雙十一光棍節(jié)又要來臨了,每年這個(gè)時(shí)候都是本人最苦悶的時(shí)刻。能不能再給力一點(diǎn)說好的粒子系統(tǒng),現(xiàn)在只是簡(jiǎn)單的畫了一點(diǎn)。 showImg(https://segmentfault.com/img/remote/1460000016908379?w=1100&h=564); ? 雙十一光棍節(jié)又要來臨了,每年這個(gè)時(shí)候都是本人最苦悶的時(shí)刻。日漸消瘦的錢包,愈發(fā)干涸的雙手,雖然變強(qiáng)了,頭卻變涼...

    lauren_liuling 評(píng)論0 收藏0
  • 從小數(shù)學(xué)就不及格的我,竟然用極坐標(biāo)系表白我的女神?。ǜ酱a)

    摘要:在兩點(diǎn)間的關(guān)系用夾角和距離很容易表示時(shí),極坐標(biāo)系便顯得尤為有用而在平面直角坐標(biāo)系中,這樣的關(guān)系就只能使用三角函數(shù)來表示。對(duì)于很多類型的曲線,極坐標(biāo)方程是最簡(jiǎn)單的表達(dá)形式,甚至對(duì)于某些曲線來說,只有極坐標(biāo)方程能夠表示。 歡迎大家前往騰訊云+社區(qū),獲取更多騰訊海量技術(shù)實(shí)踐干貨哦~ 本文由郭詩雅發(fā)表于云+社區(qū)專欄 在數(shù)學(xué)中,極坐標(biāo)系(英語:Polar coordinate system)是...

    yagami 評(píng)論0 收藏0
  • 漫畫:程序員的“情人”節(jié)應(yīng)該這樣度過

    摘要:今天是年月號(hào),一年一度的情人節(jié)又來了,今天對(duì)于很多年輕人來說是個(gè)特別的日子。該程序員在聯(lián)誼會(huì)上認(rèn)識(shí)了某藝術(shù)系女生,同鄉(xiāng)的雙方互有好感。 今天是2018年8月17號(hào),一年一度的情人節(jié)又來了,今天對(duì)于很多年輕人來說是個(gè)特別的日子。但是作為屌絲界的一枚程序員,往往給人的印象是宅,不愛說話,智商不好,也不討好哄女孩子歡心。但是,為什么我身邊的程序員各個(gè)都是高智商,高顏值的小碼農(nóng)呢?或許,他們用...

    Shisui 評(píng)論0 收藏0
  • 聽說你想 520 表白

    摘要:源碼很簡(jiǎn)單鍵盤按,然后輸入表白網(wǎng)頁生成器打開網(wǎng)站,填入要表白的內(nèi)容生成好的網(wǎng)頁百度傳情其實(shí)百度很早就有個(gè)傳情功能,直接百度輸入表白即可。 又到520,一個(gè)狂虐單身狗的日子,看看知乎的熱門話題:showImg(https://segmentfault.com/img/remote/1460000019264481); 這里給大家提供幾個(gè)虐狗的新姿勢(shì)。 69 表白從 69 開始,給對(duì)方發(fā)個(gè)...

    Mr_zhang 評(píng)論0 收藏0
  • 【Python紀(jì)念冊(cè)】哪些浪漫至極的表白程序—“你做我的男孩,我做你的宇宙”

    摘要:完整的資料源碼都打包等你來取哈免費(fèi)滴直接視頻效果展示如下紀(jì)念冊(cè)哪些浪漫至極的表白程序截圖展示如下界面漫天花瓣飛舞。 ?導(dǎo)語 大家好,我是木木子!?? 今日的表白案例上線啦~有沒有期待?安排安排!源碼基地見免費(fèi)源碼哈! 貼心的木子君也給你們好多愛心花瓣、以及表白的小程序!在主頁的左側(cè)哦! 這款...

    aisuhua 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<