我正在创建旋转环的动画。
悬停时,右旋转180度,暂停并旋转回起始位置。如果用户将光标移离环,而其动画需要从当前开启的帧反转。
在我作为前端开发人员的职业生涯中,我没有太多丰富的动画经验,所以任何有关技术使用的建议都会受到赞赏。
目前我正在使用带有精灵的CSS动画,如下所示,但它缺乏从用户离开戒指时所用的框架反转的能力。
这是我的工作示例,它的灵感来自http://renren.com/
$('body').on('mouseenter', '.item', function() {
$(this).removeClass('unactive').addClass('active');
});
$('body').on('mouseleave', '.item', function() {
$(this).removeClass('active').addClass('unactive');
});
.content {
width: 150px;
height: 150px;
background-color: #EBEBEB;
}
.content.ring {
background: url(http://a.xnimg.cn/nx/apps/login/cssimg/qrcode1-t.jpg) 0 0 no-repeat
}
.active .content {
background-position: 0 -1800px;
-moz-animation: movedown 2000ms steps(12) forwards;
-webkit-animation: movedown 2000ms steps(12) forwards
}
.unactive .content {
-moz-animation: moveup 2000ms steps(7) forwards;
-webkit-animation: moveup 2000ms steps(7) forwards
}
@-moz-keyframes movedown {
0% {
background-position: 0 0
}
100% {
background-position: 0 -1800px
}
}
@-moz-keyframes moveup {
0% {
background-position: 0 -1800px
}
100% {
background-position: 0 -2850px
}
}
@-webkit-keyframes movedown {
0% {
background-position: 0 0
}
100% {
background-position: 0 -1800px
}
}
@-webkit-keyframes moveup {
0% {
background-position: 0 -1800px
}
100% {
background-position: 0 -2850px
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
HTML
<div class="item active">
<div class="content ring">
</div>
</div>
我还发现了以下插件: motio
所以我的问题是,CSS能够拥有这么多控件,还是CANVAS或其他jQuery插件更适合?
修改
虽然我开始编写一个脚本来帮助控制动画,但我仍然很难解决这个问题。
我正在尝试控制背景位置以控制精灵旋转。
;(function($) {
var Ring = function (options) {
// context
var self = this;
// defaults
var currFrame = 1, totalFrames, width, height, timeout;
// default frame array
var framesObj = {};
// option defaults
self.class = "";
self.spriteHeight = "";
//properties based on options
if (typeof options != 'undefined' && options != undefined && options != null)
{
self.class = options.class;
self.spriteHeight = options.spriteHeight;
self.speed = options.speed;
}
// fire off everything you need
self.init = function ()
{
self.buildArr();
}
// check for the container dimentions
self.frameDimentions = function ()
{
// double check we have a class to select the container with
var container = self.class ? true : false;
// I know I could just write self.class in the if..
if ( container )
{
var container = $("." + self.class + "");
var containerHeight = container.outerHeight();
var containerWidth = container.outerWidth();
return [containerHeight,containerWidth];
}
console.log("Please provide a class");
}
// calculate frames e.g. 3000 into 150 per frame is 20..
self.calcFrames = function()
{
var totalFrames = parseInt(self.spriteHeight) / self.frameDimentions()[0];
return totalFrames;
}
self.buildArr = function()
{
// these values need to be pushed in to the arr
for (var i = 0; i < self.calcFrames(); i++) {
framesObj[(i+1)] = self.frameDimentions()[0]*i;
}
}
self.startForwardAnimation = function(){
// to stop manic clicking../hover..
if( currFrame <= 1 )
{
timeout = setInterval( updateFrameForward, self.speed);
}
}
self.startBackwardAnimation = function(){
// to stop manic clicking../hover..
console.log("start backward animation");
if( currFrame != 1 )
{
backTimeout = setInterval( updateFrameBackward, self.speed);
}
}
self.stopAnimation = function(){
//currFrame = 1;
clearTimeout(timeout);
}
self.reset = function(){
clearTimeout(timeout);
clearTimeout(backTimeout);
currFrame = 1;
}
self.info = function(){
$('.info').html(currFrame);
}
// if currFrame less than total frames
// add one to it
// update the current frame variable
// stop and clear timer when reach the end
function updateFrameForward(){
//check if we are in available frames..
if ( currFrame == self.calcFrames() )
{
self.stopAnimation();
self.reset();
}
$("." + self.class + "").css({
'background-position-y': "-" + framesObj[currFrame] + "px"
});
self.info();
currFrame = currFrame + 1;
}
function updateFrameBackward(){
if( currFrame <= 1 )
{
self.stopAnimation();
self.reset();
}
$("." + self.class + "").css({
'background-position-y': framesObj[currFrame] + "px"
});
self.info();
console.log(currFrame);
currFrame = currFrame - 1;
}
}
var ringAniamtion = new Ring({
class: "animate",
spriteHeight: "3000",
speed: "20"
});
$('body').on('mouseenter', '.animate', function(event){
event.preventDefault();
console.log("mouse enter");
ringAniamtion.buildArr();
ringAniamtion.startForwardAnimation();
});
$('body').on('mouseleave', '.animate', function(event){
event.preventDefault();
console.log("mouse leave");
ringAniamtion.stopAnimation();
ringAniamtion.startBackwardAnimation();
});
$('body').on('click', '.stop', function(event){
event.preventDefault();
ringAniamtion.reset();
});
})( jQuery );
// timeout = setTimeout('timeout_trigger()', 3000);
// clearTimeout(timeout);
.content
{
width: 150px;
height: 150px;
background: url(http://a.xnimg.cn/nx/apps/login/cssimg/qrcode1-t.jpg) 0 0 no-repeat;
cursor: pointer;
}
<div class="content animate">
</div>
<div class="info">
</div>
<a href="" class="stop">stop</a>
答案 0 :(得分:0)
我想出了如何在第二段代码片段中完成它。
;(function($) {
var Ring = function (options) {
// context
var self = this;
// defaults
var currFrame = 1, totalFrames, width, height, timeout;
// default frame array
var framesObj = {};
// option defaults
self.class = "";
self.spriteHeight = "";
//properties based on options
if (typeof options != 'undefined' && options != undefined && options != null)
{
self.class = options.class;
self.spriteHeight = options.spriteHeight;
self.speed = options.speed;
}
// fire off everything you need
self.init = function ()
{
self.buildArr();
}
// check for the container dimentions
self.frameDimentions = function ()
{
// double check we have a class to select the container with
var container = self.class ? true : false;
// I know I could just write self.class in the if..
if ( container )
{
var container = $("." + self.class + "");
var containerHeight = container.outerHeight();
var containerWidth = container.outerWidth();
return [containerHeight,containerWidth];
}
console.log("Please provide a class");
}
// calculate frames e.g. 3000 into 150 per frame is 20..
self.calcFrames = function()
{
var totalFrames = parseInt(self.spriteHeight) / self.frameDimentions()[0];
return totalFrames;
}
self.buildArr = function()
{
// these values need to be pushed in to the arr
for (var i = 0; i < self.calcFrames(); i++) {
framesObj[(i+1)] = self.frameDimentions()[0]*i;
}
}
self.startForwardAnimation = function(){
// to stop manic clicking../hover..
if( currFrame <= 1 )
{
timeout = setInterval( updateFrameForward, self.speed);
}
}
self.startBackwardAnimation = function(){
// to stop manic clicking../hover..
console.log("start backward animation");
if( currFrame != 1 )
{
backTimeout = setInterval( updateFrameBackward, self.speed);
}
}
self.stopAnimation = function(){
//currFrame = 1;
clearTimeout(timeout);
}
self.reset = function(){
clearTimeout(timeout);
clearTimeout(backTimeout);
currFrame = 1;
}
self.info = function(){
$('.info').html(currFrame);
}
// if currFrame less than total frames
// add one to it
// update the current frame variable
// stop and clear timer when reach the end
function updateFrameForward(){
//check if we are in available frames..
if ( currFrame == self.calcFrames() )
{
self.stopAnimation();
self.reset();
}
$("." + self.class + "").css({
'background-position-y': "-" + framesObj[currFrame] + "px"
});
self.info();
currFrame = currFrame + 1;
}
function updateFrameBackward(){
if( currFrame <= 1 )
{
self.stopAnimation();
self.reset();
}
$("." + self.class + "").css({
'background-position-y': framesObj[currFrame] + "px"
});
self.info();
console.log(currFrame);
currFrame = currFrame - 1;
}
}
var ringAniamtion = new Ring({
class: "animate",
spriteHeight: "3000",
speed: "20"
});
$('body').on('mouseenter', '.animate', function(event){
event.preventDefault();
console.log("mouse enter");
ringAniamtion.buildArr();
ringAniamtion.startForwardAnimation();
});
$('body').on('mouseleave', '.animate', function(event){
event.preventDefault();
console.log("mouse leave");
ringAniamtion.stopAnimation();
ringAniamtion.startBackwardAnimation();
});
$('body').on('click', '.stop', function(event){
event.preventDefault();
ringAniamtion.reset();
});
})( jQuery );