3

我有一个基本的 HTML Slider 元素。我希望制作的内容很简单——当滑块位于一端时,会输出一张简单的笑脸。当它在另一端时,输出一张简单的悲伤脸。

我想要的关键是从动画的一侧到另一侧的平滑过渡 - 所以笑脸会经历冷漠和轻微快乐/轻微悲伤的不同阶段。

假设滑块输出的浮点数介于 1 到 10 之间,对应于显示图像的“幸福度”。

你将如何解决这个问题?我试过搜索和谷歌搜索,但没有好的结果。可接受的所有技术——对如何存储图像/动画特别感兴趣。

4

5 回答 5

15

你可以使用 CSStransform: rotateX来做你想做的事。在我的版本中,我还使用了 HTML5inputtype="range",但如果您想影响旧浏览器,您可以使用相同的方法和更全局的滑块。该演示涉及使用两张图像,一张用于面部和背景,一张用于嘴唇,但如果您喜欢该技术,您可以以同样的方式将其应用于纯 CSS。只需确保在 javascript 中包含所需的所有浏览器前缀

现场演示在这里

/* HTML */
<div id='slimey'>
    <div id='lips'></div>
</div>
<input id="smileSlide" type="range" onchange="changeSmile(this)" value="0" />

/* Javascript */
var lips = document.getElementById('lips');
function changeSmile(slider) {
    var sliderVal = slider.value,
        rotateDegree = - sliderVal * 1.8;
    lips.style.webkitTransform = "rotateX(" + rotateDegree + "deg)";
    lips.style.transform = "rotateX(" + rotateDegree + "deg)";
}

/* CSS */
#slimey {
    margin:auto;
    background:url(http://i.imgur.com/LGQMhc3.jpg);
    background-size: 100% 100%;
    height:100px;
    width:100px;
    position:relative;
}
#lips {
    width:50px;
    height:20px;
    position:absolute;
    top:calc(70% - 10px);
    left:calc(50% - 25px);
    background:url(http://i.imgur.com/20EmUM7.gif);
    background-size: 100% 100%;
    -webkit-transform:rotateX(0deg);
    transform:rotateX(0deg);
}
#smileSlide {
    width:100px;
    position:absolute;
    left:calc(50% - 50px);     
}

灵感来自Marco Barria(这家伙有一些很棒的项目)单元素飞鸟

如果你想让中间状态更明显,你可以像这个演示一样在中间范围内切换一行的显示。像这个答案的其余部分一样,它只是一个近似的解决方案,但我认为它很好地展示了这项技术。如果你想变得超级花哨,你甚至可以为线条添加淡入/淡出,使其看起来更平滑一点

于 2013-10-07T04:26:56.727 回答
5

我通过使用纯 css 和 js(没有任何图像或旋转)改变了 Zeaklous 的答案 http://jsfiddle.net/sijav/PVvc4/3/

<!--HTML-->
<div id='slimey'>
    <div id='leye' class='eye'></div>
    <div id='reye' class='eye'></div>
    <div id='lips'></div>
</div>
<input id="smileSlide" type="range" onchange="changeSmile(this)" value="0" />

//Java Script
var lips = document.getElementById('lips');
function changeSmile(slider) {
    var lh = lips.style.height, slide=0;
    if ((50 - slider.value) > 0){
        slide = (50 - slider.value);
        lips.style.borderTop = "2px black solid";
        lips.style.borderBottom = "none";
    }
    else {
        slide = (slider.value - 50);
        lips.style.borderBottom = "2px black solid";
        lips.style.borderTop = "none";
    }
    lips.style.height = slide * 0.4 + "px" ;
    lips.style.top = "calc(70% + " + (- slide) * 0.2 + "px" ;
}

/**CSS**/
#leye{
    left:25%;
}
#reye{
    right:25%;
}
.eye{
    position:absolute;
    background:black;
    border-radius:100%;
    height:15px;
    width:15px;
    top:20px;
}
#slimey {
    margin:auto;
    background:Yellow;
    border-radius:100%;
    height:100px;
    width:100px;
    position:relative;
}
#lips {
    width:50px;
    height:20px;
    position:absolute;
    top:calc(70% - 10px);
    left:calc(50% - 25px);
    background:transparent;
    border-top:2px black solid;
    -webkit-transform:rotateX(0deg);
    border-radius:100%;
    transform:rotateX(0deg);
}
#smileSlide {
    width:100px;
    position:absolute;
    left:calc(50% - 50px);     
}

编辑:嘴唇在这里移动的细微差别http://jsfiddle.net/sijav/PVvc4/4/

于 2013-10-07T22:45:30.283 回答
5

为了好玩,我在午餐时用纯 CSS(没有图像或 JavaScript)编写了一个纯 Webkit 的小版本——<strong>这是一个演示。我不一定会推荐这种方法,但我忍不住试一试!


这是一个非常简单的方法。我使用了一组单选按钮而不是滑块,它允许您使用:checked伪类根据所选值更改嘴巴的颜色和形状。嘴形是用height和来描述的border-radius。例如:

#feel-0:checked ~ #mouth {
    border-radius: 30px 30px 0 0;
    height: 20px;
    margin-top: -5px;
}

说明文本只是所选单选按钮的标签字段。最初所有标签都是隐藏的,但是一旦选中一个字段,相邻的标签就会变得可见:

#happiness input:checked + label {
    visibility: visible;
}

您可以使用箭头键更改选择的字段(视觉上向左或向右移动滑块) - 这是单选组的内置行为。

通过一些工作,您可以调整它以使滑块在非 WebKit 浏览器中看起来更好;但是,在某些较旧的浏览器中它可能会出现问题,并且您无法向左或向右拖动滑块。对于生产,我会使用 JavaScript 滑块(例如,许多可用的jQuery 选项之一)并将 CSS 伪类魔法换成少量 JS 和少数类。

于 2013-10-10T12:29:29.593 回答
3

如果您可以在 SVG 中绘制脸部,则可以使用 Raphael 之类的东西。例如,如果您要保持相同的圆脸并仅变形嘴巴。这将在形状之间设置动画。不太确定这是否是您的意思。这是我的 2 秒可怕的嘴巴路径。

var paper = Raphael( "canvas_container",400,400);

paper.circle(280, 210, 150);
// create the 2 paths to animate between in some app like inkscape
var pathStr1 = "m385,255l-197,-3l40,57l88,1l35,0l34,-55z", 
pathStr2 =  "m207,268l162,-1l-33,-45l-41,-2l-46,-1l-32,20l-10,29z"; 

var path = paper.path(pathStr1).attr({fill: "yellow", "stroke-width": 3}); 

setTimeout(function(){path.animate({path: pathStr2}, 3000, "linear");}, 1000);  

在http://jsfiddle.net/YUhHw/1/有一个小提琴,在http://cancerbero.mbarreneche.com/raphaeltut/#sec-animation有更好的例子(上面的代码基于部分)的教程,在 http有很好的例子://raphaeljs.com/animation.html我想您需要更改 setTimeout 以对应您的滑块。

于 2013-10-01T21:38:24.873 回答
1

只需使用一个没有嘴巴的 png 脸,以及几个基于 Javascript 滑块位置切换的补间嘴巴。将文件存储在数组中,并从定时函数调用它们以检查面部位置。简单轻便。

var mouthArray = new Array('frown','half_frown','half_smile','smile');
var face       = document.getElementById('face');
var faceLoc    = parseInt(face.style.left);
function changeMouth() {
 if(faceLoc<10)
  {theMouth.setAttribute('src',mouthArray[0]);}
 if(faceLoc>10,faceLoc<=19)
  {theMouth.setAttribute('src',mouthArray[1]);}
 if(faceLoc>20,faceLoc<=29)
  {theMouth.setAttribute('src',mouthArray[2]);}
 if(faceLoc>30,faceLoc<40)
  {theMouth.setAttribute('src',mouthArray[3]);} 
}

如果对滑块的长度给予足够的迭代,沿着这些思路的东西应该会给你一个体面的“平滑”效果。

于 2013-10-08T16:55:20.717 回答