• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import scene3d from '@ohos.graphics.scene'
17import router from '@ohos.router';
18import animator, { AnimatorResult } from '@ohos.animator';
19import Logger from '../util/Logger';
20
21@Entry
22@Component
23struct sceneAnimation {
24  scene: scene3d.Scene | null = null;
25  @State sceneOpt: SceneOptions | null = null;
26  cam: scene3d.Camera | null = null;
27  @State progressValue: number = 0;
28
29  @State animationEnabled: Boolean = false;
30  @State animationDuration: number = 0;
31  @State animationIsRunning: Boolean = false;
32  @State animationCallbackInvoked: string = 'no invoked callback'
33
34  backAnimator: AnimatorResult | undefined = undefined;
35
36  onPageShow(): void {
37    this.init();
38  }
39
40  onPageHide(): void {
41    if (this.scene) {
42      this.scene.destroy();
43    }
44
45    this.cam = null;
46    this.scene = null;
47  }
48
49  init(): void {
50    this.backAnimator = animator.create({
51      duration: 2000, // duration
52      easing: "ease",
53      delay: 0,
54      fill: "none",
55      direction: "normal",
56      iterations: -1, // endless loop
57      begin: 100, // begin
58      end: 200 // end
59    })
60    this.backAnimator.onframe = value => {
61      if (this.scene?.animations[0]) {
62        this.animationEnabled = this.scene.animations[0].enabled;
63        this.animationDuration = this.scene.animations[0].duration;
64        this.animationIsRunning = this.scene.animations[0].running;
65        this.progressValue = this.scene.animations[0].progress;
66      }
67    }
68    if (this.scene === null) {
69      scene3d.Scene.load($rawfile("gltf/BrainStem/glTF/BrainStem.glb"))
70        .then(async (result: scene3d.Scene) => {
71          this.scene = result;
72          this.sceneOpt = { scene: this.scene, modelType: ModelType.SURFACE } as SceneOptions;
73          let rf = this.scene.getResourceFactory();
74          this.cam = await rf.createCamera({ "name": "Camera1" });
75          this.cam.enabled = true;
76          this.cam.position.z = 5;
77
78          let env = await rf.createEnvironment({ "name": "Env" });
79          this.scene.environment.backgroundType = scene3d.EnvironmentBackgroundType.BACKGROUND_IMAGE;
80          this.scene.environment.environmentImage = await rf.createImage({ name: "envImg1", uri: $rawfile("gltf/DamagedHelmet/glTF/Default_normal.jpg") });
81        })
82        .catch((reason: string) => {
83          Logger.error("init error", reason);
84        });
85    }
86  }
87
88  build() {
89    Row() {
90      Column() {
91        Column() {
92          if (this.sceneOpt) {
93            Component3D(this.sceneOpt)
94              .renderWidth('60%')
95              .renderHeight('60%')
96              .onAppear(()=>{
97                if (!this.scene || !this.scene.animations[0]) {
98                  return;
99                }
100                let count = this.scene.animations.length;
101
102                let anim: scene3d.Animation = this.scene.animations[0];
103                anim.onStarted(()=>{
104                  this.animationCallbackInvoked = 'animation on start'
105                });
106                anim.onFinished(() => {
107                  this.animationCallbackInvoked = 'animation on finish'
108                });
109                this.backAnimator?.play();
110              })
111          }
112          else {
113            Text("loading 1...");
114          }
115        }
116        .height('30%')
117
118        Row() {
119          Text ("progress: " + (this.progressValue * 100).toFixed(2) + '%')
120        }
121        Text("Duration: " + this.animationDuration.toFixed(2) + "S");
122        Text("Running: " + this.animationIsRunning);
123        Text("enabled: " + this.animationEnabled);
124
125        Text("animation invoked callback:" + this.animationCallbackInvoked);
126
127        Button('enable animation').onClick(() => {
128          if (!this.scene || !this.scene.animations[0]) {
129            return;
130          }
131
132          this.scene.animations[0].enabled = !this.scene.animations[0].enabled;
133        }).id('enable_animation');
134
135        Button('start').onClick(async () => {
136          if (!this.scene || !this.scene.animations[0]) {
137            return;
138          }
139          let anim: scene3d.Animation = this.scene.animations[0];
140          anim.start();
141        }).id('start_animation');
142
143        Button('pause').onClick(async () => {
144          if (!this.scene || !this.scene.animations[0]) {
145            return;
146          }
147          let anim: scene3d.Animation = this.scene.animations[0];
148          anim.pause();
149        }).id('pause_animation');
150
151        Button('stop').onClick(async () => {
152          if (!this.scene || !this.scene.animations[0]) {
153            return;
154          }
155          let anim: scene3d.Animation = this.scene.animations[0];
156          anim.stop();
157        }).id('stop_animation');
158
159        Button('finish').onClick(async () => {
160          if (!this.scene || !this.scene.animations[0]) {
161            return;
162          }
163          let anim: scene3d.Animation = this.scene.animations[0];
164          anim.finish();
165        }).id('finish_animation');
166
167        Button('restart').onClick(async () => {
168          if (!this.scene || !this.scene.animations[0]) {
169            return;
170          }
171          let anim: scene3d.Animation = this.scene.animations[0];
172          anim.restart();
173        }).id('restart_animation');
174
175        Button('seek to 30% progress').onClick(async () => {
176          if (!this.scene || !this.scene.animations[0]) {
177            return;
178          }
179          let anim: scene3d.Animation = this.scene.animations[0];
180          // seek to 30%
181          anim.seek(0.3);
182        }).id('seek_animation');
183
184        Button('back').onClick(() => {
185          router.back()
186        }).id('back_animation')
187      }
188      .width('100%')
189    }
190    .height('100%')
191  }
192}