Firefox CSS 旋转与 Chrome 旋转不同

2024-05-13

我想制作一个 3D 矩形(平行六面体),用户可以用箭头移动它。它在 Chrome 中工作得很好,但在 Firefox 中,一些转换(实际上很多)与 Chrome 不同。看着this https://jsfiddle.net/7273yur9/2/小提琴(这是我的整个代码)并在两个浏览器中进行比较以更好地理解。

因为第一个小提琴包含很多代码,所以我将简化它并选择一个随机的奇怪过渡。看着this https://jsfiddle.net/L36v50kh/拨弄,然后按一次“向左”按钮或向左箭头。它工作正常,但是当您再次按下它时,矩形旋转 3 次而不是 1 次。

这是 Firefox 的错误还是我做错了什么?

下面的代码是您将在简化的小提琴中找到的代码。

var position = 'show-front';

$('#left').bind('click', function() {
    if (position == 'show-front') {
        $('#box').removeClass().addClass('show-right');
        position = 'show-right';
    } else if (position == 'show-right') {
        $('#box').removeClass().addClass('show-back-3');
        position = 'show-back-3';
    } else if (position == 'show-back-3') {
        $('#box').removeClass().addClass('show-left');
        position = 'show-left';
    } else if (position == 'show-left') {
        $('#box').removeClass().addClass('show-front');
        position = 'show-front';
    }
});
    
$(window).bind('keyup', function(event) {
    switch (event.keyCode) {
        case 37: // left
            $('#left').click();
            break;
    }
});
.container {
width: 150px;
height: 100px;
position: relative;
margin: 25px auto 25px auto;
perspective: 600px;
}

#box {
    width: 100%;
    height: 100%;
    position: absolute;
    transform-style: preserve-3d;
    transition: transform 1s;
}

#box figure {
    display: block;
    position: absolute;
    border: 1px solid black;
    line-height: 98px;
    font-size: 45px;
    text-align: center;
    font-weight: bold;
    color: white;
}

figure {
    margin: 0;
}

#box .front,
#box .back {
    width: 148px;
    height: 98px;
}

#box .right,
#box .left {
    width: 48px;
    height: 98px;
    left: 50px;
}

#box .top,
#box .bottom {
    width: 148px;
    height: 48px;
    top: 25px;
    line-height: 48px;
}

#box .front {
    background: hsla(000, 100%, 50%, 0.7);
}

#box .back {
    background: hsla(160, 100%, 50%, 0.7);
}

#box .right {
    background: hsla(120, 100%, 50%, 0.7);
}

#box .left {
    background: hsla(180, 100%, 50%, 0.7);
}

#box .top {
    background: hsla(240, 100%, 50%, 0.7);
}

#box .bottom {
    background: hsla(300, 100%, 50%, 0.7);
}

#box .front {
    transform: translateZ(25px);
}

#box .back {
    transform: rotateX(180deg) translateZ(25px);
}

#box .right {
    transform: rotateY(90deg) translateZ(75px);
}

#box .left {
    transform: rotateY(-90deg) translateZ(75px);
}

#box .top {
    transform: rotateX(90deg) translateZ(50px);
}

#box .bottom {
    transform: rotateX(-90deg) translateZ(50px);
}

#box.show-front {
    transform: translateZ(-50px);
}

#box.show-right {
    transform: translateZ(-150px) rotateY(-90deg);
}

#box.show-back-3 {
    transform: translateZ(-50px) rotateX(180deg) rotateZ(-180deg);
}

#box.show-left {
    transform: translateZ(-150px) rotateY(90deg);
}
<section class="container">
    <div id="box" class="show-front">
        <figure class="front">1</figure>
        <figure class="back">2</figure>
        <figure class="right">3</figure>
        <figure class="left">4</figure>
        <figure class="top">5</figure>
        <figure class="bottom">6</figure>
    </div>
</section>

基于 Firefox 在这方面只是有 bug 的假设(见下面的分析),这是一个解决方法 https://jsfiddle.net/955k5fhh/7/适用于 Firefox。它包裹着#box另一个元素中的元素div,并且仅转换包装器。而且包装器一次只能从起点向一个方向旋转 90 度,因此 Firefox 不会把它搞砸。

过渡完成后,旋转将重置回起始位置,同时内框旋转到新位置,两者都没有过渡,因此更改不可见。

第二个重要的变化是使用当前计算的变换#box并将旋转添加到其中,这样我们就不必在进行时跟踪旋转。

请注意,旋转的顺序很重要。为了实现您想要做的事情(在“世界空间”而不是“对象空间”中旋转),您需要以相反的顺序应用旋转。例如。要“向右”旋转,请使用.css("transform", "rotateY(90deg) " + currentComputedTransform)。这将解决您在评论中提到的问题,该问题似乎围绕错误的轴旋转。请参阅下面的详细信息。

另请注意,如果已经有轮换正在进行,我不允许开始轮换,因为这是行不通的。如果您希望能够这样做,您可以将击键排队到数组中,但您可能还希望在这种情况下减少与队列长度成比例的转换持续时间,这样就不会永远花费时间。

更新的小提琴:https://jsfiddle.net/955k5fhh/7/ https://jsfiddle.net/955k5fhh/7/

相关JavaScript:

$("#box").wrap("<div id='outer'></div>");
var pending=null;

function rotate(axis,angle,dir) {
    if (pending) return;
    $("#outer").removeClass().addClass(dir);
    var current=$("#box").css("transform");
    if (current=='none') current='';
    pending="rotate"+axis+"("+angle+"deg) "
      + current;
}

$("#outer").bind('transitionend', function() {
    $(this).removeClass();
    $("#box").css('transform',pending);
    pending=null;
});

$('#up').bind('click', function() {
    rotate('X',90,"up");
});

$('#down').bind('click', function() {
    rotate('X',-90,"down");
});

$('#right').bind('click', function() {
    rotate('Y',90,"right");
});

$('#left').bind('click', function() {
    rotate('Y',-90,"left");
});

之前的分析

我一直在研究基于 JS 的解决方案,并且发现了这篇有用的文章https://gamedev.stackexchange.com/a/67317 https://gamedev.stackexchange.com/a/67317- 它指出要在“世界空间”而不是“对象空间”中旋转对象,只需颠倒旋转顺序即可。

基于此,我将您的小提琴简化为以下内容:

var rot = "";
var tr = "translateZ(-50px)";

$('#up').bind('click', function() {
    rot=" rotateX(90deg)"+rot;
    $("#box").css("transform",tr+rot);
});

$('#down').bind('click', function() {
    rot=" rotateX(-90deg)"+rot;
    $("#box").css("transform",tr+rot);
});

$('#right').bind('click', function() {
    rot=" rotateY(90deg)"+rot;
    $("#box").css("transform",tr+rot);
});

$('#left').bind('click', function() {
    rot=" rotateY(-90deg)"+rot;
    $("#box").css("transform",tr+rot);
});

https://jsfiddle.net/955k5fhh/ https://jsfiddle.net/955k5fhh/(请注意,这不是一个完整的解决方案,因为最终rot字符串会变得太长)

在 Chrome 上,其行为符合预期。再一次,Firefox 会出错,即使你只是链接,例如的序列rotateX(90deg)转变。

所以我更进一步,在同一轴上卷起相邻的旋转......

var rots = [];
var tr = "translateZ(-50px)";

function transform() {
    var tf = "translateZ(-50px)";
    rots.forEach(function(rot) {
        tf += " rotate" + rot[0] + "(" + rot[1] + "deg)";
    });
    console.log(tf);
    $("#box").css("transform", tf);
}

function addRot(axis,angle) {
    if (rots.length==0 || rots[0][0]!=axis) {
        rots.unshift([axis,angle]);
    } else {
        rots[0][1]+=angle;
    }
    transform();
}

$('#up').bind('click', function() {
    addRot('X',90);
});

$('#down').bind('click', function() {
    addRot('X',-90);
});

$('#right').bind('click', function() {
    addRot('Y',90);
});

$('#left').bind('click', function() {
    addRot('Y',-90);
});

https://jsfiddle.net/955k5fhh/2/ https://jsfiddle.net/955k5fhh/2/

同样,它在 Chrome 中运行良好,在 Firefox 中运行得更好一些,但一旦你切换轴,你可能会以错误的方式旋转。同样,如果您在转换完成之前单击按钮,它可能会以错误的方式旋转。

所以我得出的结论是,不幸的是,Firefox 在这方面确实存在缺陷,但至少有解决方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Firefox CSS 旋转与 Chrome 旋转不同 的相关文章

  • 音频 blob 的 URL.createObjectURL 在 Firefox 中给出 TypeError

    我正在尝试从创建的音频 blob 创建对象 URLgetUserMedia 该代码在 Chrome 中可以运行 但在 Firefox 中存在问题 错误 当我打电话时stopAudioRecorder 它停在audio player src
  • 保持未知数量的 div 居中,每行最多 4 个

    我有一个简单的问题 但我自己无法解决 简而言之 有一个未知电话我必须在页面中放置的元素数量 最多 每行 4 个元素 但仍居中 此图片给您一个提示 我为了示例而设置它 详细 在上图中我涵盖了不同的场景 例如 如果总共有 5 个元素 则应使用第
  • Jquery/Javascript 上传和下载文件,无需后端

    是否可以在没有后端服务器的情况下在 JavaScript 函数中下载和上传文件 我需要导出和导入由 JavaScript 函数生成的 XML 我想创建按钮 保存 xml 来保存文件 但我不知道是否可行 另一方面 我希望将 XML 文件直接上
  • jquery从变量中删除html元素

    我将 html 保存在变量中 var itinerary events today html 我有很多 html 和一个按钮我想删除 它的 ID 为 myButton 如何从变量中保存的 html 中删除它 我建议这种方法 var itin
  • 跟踪用户何时点击浏览器上的后退按钮

    是否可以检测用户何时单击浏览器的后退按钮 我有一个 Ajax 应用程序 如果我可以检测到用户何时单击后退按钮 我可以显示适当的数据 任何使用 PHP JavaScript 的解决方案都是优选的 任何语言的解决方案都可以 只需要我可以翻译成
  • HTML 中部分着色的阿拉伯语单词

    我不会说阿拉伯语 但我需要我们网站上对阿拉伯语的具体支持 我需要将部分阿拉伯语单词放在 span 与单词其他部分的风格不同 当我输入两个字符时 and 它们被组合成word 但是当我使用 HTML 标记时 span span 这些字母在输出
  • 在 webpack 2.x 中使用 autoprefixer 和 postcss

    如何使用autoprefixer使用 webpack 2 x 以前 它曾经是这样的 module loaders test scss loader style css sass postcss postcss gt return autop
  • Babel 7 Jest Core JS“TypeError:wks不是函数”

    将我的项目升级到 Babel 7 后 通过 Jest 运行测试会抛出以下错误 测试在 Babel 6 中运行没有任何问题 但在 Babel 7 中失败并出现以下错误 TypeError wks is not a function at Ob
  • 动态img(或视频)标签根本不加载资源,HTTP请求处于“待处理”状态

    我尝试使用以下方法在 Web 应用程序上加载资源时遇到一些问题img or videoHTML 标签 我在我的应用程序中使用 Angular 并动态设置src的参数img标签 使用ng src src 指示 没有那么多图像和资源需要加载 在
  • Grails 在 javascript 内的 GSP 站点中使用 grails var

    我有一个在 GSP 文件中的 javascript 代码中使用 grails 变量值的问题 例如 我有一个会话值session getAttribute selectedValue 我想在 javascript 代码部分使用这个值 我现在的
  • Electron - 为什么在关闭事件时将 BrowserWindow 实例设置为 null

    The 电子文档 https electronjs org docs api browser window 提供以下代码示例来创建新窗口 const BrowserWindow require electron let win new Br
  • 为 illustrator 导出脚本以保存为 web jpg

    任何人都可以帮我为 illustrator CC2017 编写一个脚本 将文件以 JPG 格式导出到网络 旧版 然后保存文件并关闭 我有 700 个文件 每个文件有 2 个画板 单击 文件 gt 导出 gt 另存为 Web 旧版 然后右键文
  • 后台脚本 chrome.tabs 在 chrome 扩展中未定义?

    我试过这个 背景 js chrome browserAction onClicked addListener function activeTab chrome tabs query active true currentWindow tr
  • 在 vue.js 中访问数组对象属性

    给定以下数组vue js packageMaps Object packageMap 0 Object Id 16 PackageType flag list ProductCode F BannerBase packageMap 1 Ob
  • 指针事件:无,过滤,适用于 ie8 和任何地方,不适用于 ie9

    正如我在这里看到的 https stackoverflow com questions 3680429 click through a div to underlying elements 4839672 4839672 过滤器可用于模拟跨
  • 更改文本输入标签中文本的大小?

    我有一个很大的文本输入框 但我无法更改字体大小
  • 如何在jquery中以相反的顺序迭代元素? [复制]

    这个问题在这里已经有答案了 我是jquery的新手 我想知道如何使用each 在jquery中以相反的顺序迭代表单元素 任何帮助 将不胜感激 尝试这个 input get reverse each function
  • JQuery 图像上传不适用于未来的活动

    我希望我的用户可以通过帖子上传图像 因此 每个回复表单都有一个上传表单 用户可以通过单击上传按钮上传图像 然后单击提交来提交帖子 现在我的上传表单可以上传第一个回复的图像 但第二个回复的上传不起作用 我的提交过程 Ajax 在 php 提交
  • 带有相对路径的 LESS CSS 背景

    我在使用 LESS 作为我的网站的样式表时遇到了问题 就我个人而言 我宁愿在CSS中使用相对路径而不是绝对路径 这只是我的习惯 但是现在当我使用带有导入功能的LESS时 我遇到了如下所示的问题 我有一个main less根文件夹中的文件 i
  • 在 React.js 中编辑丰富的数据结构

    我正在尝试为数据结构创建一个简单的基于网格的编辑器 但我在使用 React js 时遇到了一些概念问题 他们的文档对此没有太大帮助 所以我希望这里有人可以提供帮助 首先 将状态从外部组件传输到内部组件的正确方法是什么 是否有可能将内部组件中

随机推荐