我需要旋转div并停在特定位置(该值将从服务器接收)。
我尝试使用本机JS进行旋转和停止,但它耗费了我的CPU时间。
我可以使用CSS动画旋转,但我需要创建一个动态描述停止动画的位置的类。像
这样的东西@-webkit-keyframes spinIt {
100% {
-webkit-transform: rotate(A_DYNAMIC_VALUE);
}
}
@-moz-keyframes spinIt {
100% {
-webkit-transform: rotate(A_DYNAMIC_VALUE);
}
}
这是一个参考
先谢谢
答案 0 :(得分:46)
You can insert stylesheet rules dynamically to override previous styles in the head. This helps avoid adding yet another library for a single task.
var style = document.createElement('style');
style.type = 'text/css';
var keyFrames = '\
@-webkit-keyframes spinIt {\
100% {\
-webkit-transform: rotate(A_DYNAMIC_VALUE);\
}\
}\
@-moz-keyframes spinIt {\
100% {\
-webkit-transform: rotate(A_DYNAMIC_VALUE);\
}\
}';
style.innerHTML = keyFrames.replace(/A_DYNAMIC_VALUE/g, "180deg");
document.getElementsByTagName('head')[0].appendChild(style);
答案 1 :(得分:32)
我认为创建动态 @keyframes
并不容易,因为它们必须是硬编码的。
转换更易于使用,因为它们可以优雅地响应JavaScript执行的任何CSS更改。
然而,CSS过渡所带来的复杂性非常有限 - 难以实现具有多个步骤的动画。
这是CSS @keyframe动画要解决的问题,但它们没有提供转换的动态响应级别。
但这些链接可能会对您有所帮助
Link1:一个生成带有许多微小步骤的@ -webkit关键帧动画的工具。这为无限选择的宽松配方打开了大门。
Link2 以它为基础将是一个很好的帮助,因为它提供了一个UI来创建动画并将其导出到CSS代码。
我想 this 解决方案绝对适合您。它用于动态关键帧
答案 2 :(得分:6)
亚历克斯格兰德的答案适用于几个关键帧。但是,假设你想要一遍又一遍地动态地继续添加关键帧,那么你的网页真的很快就会变得非常迟缓。要解决此问题,只需停止创建新的DOM元素即可。相反,创建1个新的DOM样式表,并将其与inertRule一起重用。如果您想要更多关键帧(例如,如果您在每个动画帧中生成新的关键帧),则需要设置一个系统,在不再使用旧关键帧后删除这些关键帧。这是一个良好的开端,可以实现这样的事情。
var myReuseableStylesheet = document.createElement('style'),
addKeyFrames = null;
document.head.appendChild( myReuseableStylesheet );
if (CSS && CSS.supports && CSS.supports('animation: name')){
// we can safely assume that the browser supports unprefixed version.
addKeyFrames = function(name, frames){
var pos = myReuseableStylesheet.length;
myReuseableStylesheet.insertRule(
"@keyframes " + name + "{" + frames + "}", pos);
}
} else {
addKeyFrames = function(name, frames){
// Ugly and terrible, but users with this terrible of a browser
// *cough* IE *cough* don't deserve a fast site
var str = name + "{" + frames + "}",
pos = myReuseableStylesheet.length;
myReuseableStylesheet.insertRule("@-webkit-keyframes " + str, pos);
myReuseableStylesheet.insertRule("@keyframes " + str, pos+1);
}
}
使用示例:
addKeyFrames(
'fadeAnimation',
'0%{opacity:0}' +
'100%{opacity:1}'
);
此外,Alex Grande,我非常确定自IE8以来不需要document.getElementsByTagName('head')[0]
和type = 'text/css'
,并且在IE10之前不支持@keyframes
。只是说...
答案 3 :(得分:2)
您可以在CSSKeyframeRule中更改样式,这对我来说在Chrome中运行正常,就像下面的代码一样。 希望这会有所帮助:)
<html>
<head>
<style>
#text {
display: inline-block;
}
</style>
</head>
<body>
<div id="text">TEXT</div>
<script>
// Dynamically create a keyframe animation
document.styleSheets[0].insertRule('\
@keyframes anim {\
from { transform: rotateZ(0deg); }\
to { transform: rotateZ(360deg); }\
}'
);
var div = document.getElementById('text');
div.style.animation = 'anim 1s linear forwards';
// This function will change the anim
function stopAtSomeDeg(d) {
var ss = document.styleSheets[0];
var anim;
for (var i in ss.cssRules) {
// Find your animation by name
if (ss.cssRules[i].name === 'anim') {
anim = ss.cssRules[i];
break;
}
}
var stopFrame = anim.cssRules[1]; // This indicates the second line of "anim" above.
// Change any attributes
stopFrame.style.transform = 'rotateZ(' + d + 'deg)';
}
stopAtSomeDeg(180);
</script>
</body>
</html>
答案 4 :(得分:1)
在JavaScript中,可以使用 document.styleSheets 访问样式表。每个工作表都有规则和/或 cssRule 列表(取决于浏览器)和CSSStyleSheet.insertRule()方法。
此方法允许您添加新的关键帧raw 作为字符串:
<强>的JavaScript 强>
function insertStyleSheetRule(ruleText)
{
let sheets = document.styleSheets;
if(sheets.length == 0)
{
let style = document.createElement('style');
style.appendChild(document.createTextNode(""));
document.head.appendChild(style);
}
let sheet = sheets[sheets.length - 1];
sheet.insertRule(ruleText, sheet.rules ? sheet.rules.length : sheet.cssRules.length);
}
document.addEventListener("DOMContentLoaded", event =>
{
insertStyleSheetRule("@keyframes spinIt { 0% { transform: rotate(-20deg); } 100% { transform: rotate(20deg); } }");
insertStyleSheetRule("#box { " +
"animation: spinIt 1s infinite alternate cubic-bezier(0.5,0,0.5,1); " +
"width: 64px; height: 64px; background-color: red; border: 4px solid black; " +
"}");
});
<强> HTML 强>
<div id="box"></div>
答案 5 :(得分:0)
user7892745不适合我,需要一些小调整
1°“pos”不明白应该是,但控制台日志说“未定义” 所以我删除了“,pos”
2°“myReuseableStylesheet.insertRule”给我错误“不是函数” 所以我使用了“insertRule”的“innerHTML”
3°终于我感动了“ document.head.appendChild(myReuseableStylesheet);“最后
但在此之后它工作正常,这正是我想要的。 非常感谢user7892745:D
也许我遇到的问题,就像我使用它的方式一样
这是我用它的脚本
var getclass = document.getElementsByClassName("cls");
var countclass = getclass.length;
for (var i=0; i <countclass; i++ ){
getclass[i].addEventListener('mouseover', function(){
// get the data-name value to show element whose id are the same
var x= this.getAttribute("data-name");
var y =document.getElementById(x);
y.style.display="block";
// because the element to show have fixed width, but different text length, they have different height
// so I need to get the highness, then use the value of height to define the 100% value of animation
// or the longer ones will be cutted an the shorten have a lot of empty space a the end
var yHeig= Math.round(parseInt(getComputedStyle(y).getPropertyValue('height')));
yHeig_ = yHeig - 10; // to shorten a bit the time from end and new passage
console.log(yHeig+" - "+ yHeig_);
addKeyFrames(
'showMe',
'0%{top:35px;}' +
'100%{top:-'+ yHeig_ +'px;}'
);
y.style.animation="showMe 7s linear infinite";
},false);
getclass[i].addEventListener('mouseout', function(){
var x= this.getAttribute("data-name");
document.getElementById(x).style.display="none";
},false);
}
我知道一个html选框cuold看起来很容易做同样的事情,但是效果不好,
答案 6 :(得分:0)
您可以创建一个<style>
元素,将其内容设置为所需的CSS,在这种情况下,将其声明为动画,并将其添加到页面的<head>
。
而且,正如其他人所建议的那样,如果您需要创建许多不同的动画,那么最好重用单个<style>
标签,而不是创建多个动画并使用{{3}添加新样式}。
最后,如果您可以使用ES6的CSSStyleSheet.insertRule()
,您的代码将看起来更加简洁:
let dynamicStyles = null;
function addAnimation(body) {
if (!dynamicStyles) {
dynamicStyles = document.createElement('style');
dynamicStyles.type = 'text/css';
document.head.appendChild(dynamicStyles);
}
dynamicStyles.sheet.insertRule(body, dynamicStyles.length);
}
addAnimation(`
@keyframes myAnimation {
0% { transform: rotate(0); }
20% { transform: rotate(${ 360 * Math.random() }deg); }
60% { transform: rotate(${ -360 * Math.random() }deg); }
90% { transform: rotate(${ 360 * Math.random() }deg); }
100% { transform: rotate(${ 0 }deg); }
}
`);
document.getElementById("circle").style.animation = 'myAnimation 3s infinite';
html,
body {
height: 100vh;
}
body {
display: flex;
justify-content: center;
align-items: center;
margin: 0;
}
#circle {
width: 100px;
height: 100px;
box-shadow:
0 0 48px -4px rgba(0, 0, 0, .25),
0 0 0 4px rgba(0, 0, 0, .02);
border-radius: 100%;
position: relative;
overflow: hidden;
}
#circle::before {
content: '';
position: absolute;
top: 0;
left: 50%;
transform: translate(-2px);
border-left: 4px solid #FFF;
height: 24px;
box-shadow: 0 -4px 12px rgba(0, 0, 0, .25);
}
<div id="circle"></div>
甚至更好:
let dynamicStyles = null;
function addAnimation(name, body) {
if (!dynamicStyles) {
dynamicStyles = document.createElement('style');
dynamicStyles.type = 'text/css';
document.head.appendChild(dynamicStyles);
}
dynamicStyles.sheet.insertRule(`@keyframes ${ name } {
${ body }
}`, dynamicStyles.length);
}
addAnimation('myAnimation', `
0% { transform: rotate(0); }
20% { transform: rotate(${ 360 * Math.random() }deg); }
60% { transform: rotate(${ -360 * Math.random() }deg); }
90% { transform: rotate(${ 360 * Math.random() }deg); }
100% { transform: rotate(${ 0 }deg); }
`);
document.getElementById("circle").style.animation = 'myAnimation 3s infinite';
html,
body {
height: 100vh;
}
body {
display: flex;
justify-content: center;
align-items: center;
margin: 0;
}
#circle {
width: 100px;
height: 100px;
box-shadow:
0 0 48px -4px rgba(0, 0, 0, .25),
0 0 0 4px rgba(0, 0, 0, .02);
border-radius: 100%;
position: relative;
overflow: hidden;
}
#circle::before {
content: '';
position: absolute;
top: 0;
left: 50%;
transform: translate(-2px);
border-left: 4px solid #FFF;
height: 24px;
box-shadow: 0 -4px 12px rgba(0, 0, 0, .25);
}
<div id="circle"></div>
答案 7 :(得分:0)
您可以使用所需的动画创建一个新的样式表。 例如:
function addAnimation(keyframe){
var ss=document.createElement('style');
ss.innerText=keyframe;
document.head.appendChild(ss);
}
这将为您的动画创建一个新的样式表。
该方法仅在Chrome中经过测试。
答案 8 :(得分:0)
让我分享一个更新的(2019)答案。 **是的,如果没有Java脚本,则可以使用CSS Variables(受所有现代浏览器支持)。
--lightScaleStart: 0.8;
.light {
animation: grow 2s alternate infinite ease-in-out;
}
.light.yellow {
--lightScaleEnd: 1.1;
}
.light.red {
--lightScaleEnd: 1.2;
}
@keyframes grow {
from {
transform: scale(var(--lightScaleStart));
}
to {
transform: scale(var(--lightScaleEnd));
}
}
请参阅有关Codepen Dynamic CSS Animations with CSS Variables的演示
答案 9 :(得分:0)
使用 CSS 变量:您可以使用元素的伪 :root
在 css 规则中声明一个 css 变量,然后使用 Javascript 操作该变量。
:root {
--variable-name:
property
;}
基本上是文档的根元素 {{1} }.然后使用 JS 更改 CSS 根变量/s 的值:
<html>
element.style.setProperty(
'--variable-name'
,
'value'
。将声明的根变量 )
作为名称传递并分配新值。然后在您的 --variable-name
css 规则中,添加根变量名称,例如:@keyframes
from: { top: var(
--top-position)
,以偏移量 }
规则中的属性。示例:
@keyframe
那么 JS 会像这样:
:root {
--top-position-start: 0px;
--left-position-start: 0px;
--top-position-end: 200px;
--left-position-end: 200px;
}
.element {
top: var(--top-position-start);
left: var(--left-position-start);
animation: movePos 1s ease-in;
}
@keyframes movePos {
from: {
top: var(--top-position-start);
left: var(--left-position-start);
}
to: {
top: var(--top-position-end);
left: var(--left-position-end);
}
}
通过在根元素上使用 CSS 变量,您可以将其传递给 @keyframes 事件。
使用 CSS let ran = getRandomInt(99);
let skew = ran + getRandomInt(10);
root.style.setProperty('--top-position-end', `${ran}vw`);
root.style.setProperty('--left-position-end', `${skew}vw`);
和 left
background-color:
{{1 使用随机放置的 div 查看以下工作示例}}rgb()
(
red
,
green
,
使用 html:root 样式传递给 @keyframes 在 CSS 中。
blue
)
let root = document.documentElement;
let rain = document.querySelectorAll('.drop');
function getMaxInt(max) {
return Math.floor(Math.random() * Math.floor(max));
}
function getMinMaxInt(min, max) {
return Math.random() * (max - min) + min;
}
// set an interval to drop the div from randomly positioned view widths on the screen
setInterval(() => {
let ran = getMaxInt(86);
let skew = ran + getMaxInt(10);
let circle = `${getMinMaxInt(3,15)}px`;
root.style.setProperty('--keyframeLeftStart', `${ran}vw`);
root.style.setProperty('--keyframeLeftEnd', `${skew}vw`);
root.style.setProperty('--animationDuration', `${ getMaxInt(2500)}ms`);
root.style.setProperty('--width', circle);
root.style.setProperty('--height', circle);
root.style.setProperty('--red', getMinMaxInt(100, 255));
root.style.setProperty('--green', getMinMaxInt(100, 255));
root.style.setProperty('--blue', getMinMaxInt(100, 255));
}, getMaxInt(3500))
答案 10 :(得分:0)
使用 JavaScript 在一次调用中设置 @keyframe,并使用它,使用 append()、Object.assign() 和 template strings。
document.body.append(
Object.assign(document.createElement("style"), {
textContent: `@keyframes coolrotate { from { transform: scale(1, 1) translate(-0.1em, 0)} to { transform: scale(-1, 1) translate(0, 0) }} small { display: inline-block; font-size:2.3em; animation: 1s infinite alternate coolrotate } body {font-size: x-large}`
}),
Object.assign(document.createElement("span"), {
innerHTML: `<span>c</span><small>o</small><span>o</span><small>L</small><small>...</small>`,
style: "font-weight: 1000; font-size: 3.3em;"
})
)
答案 11 :(得分:0)
现在可以使用新的 Web Animations API 轻松实现这一点。超人。
它可能看起来像:
let anim = document.getElementById('foo').animate(
[
{ transform: `rotate(${A_DYNAMIC_VALUE})` }
], {
duration: 3000 //Dunno if can be Infinite
});
// and later
anim.pause();
答案 12 :(得分:0)
通过使用 CSS 数据 URI 发现了一个简单的 JavaScript 想法。
function addNewCSS(css_text) {
css_text = encodeURIComponent(css_text);
const url = `data:text/css,${css_text}`;
const link = document.createElement("link");
link.rel = "stylesheet";
link.href = url;
document.head.appendChild(link);
}
函数接受 CSS 代码作为文本并将其添加为样式。
将 CSS 文本转换为 URI 编码形式(作为数据 URL 传递)。然后创建一个链接标签,以 href 为 url,关系为“样式表”(这里 rel 属性是必需的,如果不添加将不起作用)最后将链接标签附加到 head 标签。
function addNewCSS(css_text) {
css_text = encodeURIComponent(css_text);
const url = `data:text/css,${css_text}`;
const link = document.createElement("link");
link.rel = "stylesheet";
link.href = url;
document.head.appendChild(link);
}
const duration = 1;
const colour = ["#2196F3", "#E91E63"];
const css_data = `
@keyframes change{
0% {
background: ${colour[0]};
}
100% {
background: ${colour[1]};
}
}
body {
animation: change ${duration}s linear infinite alternate;
}
`;
addNewCSS(css_data);
<html>
<head></head>
<body>
<h1>Wait to see JS adding background color animation</h1>
</body>
</html>
我没有在所有浏览器上测试过,但在 chrome 中工作,并且因为它被添加到 head 标签的末尾,所以它从 head 中的其他标签中获得优先权,如果您打算频繁更改值,而不是添加新的标签,尝试编辑之前添加的标签的 href
。