Перевод времени в процентах анимации по ключевым кадрам

SDK OpenXML является правильным инструментом для этого задания, но вам нужно быть осторожным, чтобы использовать подход SAX (простой API для XML), а не подход DOM . Из связанной статьи wikipedia для SAX:

Если DOM работает с документом в целом, SAX-парсеры последовательно работают с каждой частью XML-документа

blockquote>

значительно уменьшает объем памяти, потребляемой при обработке больших файлов Excel.

Здесь есть хорошая статья - http://polymathprogrammer.com/2012/ 08/06 / how-to-right-use-openxmlwriter-to-write-large-excel-files /

Адаптировано из этой статьи, вот пример, который выводит строки 115k с 30 столбцами :

public static void LargeExport(string filename)
{
    using (SpreadsheetDocument document = SpreadsheetDocument.Create(filename, SpreadsheetDocumentType.Workbook))
    {
        //this list of attributes will be used when writing a start element
        List attributes;
        OpenXmlWriter writer;

        document.AddWorkbookPart();
        WorksheetPart workSheetPart = document.WorkbookPart.AddNewPart();

        writer = OpenXmlWriter.Create(workSheetPart);            
        writer.WriteStartElement(new Worksheet());
        writer.WriteStartElement(new SheetData());

        for (int rowNum = 1; rowNum <= 115000; ++rowNum)
        {
            //create a new list of attributes
            attributes = new List();
            // add the row index attribute to the list
            attributes.Add(new OpenXmlAttribute("r", null, rowNum.ToString()));

            //write the row start element with the row index attribute
            writer.WriteStartElement(new Row(), attributes);

            for (int columnNum = 1; columnNum <= 30; ++columnNum)
            {
                //reset the list of attributes
                attributes = new List();
                // add data type attribute - in this case inline string (you might want to look at the shared strings table)
                attributes.Add(new OpenXmlAttribute("t", null, "str"));
                //add the cell reference attribute
                attributes.Add(new OpenXmlAttribute("r", "", string.Format("{0}{1}", GetColumnName(columnNum), rowNum)));

                //write the cell start element with the type and reference attributes
                writer.WriteStartElement(new Cell(), attributes);
                //write the cell value
                writer.WriteElement(new CellValue(string.Format("This is Row {0}, Cell {1}", rowNum, columnNum)));

                // write the end cell element
                writer.WriteEndElement();
            }

            // write the end row element
            writer.WriteEndElement();
        }

        // write the end SheetData element
        writer.WriteEndElement();
        // write the end Worksheet element
        writer.WriteEndElement();
        writer.Close();

        writer = OpenXmlWriter.Create(document.WorkbookPart);
        writer.WriteStartElement(new Workbook());
        writer.WriteStartElement(new Sheets());

        writer.WriteElement(new Sheet()
        {
            Name = "Large Sheet",
            SheetId = 1,
            Id = document.WorkbookPart.GetIdOfPart(workSheetPart)
        });

        // End Sheets
        writer.WriteEndElement();
        // End Workbook
        writer.WriteEndElement();

        writer.Close();

        document.Close();
    }
}

//A simple helper to get the column name from the column index. This is not well tested!
private static string GetColumnName(int columnIndex)
{
    int dividend = columnIndex;
    string columnName = String.Empty;
    int modifier;

    while (dividend > 0)
    {
        modifier = (dividend - 1) % 26;
        columnName = Convert.ToChar(65 + modifier).ToString() + columnName;
        dividend = (int)((dividend - modifier) / 26);
    }

    return columnName;
}

3
задан 1.21 gigawatts 16 January 2019 в 13:05
поделиться

2 ответа

Если я правильно понимаю ваш вопрос, то этого можно достичь с помощью следующего набора ключевых кадров:

@keyframes fadein {
  0% {
    opacity: 1;

  }
  37.5% {
    /* 3 / 8 */
    opacity: 1; 
  }
  50% {
    /* (3 + 1) / 8 */
    opacity: 0.0; 
  }
  87.5% {
    /* (3 + 1 + 3) / 8 */
    opacity: 0.0; 
  }
  100% {
    opacity: 1; 
  }
}

Комментарии показывают, как рассчитываются проценты для различных ключевых кадров на основе ваших требований. Другое ключевое изменение, которое нужно сделать, - это удалить поведение alternate из правила анимации, чтобы обеспечить повторение цикла анимации в соответствии с требованиями:

/* remove alternate */
animation: fadein 8s linear 0s infinite;

Вот урезанная копия вашего кода для выделить анимированный круг:

function animationListener(event) {
  var type = event.type;
  var label = type;
  
  if (type=="animationiteration") {
    if (app.interval!=null) {
      clearInterval(app.interval);
    }
    app.time = 0;
    app.startTime = new Date().getTime();
    app.interval = setInterval(intervalFunction, 1000);
    intervalFunction();
    label = "iteration";
  }
  else if (type=="animationstart") {
    label = "start";
  }
  else if (type=="animationend") {
    label = "end";
  }
  
  app.stateLabel.innerHTML = label;
}

function intervalFunction() {
  var time = new Date().getTime();
  app.timeLabel.innerHTML = Math.round((time - app.startTime)/1000);
  app.keyframeLabel.innerHTML = window.getComputedStyle(app.ellipse).content;
}

function loadHandler() {
  app.ellipse = document.getElementById("Ellipse_49").parentNode;
  app.stateLabel = document.getElementById("stateLabel");
  app.timeLabel = document.getElementById("timeLabel");
  app.keyframeLabel = document.getElementById("keyframeLabel");
  
  app.ellipse.addEventListener("animationiteration", animationListener);
  app.ellipse.addEventListener("animationend", animationListener);
  app.ellipse.addEventListener("animationstart", animationListener);
}

document.addEventListener("DOMContentLoaded", loadHandler);
var app = {};
* {
  font-family: sans-serif;
  font-size: 11px;
  letter-spacing: .6px;
}

#Ellipse_49 {
  opacity: 1;
  fill: rgba(180, 180, 180, 1);
  stroke: rgb(112, 112, 112);
  stroke-width: 1px;
  stroke-linejoin: miter;
  stroke-linecap: butt;
  stroke-miterlimit: 4;
  shape-rendering: auto;
}

.Ellipse_49 {
  position: absolute;
  overflow: visible;
  width: 56px;
  height: 56px;
  left: 72px;
  top: 51px;
  
  /* remove alternate */
  animation: fadein 8s linear 0s infinite;
}

#container {
   top: 130px;
   left: 10px;
   position: relative;
   display: block;
   align-items: center;
   
}

label {
  width: 80px;
  display: inline-block;
}

@keyframes fadein {
  0% {
    opacity: 1;
    content: "show";
  }
  37.5% {
    /* 3 / 8 */
    opacity: 1;
    content: "fade out";
  }
  50% {
    /* (3 + 1) / 8 */
    opacity: 0.0;
    content: "wait";
  }
  87.5% {
    /* (3 + 1 + 3) / 8 */
    opacity: 0.0;
    content: "fade in";
  }
  100% {
    opacity: 1;
    content: "show";
  }
}
<svg class="Ellipse_49">
		<ellipse id="Ellipse_49" rx="28" ry="28" cx="28" cy="28">
		</ellipse>
</svg>


<div id="container">
  <label>time: </label>
  <span id="timeLabel"></span>
  <br>
  <label>state: </label>
  <span id="stateLabel"></span>
  <br>
  <label>key frame: </label>
  <span id="keyframeLabel"></span>
</div>

0
ответ дан 1.21 gigawatts 16 January 2019 в 13:05
поделиться

Добавление ответа @ DacreDenny здесь, чтобы я мог изменить его и добавить примечания.

function animationListener(event) {
  var type = event.type;
  var label = type;
  
  if (type=="animationiteration") {
    if (app.interval!=null) {
      clearInterval(app.interval);
    }
    app.time = 0;
    app.startTime = new Date().getTime();
    app.interval = setInterval(intervalFunction, 15);
    intervalFunction();
    label = "iteration";
  }
  else if (type=="animationstart") {
    label = "start";
  }
  else if (type=="animationend") {
    label = "end";
  }
  
  app.stateLabel.innerHTML = label;
}

function intervalFunction() {
  var currentTime = new Date().getTime();
  var time = (currentTime - app.startTime)/1000;
  var duration = parseFloat(window.getComputedStyle(app.ellipse).animationDuration);
  var maxValue = 100;
  var position = ((time * maxValue)/duration);
  
  app.timeLabel.innerHTML = Math.round(time);
  app.keyframeLabel.innerHTML = window.getComputedStyle(app.ellipse).content;
  app.timelineRange.value = position;
  app.positionLabel.innerHTML = Math.round(position) + "%";
}

function loadHandler() {
  app.ellipse = document.getElementById("Ellipse_49").parentNode;
  app.stateLabel = document.getElementById("stateLabel");
  app.timeLabel = document.getElementById("timeLabel");
  app.keyframeLabel = document.getElementById("keyframeLabel");
  app.timelineRange = document.getElementById("timelineRange");
  app.positionLabel = document.getElementById("positionLabel");
  
  app.ellipse.addEventListener("animationiteration", animationListener);
  app.ellipse.addEventListener("animationend", animationListener);
  app.ellipse.addEventListener("animationstart", animationListener);
}

document.addEventListener("DOMContentLoaded", loadHandler);
var app = {};
* {
  font-family: sans-serif;
  font-size: 11px;
  letter-spacing: .6px;
}

@keyframes fadein {
  0% {
    opacity: 1;
    content: "show";
  }
  37.5% {
    /* 3 / 8 */
    opacity: 1;
    content: "fade out";
  }
  50% {
    /* (3 + 1) / 8 */
    opacity: 0.0;
    content: "wait";
  }
  87.5% {
    /* (3 + 1 + 3) / 8 */
    opacity: 0.0;
    content: "fade in";
  }
  100% {
    opacity: 1;
    content: "show";
  }
}

#Ellipse_49 {
  opacity: 1;
  fill: rgba(180, 180, 180, 1);
  stroke: rgb(112, 112, 112);
  stroke-width: 1px;
  stroke-linejoin: miter;
  stroke-linecap: butt;
  stroke-miterlimit: 4;
  shape-rendering: auto;
}

.Ellipse_49 {
  position: absolute;
  overflow: visible;
  width: 50px;
  height: 50px;
  left: 20px;
  top: 50px;
  
  /* remove alternate */
  animation: fadein 4s linear 0s infinite;
}

#container {
   top: 130px;
   left: 10px;
   position: relative;
   display: block;
}

label {
  width: 80px;
  display: inline-block;
}

input[type=range] {
  outline: 0px solid red;
  display: block;
  width: 90%;
  margin-left: 0;
}
input[type=range]::-webkit-slider-runnable-track {
  width: 100%;
  height: 8.4px;
  cursor: pointer;
  box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
  background: rgb(255,255,255);
}
<svg class="Ellipse_49">
		<ellipse id="Ellipse_49" rx="28" ry="28" cx="28" cy="28">
		</ellipse>
</svg>


<div id="container">
  <input id="timelineRange" type="range" value="0" min="0" max="100">
  <br>
  
  <label>time: </label>
  <span id="timeLabel"></span>
  <br>
  <label>position: </label>
  <span id="positionLabel"></span>
  <br>
  <label>state: </label>
  <span id="stateLabel"></span>
  <br>
  <label>key frame: </label>
  <span id="keyframeLabel"></span>
  <br>
  <br>
</div>

0
ответ дан 1.21 gigawatts 16 January 2019 в 13:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: