用 JavaScript 和 Emoji 做地址栏动画

原文地址:Animating URLs with Javascript and Emojis

原文作者:Matthew Rayfield

译者:Wpeach

你可以在地址栏使用 emoji(和其它图形 unicode 字符),这看着很棒,但是好像没人这么做,为什么呢?也许 emoji 对于正常的网络平台来说太过异国情调了?或许是他们因为害怕不利于SEO?

不管什么原因,维恩图中的合理性观点“没人这么做,但这是可能的”是让我兴奋的点。所以我决定花费一些时间研究在地址栏中图形字符的可能性,特别是通过 JavaScript 给这些字符加上动画。

循环动画

首先,确保你页面的 JavaScript 代码是 UTF-8 编码,否则无法在你的代码中显示 emoji,这可以通过设置 HTTP 头部或页面的 META 标签来实现。你很可能不用担心这个,但你可以在这里找到更多信息:Unicode in Javascript by Flavio

为了达到我们想要的效果,让 emoji 像小仙女一样在地址栏里偏偏起舞,我们需要一个循环,实际上,我们所需要的只是一个循环,我们启动这个循环,它不断循环,我们的目的就达到了。这是我们的第一个循环动画,一个旋转的emoji 月亮。我猜当他们添加这个 emoji 序列时,也有这个想法吧?

var f = ['🌑','🌒','🌓','🌔','🌝','🌖','🌗','🌘'];

function loop(){

        location.hash = f[Math.floor((Date.now()/100)%f.length)];

        setTimeout(loop,50);

    }

    loop();

运行代码,你可以在地址栏看到此循环的结果。

如果你不喜欢旋转的月亮,你可以选择任何你喜欢的 emoji 来替换这个数组,比如一个时钟:

varf = ['🕐','🕑','🕒','🕓','🕔','🕕','🕖','🕗','🕘','🕙','🕚','🕛'];复制代码

这是一个非常简单的例子,真的非常简单,所以我们来升级一下循环,让它显示一串 emoji ! 这次我们使用 emoji 的skin tone modifiers肤色调节属性来制作一些变色宝宝:

var e = ['🏻','🏼','🏽','🏾','🏿'];

function loop(){

    var s ='', i, m;

    for(i =0; i <10; i ++) {

            m =Math.floor(e.length * ((Math.sin((Date.now()/100) + i)+1)/2));

            s +='👶'+ e[m];

        }

        location.hash = s;

        setTimeout(loop,50);

    }

    loop();

我们可以使用时间和位置控制的正弦波来选择我们想要的颜色,这给了我们一个很好的颜色变幻效果!

比如我们再来一次月亮旋转,使它展开,制作一个类似于加载条的动画?好的,开始实现:

var f = ['🌑', '🌘', '🌗', '🌖', '🌕', '🌔', '🌓', '🌒'],

        d = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

        m = 0;

    function loop() {

        var s = '', x = 0;

        if (!m) {

            while (d[x] == 4) {

                x ++;

            }

            if (x >= d.length) m = 1;

            else {

                d[x] ++;

            }

        }

        else {

            while (d[x] == 0) {

                x ++;

            }

            if (x >= d.length) m = 0;

            else {

                d[x] ++;

                if (d[x] == 8) d[x] = 0;

            }

        }

        d.forEach(function (n) {

            s += f[n];

        });

        location.hash = s;

        setTimeout(loop, 50);

    }

    loop();

探索其它字符

不止是 emoji 给我们提供了一种在地址栏显示图形的方法,我们的目标中也有一些 unicode 字符。

特别有趣的是框线字符:


它们中很多更适合二维输出,但它们在一维输出也很棒,例如,我们可以创建一个多个高度变化的块字符串,并构造一个漂亮的小波浪动画:

function loop() {

        var i, n, s = '';

        for (i = 0; i < 10; i++) {

            n = Math.floor(Math.sin((Date.now()/200) + (i/2)) * 4) + 4;

            s += String.fromCharCode(0x2581 + n);

        }

        window.location.hash = s;

        setTimeout(loop, 50);

    }

    loop();

我非常喜欢它的效果,我把它永久放在了wavyurl.com上。

使用可变宽度字符,我们甚至在水平方向上摆动,创建类似于进度条的东西:

function loop() {

        var s = '',

            p;

        p = Math.floor(((Math.sin(Date.now()/300)+1)/2) * 100);

        while (p >= 8) {

            s += '█';

            p -= 8;

        }

        s += ['⠀','▏','▎','▍','▌','▋','▊','▉'][p];

        location.hash = s;

        setTimeout(loop, 50);

    }

进度条?这看起来,还是有用的,这让我想到了……

在地址栏显示视频进度

为了增加我们小实验的可能性,我提出了在地址栏中显示网络视频进度的想法。我只需附加一个函数,将我们的进度字符串定义在视频的timeupdate事件中,瞧!地址栏中的视频进度条包含时间和持续时间!

var video;

    function formatTime(seconds) {

        var minutes = Math.floor(seconds/60),

            seconds = Math.floor(seconds - (minutes*60));

        return ('0'+minutes).substr(-2) + ':' + ('0'+seconds).substr(-2);

    }

    function renderProgressBar() {

        var s = '',

            l = 15,

            p = Math.floor(video.currentTime / video.duration * (l-1)),

            i;

        for (i = 0; i < l; i ++) {

            if (i == p) s +='◯';

            else if (i < p) s += '─';

            else s += '┄';

        }

        location.hash = '╭'+s+'╮'+formatTime(video.currentTime)+'╱'+formatTime(video.duration);

    }

    video = document.getElementById('video');

    video.addEventListener('timeupdate', renderProgressBar);

我比较喜欢这个线条和圆组成的进度条,如果你喜欢别的 emoji 比如月亮,我也能让你满意:

var e = ['🌑', '🌘', '🌗', '🌖', '🌕'],

        video;

    function formatTime(seconds) {

        var minutes = Math.floor(seconds/60),

            seconds = Math.floor(seconds - (minutes*60));

        return ('0'+minutes).substr(-2) + ':' + ('0'+seconds).substr(-2);

    }

    function renderProgressBar() {

        var s = '',

            c = 0,

            l = 10,

            p = Math.floor(video.currentTime / video.duration * ((l*5)-1)),

            i;

        while (p >= 5) {

            s += e[4];

            c ++;

            p -= 5;

        }

        s += e[p];

        c ++;

        while (c < l) {

            s += e[0];

            c ++;

        }

        location.hash = s+formatTime(video.currentTime)+'╱'+formatTime(video.duration);

    }

    video = document.getElementById('video');

    video.addEventListener('timeupdate', renderProgressBar);

好的,将此进度条称为“有用”的延伸。 只瞄一眼,我也可以看到在视频分享 URL 中的进度。 与YouTube一样,你可以选择在特定时间创建指向视频的链接,添加视觉指示是不是很酷?嗯?

也许我还没有提出一些更有用的“技术”实现,我会继续思考这个问题。 嘿,也许你可以尝试一些东西?

最后

你可能想知道为什么我使用location.hash =,而不是新且酷的HTML5 History API。 有两个原因:

第一个问题是History API有一个特点:它实际上更改了整个 URL 路径,而不仅仅是hash。 因此,如果我使用History API并将页面更改为/🌑🌘🌗🌖🌕,它看起来会比添加 # 更好。 但这也意味着我的 Web 服务器必须能够响应/🌑🌘🌗🌖🌕,否则如果用户刷新或以其他方式导航到修改后的 URL 将会失败。 这是可行的,但比使用location.hash =更复杂,需要我修改服务器配置。

第二个问题有些出乎意料。 实际上,在我测试的3个浏览器中,有2个历史API被限制的。 如果我以极快的速度将我的波形网址推送到地址栏,我最终会在 Chrome 中收到以下错误:

Throttling history state changes to prevent the browser from hanging.

Safari 给我们提供了更详细的信息:

SecurityError: Attempt to use history.pushState() more than 100 times per 30.000000 seconds

现在,如果让我保持在这个限制下也行,但是每秒3帧只是不会影响我目前的动画效果。

好孩子 Firefox 似乎并不在乎我推送新历史的次数和速度,这真是想得太周到了。但是,两个主要的浏览器受到影响,加上需要web服务器配置来修复第一个问题,使我更愿意忍受 URL 中的 #。

结语

我就讲到这里。但我要告诉你,我还有一些想法,让小游戏显示在地址栏。特别是考虑到盲文字符我们还没有探索,所以请继续关注。

如果你有任何问题、评论,或者只是想了解我的最新进展,请在 Twitter 上关注我:@MatthewRayfield。或者点这里订阅我的几乎从未被打扰过的电子邮件。

哦,如果你想要以上示例的源代码,点这下载


转自:https://juejin.im/post/5c49b822f265da6142743a87?utm_source=gold_browser_extension#%E2%96%81%E2%96%82%E2%96%84%E2%96%86%E2%96%88%E2%96%88%E2%96%88%E2%96%87%E2%96%85%E2%96%83

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容