为什么要折腾开机动画
我觉得要好好思考这个问题。
前天突发奇想,如果能把watchdog开机动画从手机移植到电脑上去就好了……于是我就去找了一下如何在Ubuntu上面实现开机动画,搜到Plymouth这个模块。
Arch Linux上面有一些对于这个模块的简介;不过没有Ubuntu Wiki上面这篇详细。先前走了不少弯路,没能正确预览动画;后来仔细读了一下教程,发现用plymouth-x11
这个包的话就可以在图形界面下预览开机动画了。
主要的涉及到的步骤有这些:
安装
plymouth-x11
:sudo apt-get install plymouth-x11
预览动画:先开一个终端负责启动
plymouthd
sudo plymouthd --debug --tty=`tty` --no-daemon
然后再开一个终端预览
sudo plymouth show-splash sudo plymouth quit #exit command
把现在可用的文件复制一份出来,并且设置默认项:
mkdir ~/bootanim sudo cp /lib/plymouth/themes/ubuntu-logo ~/bootanim/myanim -R sudo cp /lib/plymouth/themes/default.plymouth ~/bootanim/myanim.plymouth sudo chown yourusername:youusername ~/bootanim -R sudo ln -s ~/bootanim/myanim.plymouth /lib/plymouth/themes/myanim.plymouth sudo ln -s ~/bootanim/myanim /lib/plymouth/themes/myanim sudo update-alternatives --install /lib/plymouth/themes/default.plymouth default.plymouth /lib/plymouth/themes/myanim.plymouth 101 sudo update-alternatives --config default.plymouth #and choose your anim
开始折腾拷贝出来的文件吧!!!期间犯了几次傻……
fun num_to_longnum (int num) {...} //no 'int' parts = 4; num[parts] = [33, 62, 56, 58]; //should write into 'num = [...]' cyc = false; //no 'false'; use 0 instead
语法蛮像js的,可参考:Scripts
顺便附上我在用的脚本:
/*-----functions-----*/ fun num_to_longnum (num) { if (num < 10) longnum = "0000" + num; else longnum = "000" + num; return longnum; } /*-----end of functions-----*/ /*-----init-----*/ time = 0; now_part.left = 3; now_part.main = 0; now_part.right = 5; now_index.left = 0; now_index.main = 0; now_index.right = 0; cyc = 0; end = 0; pro = 0; /*-----end of init-----*/ /*-----consts-----*/ maxopa = 0.5; parts = 7; //num = [1, 62, 56, 58, 62, 95, 53]; num = [1, 1, 1, 58, 62, 95, 53]; winwidth = Window.GetWidth(); winheight = Window.GetHeight(); picwidth = 460; picheight = 768; whiteheight = 50; fps = 50; /*-----end of consts-----*/ /*-----load pics-----*/ fun load_startup () { for (i = 0; i < parts; ++i) { for (j = 0; j < num[i]; ++j) { global.bg[i][j] = Image ("part" + i + "/" + num_to_longnum(j) + ".png"); } } global.on = Image ("on.png"); global.off = Image ("off.png"); global.white = Image ("white.png"); } fun load_shutdown () { for (j = 0; j < num[6]; ++j) { global.bg[6][j] = Image ("part" + i + "/" + num_to_longnum(j) + ".png"); } } fun load () { if (Plymouth.GetMode () == "boot") { load_startup(); } else if (Plymouth.GetMode() == "shutdown") { load_shutdown(); } } /*-----end of load pics-----*/ /*-----init-----*/ fun init_startup () { global.main_sprite = Sprite(); main_sprite.SetPosition (winwidth / 2 - picwidth / 2, winheight/2-picheight/2, -10); global.left_sprite = Sprite(); left_sprite.SetPosition (winwidth / 2 - 3 * picwidth / 2, winheight/2-picheight/2, -15); global.right_sprite = Sprite(); right_sprite.SetPosition (winwidth / 2 + picwidth / 2, winheight/2-picheight/2, -15); global.white_sprite = Sprite(); white_sprite.SetImage (white); white_sprite.SetOpacity (0.5); } fun init_shutdown () { global.main_sprite = Sprite(); main_sprite.SetPosition (winwidth / 2 - picwidth / 2, winheight/2-picheight/2, -10); } fun init () { if (Plymouth.GetMode () == "boot") { init_startup(); } else if (Plymouth.GetMode() == "shutdown") { init_shutdown(); } } /*-----end of init-----*/ /*-----main-----*/ fun refresh_callback_startup () { /*info_text = Image.Text ("Waited " + time / 50 + " seconds"); info_sprite = Sprite (info_text); info_sprite.SetX (Window.GetWidth () / 2 - info_sprite.GetImage().GetWidth() / 2); info_sprite.SetY (Window.GetHeight () / 3); info_sprite.SetZ (-5);*/ if (!cyc) { main_sprite.SetImage (bg[now_part.main][now_index.main]); } else { if (time % 100 < 90) main_sprite.SetImage (off); else main_sprite.SetImage (on); main_sprite.SetOpacity (main_sprite.GetOpacity() * 0.01 + 100 * 0.99); } if (now_part.main > now_part.left) { left_sprite.SetImage(bg[now_part.left][now_index.left]); left_sprite.SetOpacity(maxopa * Math.Abs(Math.Sin(Math.Pi * now_index.left / num[now_part.left]))); } if (now_part.main > now_part.right) { right_sprite.SetImage(bg[now_part.right][now_index.right]); right_sprite.SetOpacity(maxopa * Math.Abs(Math.Sin(Math.Pi * now_index.right / num[now_part.right]))); } white_sprite.SetPosition(pro * winwidth - winwidth, winheight - whiteheight, -5); time++; if (time % 2 == 0) { if (!cyc) { now_index.main++; if (now_index.main == num[now_part.main]) { now_index.main = 0; now_part.main++; if (now_part.main == parts) { now_part.main = parts - 1; cyc = 1; main_sprite.SetOpacity(0); } } } now_index.left++; if (now_index.left == num[now_part.left]) now_index.left = 0; now_index.right++; if (now_index.right == num[now_part.right]) now_index.right = 0; } } fun refresh_callback_shutdown () { now_part.main = 6; if (!end) { main_sprite.SetImage (bg[now_part.main][num[now_part.main] - now_index.main - 1]); } time++; if (time % 5 == 0) { if (!end) { now_index.main++; if (now_index.main == num[now_part.main]) { end = 1; main_sprite.SetOpacity(0); } } } } fun refresh_callback() { if (Plymouth.GetMode () == "boot") { refresh_callback_startup(); } else if (Plymouth.GetMode() == "shutdown") { refresh_callback_shutdown(); } } load(); init(); Plymouth.SetRefreshFunction (refresh_callback); /*-----end of main-----*/ fun progress_callback (time, progress) { pro = progress; } Plymouth.SetBootProgressFunction (progress_callback);