NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

animations.py (6107B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\carbonui\graphs\animations.py
      2 import random
      3 import trinity
      4 import uthread2
      5 from carbonui.graphs import axis
      6 from carbonui.uicore import uicore
      7 
      8 class AnimationType(object):
      9     FADE = 1
     10     GROW = 2
     11 
     12 
     13 class AnimationDynamics(object):
     14     SIMULTANEOUS = 0
     15     ALONG_AXIS = 1
     16     OPPOSITE_AXIS = 2
     17     RANDOM = 3
     18 
     19 
     20 def CreateAnimation(uiObject, categoryAxis, valueAxis, orientation, animationType, animationDynamics, duration, vertexPerDataPoint):
     21     if animationType == AnimationType.FADE:
     22         return CreateOpacityAnimation(uiObject, categoryAxis, orientation, animationDynamics, duration, vertexPerDataPoint)
     23     if animationType == AnimationType.GROW:
     24         return CreateVertexAnimation(uiObject, categoryAxis, valueAxis, orientation, animationDynamics, duration, vertexPerDataPoint)
     25     raise ValueError('unsupported animation type')
     26 
     27 
     28 def CreateVertexAnimation(uiObject, categoryAxis, valueAxis, orientation, animationDynamics, duration, vertexPerDataPoint):
     29     startVertex = max(0, int(categoryAxis.GetVisibleRange()[0] - 1)) * vertexPerDataPoint
     30     endVertex = int(min(categoryAxis.GetVisibleRange()[1] + 1, len(categoryAxis.GetDataPoints()))) * vertexPerDataPoint
     31     if startVertex >= endVertex:
     32         return None
     33     axisZero = valueAxis.GetViewportRange()[0]
     34     source = (axisZero,) * (endVertex - startVertex)
     35     index = 0 if orientation == axis.AxisOrientation.HORIZONTAL else 1
     36     dest = [ uiObject.renderObject.vertices[i].position[index] for i in xrange(startVertex, endVertex) ]
     37     offsets = GetAnimationOffsets(animationDynamics, endVertex - startVertex, vertexPerDataPoint=vertexPerDataPoint)
     38     return VertexAnimation('position', duration, offsets, source, dest, uiObject.renderObject, startVertex, index)
     39 
     40 
     41 def CreateOpacityAnimation(uiObject, categoryAxis, orientation, animationDynamics, duration, vertexPerDataPoint):
     42     if animationDynamics == AnimationDynamics.SIMULTANEOUS:
     43         uicore.animations.MorphScalar(uiObject, 'opacity', startVal=0.0, endVal=1.0, duration=duration)
     44         return None
     45     startVertex = max(0, int(categoryAxis.GetVisibleRange()[0] - 1)) * vertexPerDataPoint
     46     endVertex = int(min(categoryAxis.GetVisibleRange()[1] + 1, len(categoryAxis.GetDataPoints()))) * vertexPerDataPoint
     47     if startVertex >= endVertex:
     48         return None
     49     source = (0,) * (endVertex - startVertex)
     50     index = 0 if orientation == axis.AxisOrientation.HORIZONTAL else 1
     51     dest = (1,) * (endVertex - startVertex)
     52     offsets = GetAnimationOffsets(animationDynamics, endVertex - startVertex, vertexPerDataPoint=vertexPerDataPoint)
     53     return VertexAnimation('color', duration, offsets, source, dest, uiObject.renderObject, startVertex, index)
     54 
     55 
     56 class VertexAnimation(object):
     57 
     58     def __init__(self, attribute, duration, timeOffsets, source, destination, polygon, vertexOffset, vertexAttribute):
     59         self._attibute = attribute
     60         self._source = source
     61         self._timeOffsets = timeOffsets
     62         self._destination = destination
     63         self._polygon = polygon
     64         self._offset = vertexOffset
     65         self._startTime = trinity.device.animationTime
     66         self._endTime = self._startTime + max(self._timeOffsets) + duration
     67         self._duration = duration
     68         self._vertexAttribute = vertexAttribute
     69         self._cancelled = False
     70         uthread2.StartTasklet(self._Thread)
     71 
     72     def Cancel(self, applyLastFrame = True):
     73         self._cancelled = True
     74         if applyLastFrame:
     75             self._Apply((self._endTime - self._startTime) / self._duration)
     76 
     77     def _Apply(self, time):
     78         if self._attibute == 'position':
     79             self._ApplyPositions(time)
     80         else:
     81             self._ApplyColors(time)
     82 
     83     def _ApplyPositions(self, time):
     84         vertices = self._polygon.vertices
     85         for i, (offset, source, dest) in enumerate(zip(self._timeOffsets, self._source, self._destination)):
     86             t = time - offset
     87             t = min(max(t, 0), 1)
     88             t = t ** 0.3
     89             v = source * (1 - t) + dest * t
     90             vtx = vertices[i + self._offset]
     91             if self._vertexAttribute == 0:
     92                 vtx.position = (v, vtx.position[1])
     93             else:
     94                 vtx.position = (vtx.position[0], v)
     95 
     96         self._polygon.SetDirty()
     97 
     98     def _ApplyColors(self, time):
     99         vertices = self._polygon.vertices
    100         for i, (offset, source, dest) in enumerate(zip(self._timeOffsets, self._source, self._destination)):
    101             t = time - offset
    102             t = min(max(t, 0), 1)
    103             t = t ** 0.3
    104             v = source * (1 - t) + dest * t
    105             vtx = vertices[i + self._offset]
    106             vtx.color = (vtx.color[0],
    107              vtx.color[1],
    108              vtx.color[2],
    109              v)
    110 
    111         self._polygon.SetDirty()
    112 
    113     def _Thread(self):
    114         while not self._cancelled:
    115             now = trinity.device.animationTime
    116             self._Apply((now - self._startTime) / self._duration)
    117             if now > self._endTime:
    118                 break
    119             uthread2.Yield()
    120 
    121 
    122 def GetAnimationOffsets(animationDynamics, vertexCount, vertexPerDataPoint = 1):
    123     if animationDynamics == AnimationDynamics.SIMULTANEOUS:
    124         offsets = (0,) * vertexCount
    125     elif animationDynamics == AnimationDynamics.ALONG_AXIS:
    126         relRange = vertexPerDataPoint / float(vertexCount)
    127         offsets = [ x / vertexPerDataPoint * relRange for x in xrange(vertexCount) ]
    128     elif animationDynamics == AnimationDynamics.OPPOSITE_AXIS:
    129         relRange = vertexPerDataPoint / float(vertexCount)
    130         offsets = [ 1 - x / vertexPerDataPoint * relRange for x in xrange(vertexCount) ]
    131     elif animationDynamics == AnimationDynamics.RANDOM:
    132         if vertexPerDataPoint == 1:
    133             offsets = [ random.random() for _ in xrange(vertexCount) ]
    134         else:
    135             offsets = []
    136             for each in xrange(vertexCount):
    137                 offsets.extend((random.random(),) * vertexPerDataPoint)
    138 
    139     else:
    140         raise ValueError('unsupported animation dynamics')
    141     return offsets