123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262 |
- # JavaScript template for HTMLWriter
- JS_INCLUDE = """
- <link rel="stylesheet"
- href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
- <script language="javascript">
- function isInternetExplorer() {
- ua = navigator.userAgent;
- /* MSIE used to detect old browsers and Trident used to newer ones*/
- return ua.indexOf("MSIE ") > -1 || ua.indexOf("Trident/") > -1;
- }
- /* Define the Animation class */
- function Animation(frames, img_id, slider_id, interval, loop_select_id){
- this.img_id = img_id;
- this.slider_id = slider_id;
- this.loop_select_id = loop_select_id;
- this.interval = interval;
- this.current_frame = 0;
- this.direction = 0;
- this.timer = null;
- this.frames = new Array(frames.length);
- for (var i=0; i<frames.length; i++)
- {
- this.frames[i] = new Image();
- this.frames[i].src = frames[i];
- }
- var slider = document.getElementById(this.slider_id);
- slider.max = this.frames.length - 1;
- if (isInternetExplorer()) {
- // switch from oninput to onchange because IE <= 11 does not conform
- // with W3C specification. It ignores oninput and onchange behaves
- // like oninput. In contrast, Microsoft Edge behaves correctly.
- slider.setAttribute('onchange', slider.getAttribute('oninput'));
- slider.setAttribute('oninput', null);
- }
- this.set_frame(this.current_frame);
- }
- Animation.prototype.get_loop_state = function(){
- var button_group = document[this.loop_select_id].state;
- for (var i = 0; i < button_group.length; i++) {
- var button = button_group[i];
- if (button.checked) {
- return button.value;
- }
- }
- return undefined;
- }
- Animation.prototype.set_frame = function(frame){
- this.current_frame = frame;
- document.getElementById(this.img_id).src =
- this.frames[this.current_frame].src;
- document.getElementById(this.slider_id).value = this.current_frame;
- }
- Animation.prototype.next_frame = function()
- {
- this.set_frame(Math.min(this.frames.length - 1, this.current_frame + 1));
- }
- Animation.prototype.previous_frame = function()
- {
- this.set_frame(Math.max(0, this.current_frame - 1));
- }
- Animation.prototype.first_frame = function()
- {
- this.set_frame(0);
- }
- Animation.prototype.last_frame = function()
- {
- this.set_frame(this.frames.length - 1);
- }
- Animation.prototype.slower = function()
- {
- this.interval /= 0.7;
- if(this.direction > 0){this.play_animation();}
- else if(this.direction < 0){this.reverse_animation();}
- }
- Animation.prototype.faster = function()
- {
- this.interval *= 0.7;
- if(this.direction > 0){this.play_animation();}
- else if(this.direction < 0){this.reverse_animation();}
- }
- Animation.prototype.anim_step_forward = function()
- {
- this.current_frame += 1;
- if(this.current_frame < this.frames.length){
- this.set_frame(this.current_frame);
- }else{
- var loop_state = this.get_loop_state();
- if(loop_state == "loop"){
- this.first_frame();
- }else if(loop_state == "reflect"){
- this.last_frame();
- this.reverse_animation();
- }else{
- this.pause_animation();
- this.last_frame();
- }
- }
- }
- Animation.prototype.anim_step_reverse = function()
- {
- this.current_frame -= 1;
- if(this.current_frame >= 0){
- this.set_frame(this.current_frame);
- }else{
- var loop_state = this.get_loop_state();
- if(loop_state == "loop"){
- this.last_frame();
- }else if(loop_state == "reflect"){
- this.first_frame();
- this.play_animation();
- }else{
- this.pause_animation();
- this.first_frame();
- }
- }
- }
- Animation.prototype.pause_animation = function()
- {
- this.direction = 0;
- if (this.timer){
- clearInterval(this.timer);
- this.timer = null;
- }
- }
- Animation.prototype.play_animation = function()
- {
- this.pause_animation();
- this.direction = 1;
- var t = this;
- if (!this.timer) this.timer = setInterval(function() {
- t.anim_step_forward();
- }, this.interval);
- }
- Animation.prototype.reverse_animation = function()
- {
- this.pause_animation();
- this.direction = -1;
- var t = this;
- if (!this.timer) this.timer = setInterval(function() {
- t.anim_step_reverse();
- }, this.interval);
- }
- </script>
- """
- # Style definitions for the HTML template
- STYLE_INCLUDE = """
- <style>
- .animation {
- display: inline-block;
- text-align: center;
- }
- input[type=range].anim-slider {
- width: 374px;
- margin-left: auto;
- margin-right: auto;
- }
- .anim-buttons {
- margin: 8px 0px;
- }
- .anim-buttons button {
- padding: 0;
- width: 36px;
- }
- .anim-state label {
- margin-right: 8px;
- }
- .anim-state input {
- margin: 0;
- vertical-align: middle;
- }
- </style>
- """
- # HTML template for HTMLWriter
- DISPLAY_TEMPLATE = """
- <div class="animation">
- <img id="_anim_img{id}">
- <div class="anim-controls">
- <input id="_anim_slider{id}" type="range" class="anim-slider"
- name="points" min="0" max="1" step="1" value="0"
- oninput="anim{id}.set_frame(parseInt(this.value));">
- <div class="anim-buttons">
- <button title="Decrease speed" aria-label="Decrease speed" onclick="anim{id}.slower()">
- <i class="fa fa-minus"></i></button>
- <button title="First frame" aria-label="First frame" onclick="anim{id}.first_frame()">
- <i class="fa fa-fast-backward"></i></button>
- <button title="Previous frame" aria-label="Previous frame" onclick="anim{id}.previous_frame()">
- <i class="fa fa-step-backward"></i></button>
- <button title="Play backwards" aria-label="Play backwards" onclick="anim{id}.reverse_animation()">
- <i class="fa fa-play fa-flip-horizontal"></i></button>
- <button title="Pause" aria-label="Pause" onclick="anim{id}.pause_animation()">
- <i class="fa fa-pause"></i></button>
- <button title="Play" aria-label="Play" onclick="anim{id}.play_animation()">
- <i class="fa fa-play"></i></button>
- <button title="Next frame" aria-label="Next frame" onclick="anim{id}.next_frame()">
- <i class="fa fa-step-forward"></i></button>
- <button title="Last frame" aria-label="Last frame" onclick="anim{id}.last_frame()">
- <i class="fa fa-fast-forward"></i></button>
- <button title="Increase speed" aria-label="Increase speed" onclick="anim{id}.faster()">
- <i class="fa fa-plus"></i></button>
- </div>
- <form title="Repetition mode" aria-label="Repetition mode" action="#n" name="_anim_loop_select{id}"
- class="anim-state">
- <input type="radio" name="state" value="once" id="_anim_radio1_{id}"
- {once_checked}>
- <label for="_anim_radio1_{id}">Once</label>
- <input type="radio" name="state" value="loop" id="_anim_radio2_{id}"
- {loop_checked}>
- <label for="_anim_radio2_{id}">Loop</label>
- <input type="radio" name="state" value="reflect" id="_anim_radio3_{id}"
- {reflect_checked}>
- <label for="_anim_radio3_{id}">Reflect</label>
- </form>
- </div>
- </div>
- <script language="javascript">
- /* Instantiate the Animation class. */
- /* The IDs given should match those used in the template above. */
- (function() {{
- var img_id = "_anim_img{id}";
- var slider_id = "_anim_slider{id}";
- var loop_select_id = "_anim_loop_select{id}";
- var frames = new Array({Nframes});
- {fill_frames}
- /* set a timeout to make sure all the above elements are created before
- the object is initialized. */
- setTimeout(function() {{
- anim{id} = new Animation(frames, img_id, slider_id, {interval},
- loop_select_id);
- }}, 0);
- }})()
- </script>
- """
- INCLUDED_FRAMES = """
- for (var i=0; i<{Nframes}; i++){{
- frames[i] = "{frame_dir}/frame" + ("0000000" + i).slice(-7) +
- ".{frame_format}";
- }}
- """
|