Examples to explain javascript frame animation
The editor below will bring you a javascript frame animation (explanation with examples). The editor thinks it’s pretty good, so I’ll share it with you now and give it as a reference. Let’s follow the editor and take a look.
The previous words
frame animation is to decompose animation actions in "continuous key frames", that is, It is an animation that draws different content frame by frame on each frame of the timeline and plays it continuously. Because it is drawn frame by frame, frame animation has great flexibility and can express almost any content you want to express. This article will introduce javascript frame animation in detail
Overview
[Classification]
There are three common ways of frame animation, Including gif, CSS3 animation and javascript
git and CSS3 animation cannot flexibly control the pause and playback of animation, and cannot flexibly expand frame animation. In addition, gif images cannot capture the event of animation completion. Therefore, generally, use javascript to implement frame animation
[Principle]
There are two ways to implement frame animation using js
1. If If you have multiple frame animation pictures, you can use an image tag to carry the picture, and regularly change the src attribute of the image (not recommended)
2. Draw all the animation key frames in one picture, and put the picture As the background-image of the element, change the background-position attribute of the element regularly (recommended)
Because the first method requires multiple HTTP requests, it is generally recommended to use the second method
[Example]
The following is an example of using frame animation
<p id="rabbit" ></p> <button id="btn">暂停运动</button> <script> var url = 'rabbit-big.png'; var positions = ['0,-854','-174 -852','-349 -852','-524 -852','-698 -852','-873 -848']; var ele = document.getElementById('rabbit'); var oTimer = null; btn.onclick = function(){ if(btn.innerHTML == '开始运动'){ frameAnimation(ele,positions,url); btn.innerHTML = '暂停运动'; }else{ clearTimeout(oTimer); btn.innerHTML = '开始运动'; } } frameAnimation(ele,positions,url); function frameAnimation(ele,positions,url){ ele.style.backgroundImage = 'url(' + url + ')'; ele.style.backgroundRepeat = 'no-repeat'; var index = 0; function run(){ var pos = positions[index].split(' '); ele.style.backgroundPosition = pos[0] + 'px ' + pos[1] + 'px'; index++; if(index >= positions.length){ index = 0; } oTimer = setTimeout(run,80); } run(); } </script>
General frame animation
Let’s design a general frame animation library
[Requirement Analysis]
1. Support image preloading
2. Support two kinds of animation playback method, and customize each frame of animation
3. Support a single group of animations to control the number of loops (can support unlimited times)
4. Support the completion of one group of animations and proceed to the next group of animations
5. Support waiting time after each animation is completed
6. Support animation pause and continue playback
7. Support callback function execution after animation is completed
[Programming interface]
1. loadImage(imglist)//Preload the image
2. changePosition(ele, positions, imageUrl)//Realize animation by changing the background-position of the element
3. changeSrc(ele,imglist)//By changing the src of the image element
4. enterFrame(callback)//The function executed for each frame of animation is equivalent to the user being able to customize each Frame animation callback
5, repeat(times)//The number of times the animation is repeated, when times is empty, it means unlimited times
6, repeatForever()//Repeat the last animation infinitely, Equivalent to repeat()
7, wait(time)//The waiting time after each animation execution is completed
8, then(callback)//The callback function after the animation execution is completed
9. start(interval)//The animation starts executing. interval represents the interval between animation execution.
10. pause()//The animation pauses.
11. restart()/ /The animation is re-executed from the previous pause point
12. dispose()//Release resources
[Calling method]
Supports chain calls, using verbs Description interface
[Code design]
1. Treat a series of operations such as image preloading-> animation execution-> animation end as a task chain. The task chain includes two tasks: synchronous execution and asynchronous scheduled execution
2. Record the index of the current task chain
3. After each task is executed, the next task is executed by calling the next method. , and update the task chain index value at the same time
[Interface definition]
'use strict'; /* 帧动画库类 * @constructor */ function FrameAnimation(){} /* 添加一个同步任务,去预加载图片 * @param imglist 图片数组 */ FrameAnimation.prototype.loadImage = function(imglist){} /* 添加一个异步定时任务,通过定时改变图片背景位置,实现帧动画 * @param ele dom对象 * @param positions 背景位置数组 * @param imageUrl 图片URL地址 */ FrameAnimation.prototype.changePosition = function(ele,positions,imageUrl){} /* 添加一个异步定时任务,通过定时改变image标签的src属性,实现帧动画 * @param ele dom对象 * @param imglist 图片数组 */ FrameAnimation.prototype.changeSrc = function(ele,imglist){} /* 添加一个异步定时任务,自定义动画每帧执行的任务函数 * @param tastFn 自定义每帧执行的任务函数 */ FrameAnimation.prototype.enterFrame = function(taskFn){} /* 添加一个同步任务,在上一个任务完成后执行回调函数 * @param callback 回调函数 */ FrameAnimation.prototype.then = function(callback){} /* 开始执行任务,异步定时任务执行的间隔 * @param interval */ FrameAnimation.prototype.start = function(interval){} /* 添加一个同步任务,回退到上一个任务,实现重复上一个任务的效果,可以定义重复的次数 * @param times 重复次数 */ FrameAnimation.prototype.repeat = function(times){} /* 添加一个同步任务,相当于repeat(),无限循环上一次任务 * */ FrameAnimation.prototype.repeatForever = function(){} /* 设置当前任务执行结束后到下一个任务开始前的等待时间 * @param time 等待时长 */ FrameAnimation.prototype.wait = function(time){} /* 暂停当前异步定时任务 * */ FrameAnimation.prototype.pause = function(){} /* 重新执行上一次暂停的异步定时任务 * */ FrameAnimation.prototype.restart = function(){} /* 释放资源 * */ FrameAnimation.prototype.dispose = function(){}
Picture preset Loading
Image preloading is a relatively independent function, which can be encapsulated as a module imageloader.js
'use strict'; /** * 预加载图片函数 * @param images 加载图片的数组或者对象 * @param callback 全部图片加载完毕后调用的回调函数 * @param timeout 加载超时的时长 */ function loadImage(images,callback,timeout){ //加载完成图片的计数器 var count = 0; //全部图片加载成功的标志位 var success = true; //超时timer的id var timeoutId = 0; //是否加载超时的标志位 var isTimeout = false; //对图片数组(或对象)进行遍历 for(var key in images){ //过滤prototype上的属性 if(!images.hasOwnProperty(key)){ continue; } //获得每个图片元素 //期望格式是object:{src:xxx} var item = images[key]; if(typeof item === 'string'){ item = images[key] = { src:item }; } //如果格式不满足期望,则丢弃此条数据,进行下一次遍历 if(!item || !item.src){ continue; } //计数+1 count++; //设置图片元素的id item.id = '__img__' + key + getId(); //设置图片元素的img,它是一个Image对象 item.img = window[item.id] = new Image(); doLoad(item); } //遍历完成如果计数为0,则直接调用callback if(!count){ callback(success); }else if(timeout){ timeoutId = setTimeout(onTimeout,timeout); } /** * 真正进行图片加载的函数 * @param item 图片元素对象 */ function doLoad(item){ item.status = 'loading'; var img = item.img; //定义图片加载成功的回调函数 img.onload = function(){ success = success && true; item.status = 'loaded'; done(); } //定义图片加载失败的回调函数 img.onerror = function(){ success = false; item.status = 'error'; done(); } //发起一个http(s)请求 img.src = item.src; /** * 每张图片加载完成的回调函数 */ function done(){ img.onload = img.onerror = null; try{ delete window[item.id]; }catch(e){ } //每张图片加载完成,计数器减1,当所有图片加载完成,且没有超时的情况,清除超时计时器,且执行回调函数 if(!--count && !isTimeout){ clearTimeout(timeoutId); callback(success); } } } /** * 超时函数 */ function onTimeout(){ isTimeout = true; callback(false); } } var __id = 0; function getId(){ return ++__id; } module.exports = loadImage;
Timeline
In animation processing, it is implemented by using setTimeout() iteratively, but this interval is not accurate. Next, to implement a timeline class timeline.js
'use strict'; var DEFAULT_INTERVAL = 1000/60; //初始化状态 var STATE_INITIAL = 0; //开始状态 var STATE_START = 1; //停止状态 var STATE_STOP = 2; var requestAnimationFrame = (function(){ return window.requestAnimationFrame || window.webkitRequestAnimationFrame|| window.mozRequestAnimationFrame || window.oRequestAnimationFrame || function(callback){ return window.setTimeout(callback,(callback.interval || DEFAULT_INTERVAL)); } })(); var cancelAnimationFrame = (function(){ return window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.oCancelAnimationFrame || function(id){ return window.clearTimeout(id); } })(); /** * 时间轴类 * @constructor */ function Timeline(){ this.animationHandler = 0; this.state = STATE_INITIAL; } /** * 时间轴上每一次回调执行的函数 * @param time 从动画开始到当前执行的时间 */ Timeline.prototype.onenterframe = function(time){ } /** * 动画开始 * @param interval 每一次回调的间隔时间 */ Timeline.prototype.start = function(interval){ if(this.state === STATE_START){ return; } this.state = STATE_START; this.interval = interval || DEFAULT_INTERVAL; startTimeline(this,+new Date()); } /** * 动画停止 */ Timeline.prototype.stop = function(){ if(this.state !== STATE_START){ return; } this.state = STATE_STOP; //如果动画开始过,则记录动画从开始到现在所经历的时间 if(this.startTime){ this.dur = +new Date() - this.startTime; } cancelAnimationFrame(this.animationHandler); } /** * 重新开始动画 */ Timeline.prototype.restart = function(){ if(this.state === STATE_START){ return; } if(!this.dur || !this.interval){ return; } this.state = STATE_START; //无缝连接动画 startTimeline(this,+new Date()-this.dur); } /** * 时间轴动画启动函数 * @param timeline 时间轴的实例 * @param startTime 动画开始时间戳 */ function startTimeline(timeline,startTime){ //记录上一次回调的时间戳 var lastTick = +new Date(); timeline.startTime = startTime; nextTick.interval = timeline.interval; nextTick(); /** * 每一帧执行的函数 */ function nextTick(){ var now = +new Date(); timeline.animationHandler = requestAnimationFrame(nextTick); //如果当前时间与上一次回调的时间戳大于设置的时间间隔,表示这一次可以执行回调函数 if(now - lastTick >= timeline.interval){ timeline.onenterframe(now - startTime); lastTick = now; } } } module.exports = Timeline;
Animation class implementation
The following is The complete code of animation class animation.js implementation
'use strict'; var loadImage = require('./imageloader'); var Timeline = require('./timeline'); //初始化状态 var STATE_INITIAL = 0; //开始状态 var STATE_START = 1; //停止状态 var STATE_STOP = 2; //同步任务 var TASK_SYNC = 0; //异步任务 var TASK_ASYNC = 1; /** * 简单的函数封装,执行callback * @param callback 执行函数 */ function next(callback){ callback && callback(); } /* 帧动画库类 * @constructor */ function FrameAnimation(){ this.taskQueue = []; this.index = 0; this.timeline = new Timeline(); this.state = STATE_INITIAL; } /* 添加一个同步任务,去预加载图片 * @param imglist 图片数组 */ FrameAnimation.prototype.loadImage = function(imglist){ var taskFn = function(next){ loadImage(imglist.slice(),next); }; var type = TASK_SYNC; return this._add(taskFn,type); } /* 添加一个异步定时任务,通过定时改变图片背景位置,实现帧动画 * @param ele dom对象 * @param positions 背景位置数组 * @param imageUrl 图片URL地址 */ FrameAnimation.prototype.changePosition = function(ele,positions,imageUrl){ var len = positions.length; var taskFn; var type; if(len){ var me = this; taskFn = function(next,time){ if(imageUrl){ ele.style.backgroundImage = 'url(' + imageUrl + ')'; } //获得当前背景图片位置索引 var index = Math.min(time/me.interval|0,len); var position = positions[index-1].split(' '); //改变dom对象的背景图片位置 ele.style.backgroundPosition = position[0] + 'px ' + position[1] + 'px'; if(index === len){ next(); } } type = TASK_ASYNC; }else{ taskFn = next; type = TASK_SYNC; } return this._add(taskFn,type); } /* 添加一个异步定时任务,通过定时改变image标签的src属性,实现帧动画 * @param ele dom对象 * @param imglist 图片数组 */ FrameAnimation.prototype.changeSrc = function(ele,imglist){ var len = imglist.length; var taskFn; var type; if(len){ var me = this; taskFn = function(next,time){ //获得当前背景图片位置索引 var index = Math.min(time/me.interval|0,len); //改变image对象的背景图片位置 ele.src = imglist[index-1]; if(index === len){ next(); } } type = TASK_ASYNC; }else{ taskFn = next; type = TASK_SYNC; } return this._add(taskFn,type); } /* 添加一个异步定时任务,自定义动画每帧执行的任务函数 * @param tastFn 自定义每帧执行的任务函数 */ FrameAnimation.prototype.enterFrame = function(taskFn){ return this._add(taskFn,TASK_ASYNC); } /* 添加一个同步任务,在上一个任务完成后执行回调函数 * @param callback 回调函数 */ FrameAnimation.prototype.then = function(callback){ var taskFn = function(next){ callback(this); next(); }; var type = TASK_SYNC; return this._add(taskFn,type); } /* 开始执行任务,异步定义任务执行的间隔 * @param interval */ FrameAnimation.prototype.start = function(interval){ if(this.state === STATE_START){ return this; } //如果任务链中没有任务,则返回 if(!this.taskQueue.length){ return this; } this.state = STATE_START; this.interval = interval; this._runTask(); return this; } /* 添加一个同步任务,回退到上一个任务,实现重复上一个任务的效果,可以定义重复的次数 * @param times 重复次数 */ FrameAnimation.prototype.repeat = function(times){ var me = this; var taskFn = function(){ if(typeof times === 'undefined'){ //无限回退到上一个任务 me.index--; me._runTask(); return; } if(times){ times--; //回退 me.index--; me._runTask(); }else{ //达到重复次数,跳转到下一个任务 var task = me.taskQueue[me.index]; me._next(task); } } var type = TASK_SYNC; return this._add(taskFn,type); } /* 添加一个同步任务,相当于repeat(),无限循环上一次任务 * */ FrameAnimation.prototype.repeatForever = function(){ return this.repeat(); } /* 设置当前任务执行结束后到下一个任务开始前的等待时间 * @param time 等待时长 */ FrameAnimation.prototype.wait = function(time){ if(this.taskQueue && this.taskQueue.length > 0){ this.taskQueue[this.taskQueue.length - 1].wait = time; } return this; } /* 暂停当前异步定时任务 * */ FrameAnimation.prototype.pause = function(){ if(this.state === STATE_START){ this.state = STATE_STOP; this.timeline.stop(); return this; } return this; } /* 重新执行上一次暂停的异步定时任务 * */ FrameAnimation.prototype.restart = function(){ if(this.state === STATE_STOP){ this.state = STATE_START; this.timeline.restart(); return this; } return this; } /* 释放资源 * */ FrameAnimation.prototype.dispose = function(){ if(this.state !== STATE_INITIAL){ this.state = STATE_INITIAL; this.taskQueue = null; this.timeline.stop(); this.timeline = null; return this; } return this; } /** * 添加一个任务到任务队列 * @param taskFn 任务方法 * @param type 任务类型 * @private */ FrameAnimation.prototype._add = function(taskFn,type){ this.taskQueue.push({ taskFn:taskFn, type:type }); return this; } /** * 执行任务 * @private */ FrameAnimation.prototype._runTask = function(){ if(!this.taskQueue || this.state !== STATE_START){ return; } //任务执行完毕 if(this.index === this.taskQueue.length){ this.dispose(); return; } //获得任务链上的当前任务 var task = this.taskQueue[this.index]; if(task.type === TASK_SYNC){ this._syncTask(task); }else{ this._asyncTask(task); } } /** * 同步任务 * @param task 执行的任务对象 * @private */ FrameAnimation.prototype._syncTask = function(task){ var me = this; var next = function(){ //切换到下一个任务 me._next(task); } var taskFn = task.taskFn; taskFn(next); } /** * 异步任务 * @param task 执行的任务对象 * @private */ FrameAnimation.prototype._asyncTask = function(task){ var me = this; //定义每一帧执行的回调函数 var enterframe = function(time){ var taskFn = task.taskFn; var next = function(){ //停止当前任务 me.timeline.stop(); //执行下一个任务 me._next(task); }; taskFn(next,time); } this.timeline.onenterframe = enterframe; this.timeline.start(this.interval); } /** * 切换到下一个任务,支持如果当前任务需要等待,则延时执行 * @private */ FrameAnimation.prototype._next = function(task){ this.index++; var me = this; task.wait ? setTimeout(function(){ me._runTask(); },task.wait) : this._runTask(); } module.exports = function(){ return new FrameAnimation(); }
webpack configuration
due to animation frame animation library The AMD module specification is applied in the production, but because it is not supported at the browser level, webpack needs to be used for modular management, and animation.js, imageloader.js and timeline.js are packaged into one file
module.exports = { entry:{ animation:"./src/animation.js" }, output:{ path:__dirname + "/build", filename:"[name].js", library:"animation", libraryTarget:"umd", } }
The following is a code example to achieve the animation effect of blog start through the created frame animation library
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <p id="rabbit" ></p> <script src="../build/animation.js"></script> <script>var imgUrl = 'rabbit-big.png'; var positions = ['0,-854','-174 -852','-349 -852','-524 -852','-698 -852','-873 -848']; var ele = document.getElementById('rabbit'); var animation = window.animation; var repeatAnimation = animation().loadImage([imgUrl]).changePosition(ele,positions,imgUrl).repeatForever(); repeatAnimation.start(80); </script> </body> </html>
More examples
In addition to achieving the effect of a rabbit cart, you can also use frame animation to achieve the effects of rabbit victory and rabbit failure
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> p{position:absolute;width:102px;height:80px;background-repeat:no-repeat;} </style> </head> <body> <p id="rabbit1" ></p> <p id="rabbit2" ></p> <p id="rabbit3" ></p> <script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/26/ddzmgynp/animation.js"></script> <script> var baseUrl = 'http://7xpdkf.com1.z0.glb.clouddn.com/runjs/img/'; var images = ['rabbit-big.png','rabbit-lose.png','rabbit-win.png']; for(var i = 0; i < images.length; i++){ images[i] = baseUrl + images[i]; } var rightRunningMap = ["0 -854", "-174 -852", "-349 -852", "-524 -852", "-698 -851", "-873 -848"]; var leftRunningMap = ["0 -373", "-175 -376", "-350 -377", "-524 -377", "-699 -377", "-873 -379"]; var rabbitWinMap = ["0 0", "-198 0", "-401 0", "-609 0", "-816 0", "0 -96", "-208 -97", "-415 -97", "-623 -97", "-831 -97", "0 -203", "-207 -203", "-415 -203", "-623 -203", "-831 -203", "0 -307", "-206 -307", "-414 -307", "-623 -307"]; var rabbitLoseMap = ["0 0", "-163 0", "-327 0", "-491 0", "-655 0", "-819 0", "0 -135", "-166 -135", "-333 -135", "-500 -135", "-668 -135", "-835 -135", "0 -262"]; var animation = window.animation; function repeat(){ var repeatAnimation = animation().loadImage(images).changePosition(rabbit1, rightRunningMap, images[0]).repeatForever(); repeatAnimation.start(80); } function win() { var winAnimation = animation().loadImage(images).changePosition(rabbit2, rabbitWinMap, images[2]).repeatForever(); winAnimation.start(200); } function lose() { var loseAnimation = animation().loadImage(images).changePosition(rabbit3, rabbitLoseMap, images[1]).repeatForever(); loseAnimation.start(200); } repeat(); win(); lose(); </script> </body> </html>
The above is the detailed content of Examples to explain javascript frame animation. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics


![Animation not working in PowerPoint [Fixed]](https://img.php.cn/upload/article/000/887/227/170831232982910.jpg?x-oss-process=image/resize,m_fill,h_207,w_330)
Are you trying to create a presentation but can't add animation? If animations are not working in PowerPoint on your Windows PC, then this article will help you. This is a common problem that many people complain about. For example, animations may stop working during presentations in Microsoft Teams or during screen recordings. In this guide, we will explore various troubleshooting techniques to help you fix animations not working in PowerPoint on Windows. Why aren't my PowerPoint animations working? We have noticed that some possible reasons that may cause the animation in PowerPoint not working issue on Windows are as follows: Due to personal

Face detection and recognition technology is already a relatively mature and widely used technology. Currently, the most widely used Internet application language is JS. Implementing face detection and recognition on the Web front-end has advantages and disadvantages compared to back-end face recognition. Advantages include reducing network interaction and real-time recognition, which greatly shortens user waiting time and improves user experience; disadvantages include: being limited by model size, the accuracy is also limited. How to use js to implement face detection on the web? In order to implement face recognition on the Web, you need to be familiar with related programming languages and technologies, such as JavaScript, HTML, CSS, WebRTC, etc. At the same time, you also need to master relevant computer vision and artificial intelligence technologies. It is worth noting that due to the design of the Web side

We often use ppt in our daily work, so are you familiar with every operating function in ppt? For example: How to set animation effects in ppt, how to set switching effects, and what is the effect duration of each animation? Can each slide play automatically, enter and then exit the ppt animation, etc. In this issue, I will first share with you the specific steps of entering and then exiting the ppt animation. It is below. Friends, come and take a look. Look! 1. First, we open ppt on the computer, click outside the text box to select the text box (as shown in the red circle in the figure below). 2. Then, click [Animation] in the menu bar and select the [Erase] effect (as shown in the red circle in the figure). 3. Next, click [

This website reported on January 26 that the domestic 3D animated film "Er Lang Shen: The Deep Sea Dragon" released a set of latest stills and officially announced that it will be released on July 13. It is understood that "Er Lang Shen: The Deep Sea Dragon" is produced by Mihuxing (Beijing) Animation Co., Ltd., Horgos Zhonghe Qiancheng Film Co., Ltd., Zhejiang Hengdian Film Co., Ltd., Zhejiang Gongying Film Co., Ltd., Chengdu The animated film produced by Tianhuo Technology Co., Ltd. and Huawen Image (Beijing) Film Co., Ltd. and directed by Wang Jun was originally scheduled to be released in mainland China on July 22, 2022. Synopsis of the plot of this site: After the Battle of the Conferred Gods, Jiang Ziya took the "Conferred Gods List" to divide the gods, and then the Conferred Gods List was sealed by the Heavenly Court under the deep sea of Kyushu Secret Realm. In fact, in addition to conferring divine positions, there are also many powerful evil spirits sealed in the Conferred Gods List.

According to news from this site, Miyazaki Hayao's animated film "Porco Rosso" has announced that it will extend the release date to January 16, 2024. This site previously reported that "Porco Rosso" has been launched in the National Art Federation Special Line Cinema on November 17, with a cumulative box office of over 2,000 10,000, with a Douban score of 8.6, and 85.8% of 4 and 5 star reviews. "Porco Rosso" was produced by Studio Ghibli and directed by Hayao Miyazaki. Moriyama Moriyama, Tokiko Kato, Otsuka Akio, Okamura Akemi and others participated in the dubbing. It was originally released in Japan in 1992. The film is adapted from Hayao Miyazaki's comic book "The Age of Airships" and tells the story of the Italian Air Force's ace pilot Pollock Rosen who was magically turned into a pig. After that, he became a bounty hunter, fighting against air robbers and protecting those around him. Plot synopsis: Rosen is a soldier in World War I

With the rapid development of Internet finance, stock investment has become the choice of more and more people. In stock trading, candle charts are a commonly used technical analysis method. It can show the changing trend of stock prices and help investors make more accurate decisions. This article will introduce the development skills of PHP and JS, lead readers to understand how to draw stock candle charts, and provide specific code examples. 1. Understanding Stock Candle Charts Before introducing how to draw stock candle charts, we first need to understand what a candle chart is. Candlestick charts were developed by the Japanese

If you are eager to find the top free AI animation art generator, you can end your search. The world of anime art has been captivating audiences for decades with its unique character designs, captivating colors and captivating plots. However, creating anime art requires talent, skill, and a lot of time. However, with the continuous development of artificial intelligence (AI), you can now explore the world of animation art without having to delve into complex technologies with the help of the best free AI animation art generator. This will open up new possibilities for you to unleash your creativity. What is an AI anime art generator? The AI Animation Art Generator utilizes sophisticated algorithms and machine learning techniques to analyze an extensive database of animation works. Through these algorithms, the system learns and identifies different animation styles

JavaScript tutorial: How to get HTTP status code, specific code examples are required. Preface: In web development, data interaction with the server is often involved. When communicating with the server, we often need to obtain the returned HTTP status code to determine whether the operation is successful, and perform corresponding processing based on different status codes. This article will teach you how to use JavaScript to obtain HTTP status codes and provide some practical code examples. Using XMLHttpRequest
