草庐IT

JavaScript 缩小/增长循环过渡

coder 2024-07-15 原文

我在这里的第一个问题。 :)

我正在寻找两个图像之间的过渡,其中图像首先缩小为圆形,然后圆圈再次增长,包含另一个图像。这很难解释,而且我可能用错了词,因为我在 Interwebz 上找不到任何关于它的信息。

我说的是像 Loony Toons 结局这样的效果。
http://www.youtube.com/watch?v=ZuYIq-J5l9I

缩小到黑色,可以在 JavaScript/JQuery 中完成吗?

最佳答案

TL:博士

- 跨浏览器:[**查看工作演示
这里**](http://jsfiddle.net/lthibodeaux/8DSjz/)。
嗯,主要是工作......和
跨浏览器。可以做得更糟。 ;]
- 纯 CSS3 解决方案:[**查看工作演示
这里**](http://jsfiddle.net/lthibodeaux/8DSjz/16/)

我该如何开始描述这个?如果 CSS 2 剪辑标准支持除“矩形”值之外的任何内容,即“圆形”或“椭圆”,那会容易得多,但是......因为那不存在,我已经尽力拼凑一些东西一起做你所要求的。警告有很多。一个是,如果您希望将图片剪辑到背景,这仅适用于具有纯色背景的东西。另一个原因是,虽然我尝试考虑跨浏览器的 CSS 更新时间,但渲染仍然不是“完美的”。我最初的方法是简单地对要替换的图像上的剪辑进行动画处理,但是由于通过我找到的插件中的缓动功能对剪辑进行更新的方式,这不起作用。最后的方法如下。

方法

概念是将图像设置为 background-image<div> 这样的容器的属性与 background-positioncenter center ,以及 position将容器移至 relative ,或任何非静态的。接下来是生成剪辑元素作为容器的子项。第一个是 position: absolute背景颜色的剪裁圆图像,可以是透明的 PNG 或 GIF(我更喜欢前者),接下来的四个是 div,也是 absolute拥有 left 的职位, right , top , 和 bottom属性设置为 0 他们将剪辑的每一边。这个想法是动画 top , left , width , 和 height使用 .animate() 调用的 step 回调选项,通过将它们与当前 left 匹配来同步裁剪 div 的宽度和高度。和 top值(value)观。在动画之间,您更改 background-image将容器移动到新图像,然后以相反的方向开始动画。

这需要在 IE7、8 和 Webkit 浏览器中进行一些调整,因为动画在 Firefox 和 IE9 中剪辑得更加干净。这将是 adjust您将在工作演示中看到的变量。

示例代码如下:

标记

<div class="imageContainer image1">
    <img class="clip" src="clipCircle.png" />
    <div class="top fill"></div>
    <div class="left fill"></div>
    <div class="right fill"></div>
    <div class="bottom fill"></div>
</div>

CSS
div.imageContainer
{
    background-position: center;
    width: 300px;
    height: 300px;
    position: relative;
}

img.clip
{
    width: 100%;
    height: 100%;
    position: absolute;
}

div.fill
{
    position: absolute;
    background-color: White;
}

div.left, div.right
{
    height: 100%;
    top: 0;
    width: 0;
}

div.left
{
    left: 0;
}

div.right
{
    right: 0;
}

div.top, div.bottom
{
    width: 100%;
    left: 0;
    height: 0;
}

div.top
{
    top: 0;
}

div.bottom
{
    bottom: 0;
}

脚本
var speed = 1000;

$clip = $("img.clip");

$clip.animate({
    top: $clip.parent().height() / 2,
    left: $clip.parent().width() / 2,
    width: 0,
    height: 0
}, {
    duration: speed,
    step: function(now, fx) {
        switch (fx.prop) {
        case "top":
            $("div.top").css("height", now);
            $("div.bottom").css("height", now + adjust);    
            break;
        case "left":
            $("div.left").css("width", now);
            $("div.right").css("width", now + adjust);
        }
    },
    complete: function() {
        $(this).parent().addClass("image2");

        $(this).animate({
            top: 0,
            left: 0,
            width: $clip.parent().width(),
            height: $clip.parent().height()
        }, {
            duration: speed,
            step: function(now, fx) {
                switch (fx.prop) {
                case "top":
                    $("div.top").css("height", now);
                    $("div.bottom").css("height", now + adjust);    
                    break;
                case "left":
                    $("div.left").css("width", now);
                    $("div.right").css("width", now + adjust);
                }
            },
            complete: function() {
                $("div.imageContainer > *").removeAttr("style");
            }
        });
    }
});

编辑:

CSS3 解决方案

当跨浏览器兼容性不那么重要时,CSS3 是一种选择(尽管我可能会建议看看新的 HTML5 Canvas 可以为这种动画做什么)。有几点需要注意:
  • 图像必须在容器内,以便我们可以向其中心而不是左上角剪辑。
  • border-radius 属性不会裁剪容器内的子图像。为此,图像必须成为容器的背景图像属性。
  • jQuery 目前没有正确地为边界半径设置动画。您可以替换该属性的当前 jQuery 动画功能或构建自定义边框半径动画对象以使 jQuery 表现得更好。我选择了后者。每个 Angular 的边界半径必须单独设置动画。
  • 进出动画由两个单独的段组成,因此“线性”缓动函数可能最适合用于最干净的结果。

  • 该方法在下面内联注释:

    标记
    <div class="imageContainer image1">
    </div>
    

    CSS
    div.imageContainer
    {
        background-position: 0px 0px;
        background-repeat: no-repeat;
        width: 300px;
        height: 300px;
        position: absolute;
        top: 0;
        left: 0;
    }
    
    div.image1
    {
        background-image: url(/images/myFirstImage.png);
    }
    
    div.image2
    {
        background-image: url(/images/mySecondImage.png);
    }
    

    脚本
    // Total animation speed in or out will be speed * 1.5
    var speed = 600;
    
    // Store a reference to the object to be clipped
    var $clip = $("div")
    
    // A function to build a mapping object for border radius parameters
    var buildRadiusObj = function(value) {
    
        // Dimension an option object
        var opts = {};
    
        // Use specialized Mozilla CSS attributes when needed
        var attributes = $.browser.mozilla ?
            ["-moz-border-radius-topleft",
             "-moz-border-radius-bottomleft",
             "-moz-border-radius-topright",
             "-moz-border-radius-bottomright"] :
            ["border-top-left-radius",
             "border-bottom-left-radius",
             "border-top-right-radius",
             "border-bottom-right-radius"];
    
        // Build the option object
        $.each(attributes, function(i, key) {
            opts[key] = value;
        });
    
        // Return the result
        return opts;
    }
    
    $clip.animate(buildRadiusObj($clip.width() * 0.5), {    // Animate the border radius until circular
        duration: speed * 0.5,
        easing: "linear"
    }).animate({                                            // Resize and reposition the container
        width: 0,
        left: $clip.width() / 2,
        height: 0,
        top: $clip.height() / 2
    }, {
        duration: speed,
        easing: "linear",
        step: function(now, fx) {                           // Synch up the background-position
            if (fx.prop == "top") {
                $(this).css("background-position", "-" + $(this).css("top") + " -" + $(this).css("left"));
            }
        },
        complete: function() {                              // Swap the image
            $(this).addClass("image2");
        }
    }).animate({                                            // Restore position and size
        width: $clip.width(),
        left: 0,
        height: $clip.height(),
        top: 0
    }, {
        duration: speed,
        easing: "linear",
        step: function(now, fx) {                           // Synch the background-position
            if (fx.prop == "top") {
                $(this).css("background-position", "-" + $(this).css("top") + " -" + $(this).css("left"));
            }
        },
        complete: function() {                              // Remove inline styles but reapply border-radius
            $(this).removeAttr("style").css(buildRadiusObj($clip.width() * 0.5));
        }
    }).animate(buildRadiusObj(0), {                         // Restore border-radius to block
        duration: speed * 0.5,
        easing: "linear",
        complete: function() {
            $(this).removeAttr("style");                    // Remove inline styles
        }
    });
    

    Again, the demo is located here.

    关于JavaScript 缩小/增长循环过渡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5365322/

    有关JavaScript 缩小/增长循环过渡的更多相关文章

    1. ruby - 树顶语法无限循环 - 2

      我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He

    2. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

      我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

    3. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

      我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

    4. ruby - Ruby 中的闭包和 for 循环 - 2

      我是Ruby的新手,有些闭包逻辑让我感到困惑。考虑这段代码:array=[]foriin(1..5)array[5,5,5,5,5]这对我来说很有意义,因为i被绑定(bind)在循环之外,所以每次循环都会捕获相同的变量。使用每个block可以解决这个问题对我来说也很有意义:array=[](1..5).each{|i|array[1,2,3,4,5]...因为现在每次通过时都单独声明i。但现在我迷路了:为什么我不能通过引入一个中间变量来修复它?array=[]foriin1..5j=iarray[5,5,5,5,5]因为j每次循环都是新的,我认为每次循环都会捕获不同的变量。例如,这绝对

    5. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

      我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

    6. Ruby:数组中的下一个/上一个值,循环数组,数组位置 - 2

      假设我有一个没有特定顺序的随机数数组。假设这些是参加马拉松比赛的人的ID#,他们按照完成的顺序添加到数组中,例如:race1=[8,102,67,58,91,16,27]race2=[51,31,7,15,99,58,22]这是一个简化且有些做作的示例,但我认为它传达了基本思想。现在有几个问题:首先,我如何获得特定条目之前和之后的ID?假设我正在查看运行者58,我想知道谁在他之前和之后完成了比赛。race1,runner58:previousfinisher=67,nextfinisher=91race2,runner58:previousfinisher=99,nextfinishe

    7. ruby - 在 Mechanize 中使用 JavaScript 单击链接 - 2

      我有这个:AccountSummary我想单击该链接,但在使用link_to时出现错误。我试过:bot.click(page.link_with(:href=>/menu_home/))bot.click(page.link_with(:class=>'top_level_active'))bot.click(page.link_with(:href=>/AccountSummary/))我得到的错误是:NoMethodError:nil:NilClass的未定义方法“[]” 最佳答案 那是一个javascript链接。Mechan

    8. ruby - 奇怪的 ruby​​ for 循环行为(为什么这样做有效) - 2

      defreverse(ary)result=[]forresult[0,0]inaryendresultendassert_equal["baz","bar","foo"],reverse(["foo","bar","baz"])这行得通,我想了解原因。有什么解释吗? 最佳答案 如果我使用each而不是for/in重写它,它看起来像这样:defreverse(ary)result=[]#forresult[0,0]inaryary.eachdo|item|result[0,0]=itemendresultendforainb基本上就

    9. ruby - 如何证明 Ruby `for` 循环实际上是使用 `each` 方法实现的? - 2

      在EloquentRuby(第21页,第一版,第六次打印)一书中,作者(RussOlsen)提倡使用each方法而不是for循环,这与我在其他地方读到的所有内容一致。但是作者还继续说,这样做的一个原因是for循环实际上调用了each方法,所以为什么不直接删掉中间人并使用each?所以我想知道这实际上是如何工作的。为了调查,我确实在github上的Ruby存储库上进行了搜索,但发现很难确定我在哪里/如何看到它的实际效果。重述问题:我如何证明Rubyfor循环实际上是使用each方法实现的? 最佳答案 您可以通过编写一个实现每个的类来展

    10. ruby - 循环遍历数组的元素 - 2

      我想从0到2循环@a:0,1,2,0,1,2。defset_aif@a==2@a=0else@a=@a+1endend也许有更好的方法? 最佳答案 (0..2).cycle(3){|x|putsx}#=>0,1,2,0,1,2,0,1,2item=[0,1,2].cycle.eachitem.next#=>0item.next#=>1item.next#=>2item.next#=>0... 关于ruby-循环遍历数组的元素,我们在StackOverflow上找到一个类似的问题:

    随机推荐