產品經理:你能不能用div給我畫條龍?

語言: CN / TW / HK

事情是這樣的,前天上午產品經理説想要做一個心願牆,問我能不能行

我心想,這太容易了,但為了多摸一天魚,我説還是有點挑戰

結果下午,產品經理和設計師就給我發來了設計參考

image.png

他們説,心願牆的設計大致是這樣的,每個用户的心願都是一個氣泡,而客户的品牌是”龍“,我們希望在前端頁面裏用氣泡呈現一個龍形的設計,每個氣泡都會浮動,鼠標移上去變大,點擊後展示心願詳情。

當時我的內心是這樣的

image.png

我摸魚的一天要泡湯了嗎?

誰都不能阻止我摸魚

但首先要解決最核心的問題

龍從哪裏來?

設計師説了,他可以給我一條由氣泡組成的龍的設計稿,我説那等你設計稿給我,我再研究把。結果他説,已經有了,你就用這個吧

image.png

我的刀呢?

互動問題

請在評論區留下你遇到過的最奇葩的需求

拆解需求

遇到不靠譜的產品經理和設計師,前端工程師真是慘。我們頂着最後交付成品的巨鍋,所有deadline感覺都只是用來壓榨前端工程師的。

我們只能靠自己,因為

誰都不能阻止我摸魚

  • 需求1:有鼠標交互效果(太簡單)
  • 需求2:氣泡要浮動(css動畫,easy)
  • 需求3:氣泡組成一條龍

此時我腦海裏響起這首爛大街的歌

左邊跟我一起畫個龍,在你右邊畫一道彩虹~

誒,畫個龍

用什麼畫,canvas

canvas能獲得指定區域的像素點陣

卧槽,有招兒了

代碼時間

先用圖片搜索找一張龍的剪影

image.png

image.png

將圖片繪製到canvas中

~~~javascript var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d");

var image = new Image(); image.src = "dragon.jpg"; image.onload = function(){ canvas.width = image.width; canvas.height = image.height;

    ctx.drawImage(image,0,0);

} ~~~

獲取並裁剪畫布的點陣信息

~~~javascript var imageData = ctx.getImageData(0,0,image.width,image.height).data; ctx.fillStyle = "#ffffff"; ctx.fillRect(0,0,image.width,image.height);

var gap = 6;

for (var h = 0; h < image.height; h+=gap) { for(var w = 0; w < image.width; w+=gap){ var position = (image.width * h + w) * 4; var r = imageData[position], g = imageData[position + 1], b = imageData[position + 2];

        if(r+g+b==0){
                ctx.fillStyle = "#000";
                ctx.fillRect(w,h,4,4);
            }
}

} ~~~

現在我們獲得了這樣一條龍的點陣信息

image.png

通過點陣信息生成氣泡dom

~~~javascript var dragonContainer = document.getElementById("container"); var dragonScale = 2;

for (var h = 0; h < image.height; h+=gap) { for(var w = 0; w < image.width; w+=gap){ var position = (image.width * h + w) * 4; var r = imageData[position], g = imageData[position + 1], b = imageData[position + 2];

        if(r+g+b==0){
                var bubble = document.createElement("img");
                bubble.src = "bubble.png";
                bubble.setAttribute("class","bubble");

                var bubbleSize = Math.random()*10+20;
                bubble.style.left = (w*dragonScale-bubbleSize/2) + "px";
                bubble.style.top = (h*dragonScale-bubbleSize/2) + "px";
                bubble.style.width = bubble.style.height = bubbleSize+"px";
                bubble.style.animationDuration = Math.random()*6+4 + "s";

                dragonContainer.appendChild(bubble);
            }
}

} ~~~

image.png

開心摸魚吧

本例裏使用div繪製大量的dom,僅為闡述思路,沒考慮性能。利用一些js遊戲引擎,比如pixi等,可以很方便的全部交由canvas去繪製並添加交互。


本故事純屬虛構,參考案例來自本人2011年底為客户開發的春節活動網站。

如果你喜歡大帥的教程,請收藏,點贊,關注吧

  • 嗶哩嗶哩:大帥老猿
  • 微信公眾號:大帥老猿