Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
下是使用不同編程語(yǔ)言實(shí)現(xiàn)按大小順序輸出的示例代碼,并對(duì)每種語(yǔ)言的實(shí)現(xiàn)原理進(jìn)行說(shuō)明:
C語(yǔ)言實(shí)現(xiàn)原理:
C語(yǔ)言代碼:
#include <stdio.h>
void sort(int *arr, int n) {
for (int i = 0; i < n-1; i++) {
for (int j = 0; j < n-i-1; j++) {
if (arr[j] > arr[j+1]) {
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
int main() {
int a, b, c;
printf("Enter three numbers: ");
scanf("%d %d %d", &a, &b, &c);
int arr[] = {a, b, c};
int n = sizeof(arr)/sizeof(arr[0]);
sort(arr, n);
printf("Sorted numbers: %d %d %d\n", arr[0], arr[1], arr[2]);
return 0;
}
C++實(shí)現(xiàn)原理:
C++代碼:
#include <iostream>
#include <algorithm>
int main() {
int a, b, c;
std::cout << "Enter three numbers: ";
std::cin >> a >> b >> c;
int arr[] = {a, b, c};
int n = sizeof(arr)/sizeof(arr[0]);
std::sort(arr, arr+n);
std::cout << "Sorted numbers: " << arr[0] << " " << arr[1] << " " << arr[2] << std::endl;
return 0;
}
Java實(shí)現(xiàn)原理:
Java代碼:
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter three numbers: ");
int a = scanner.nextInt();
int b = scanner.nextInt();
int c = scanner.nextInt();
int[] arr = {a, b, c};
Arrays.sort(arr);
System.out.println("Sorted numbers: " + arr[0] + " " + arr[1] + " " + arr[2]);
}
}
Python實(shí)現(xiàn)原理:
Python代碼:
a = int(input("Enter the first number: "))
b = int(input("Enter the second number: "))
c = int(input("Enter the third number: "))
arr = [a, b, c]
arr.sort()
print("Sorted numbers:", arr[0], arr[1], arr[2])
C#實(shí)現(xiàn)原理:
C#代碼:
using System;
class Program
{
static void Main()
{
Console.Write("Enter three numbers: ");
int a = int.Parse(Console.ReadLine());
int b = int.Parse(Console.ReadLine());
int c = int.Parse(Console.ReadLine());
int[] arr = {a, b, c};
Array.Sort(arr);
Console.WriteLine("Sorted numbers: {0} {1} {2}", arr[0], arr[1], arr[2]);
}
}
JavaScript實(shí)現(xiàn)原理:
JavaScript代碼:
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question('Enter three numbers: ', (input) => {
const numbers = input.split(' ').map(Number);
numbers.sort((a, b) => a - b);
console.log(`Sorted numbers: ${numbers[0]} ${numbers[1]} ${numbers[2]}`);
rl.close();
});
以上是使用不同編程語(yǔ)言實(shí)現(xiàn)按大小順序輸出的示例代碼,并對(duì)每種語(yǔ)言的實(shí)現(xiàn)原理進(jìn)行了說(shuō)明。每種語(yǔ)言都使用了不同的排序算法來(lái)對(duì)輸入的數(shù)字進(jìn)行排序,然后輸出排序后的結(jié)果。
挑戰(zhàn)30天在頭條寫日記#
HTML是一種用于創(chuàng)建網(wǎng)頁(yè)結(jié)構(gòu)和內(nèi)容的標(biāo)記語(yǔ)言,其中包含了許多標(biāo)簽,可以用于排版、布局和展示內(nèi)容。本文將詳細(xì)介紹HTML中的<tr>和<td>標(biāo)簽的使用方法,并通過(guò)示例展示如何創(chuàng)建表格。
1. <tr>標(biāo)簽的作用: <tr>標(biāo)簽代表HTML表格中的一行(行數(shù)據(jù)),它可以包含一個(gè)或多個(gè)<td>元素作為單元格。
2. <td>標(biāo)簽的作用: <td>標(biāo)簽用于定義表格中的一個(gè)單元格(列數(shù)據(jù)),可以包含文本、圖像、鏈接等內(nèi)容。
3. 如何使用<tr>和<td>: 在使用<tr>和<td>標(biāo)簽時(shí),首先需要?jiǎng)?chuàng)建一個(gè)<table>元素作為表格的容器,然后在其中嵌套<tr>和<td>標(biāo)簽,如下所示:
htmlCopy code<table>
<tr>
<td>單元格1</td>
<td>單元格2</td>
</tr>
<tr>
<td>單元格3</td>
<td>單元格4</td>
</tr>
</table>
4. 表格樣式: 可以使用CSS來(lái)為表格添加樣式,如設(shè)置邊框、背景顏色等。以下是一個(gè)簡(jiǎn)單的示例:
htmlCopy code<style>
table {
border-collapse: collapse;
width: 100%;
}
td {
border: 1px solid black;
padding: 8px;
text-align: center;
}
</style>
5. 示例應(yīng)用: 以下示例演示了如何使用<tr>和<td>標(biāo)簽創(chuàng)建一個(gè)包含姓名、年齡和城市的簡(jiǎn)單表格:
htmlCopy code<!DOCTYPE html>
<html>
<head>
<style>
table {
border-collapse: collapse;
width: 100%;
}
td {
border: 1px solid black;
padding: 8px;
text-align: center;
}
</style>
</head>
<body>
<table>
<tr>
<td>姓名</td>
<td>年齡</td>
<td>城市</td>
</tr>
<tr>
<td>張三</td>
<td>25</td>
<td>北京</td>
</tr>
<tr>
<td>李四</td>
<td>30</td>
<td>上海</td>
</tr>
<tr>
<td>王五</td>
<td>28</td>
<td>廣州</td>
</tr>
</table>
</body>
</html>
6. 書籍參考:
7. 總結(jié): 通過(guò)本文的介紹,我們了解了HTML中<tr>和<td>標(biāo)簽的基本用法,以及如何創(chuàng)建簡(jiǎn)單的表格和添加樣式。使用這些標(biāo)簽,我們可以輕松地創(chuàng)建具有結(jié)構(gòu)和內(nèi)容的網(wǎng)頁(yè)表格,提升頁(yè)面的可讀性和可視性。
信 8.0 更新的一大特色就是支持動(dòng)畫表情,如果發(fā)送的消息只有一個(gè)內(nèi)置的表情圖標(biāo),這個(gè)表情會(huì)有一段簡(jiǎn)單的動(dòng)畫,一些特殊的表情還有全屏特效,例如煙花表情有全屏放煙花的特效,炸彈表情有爆炸動(dòng)畫并且消息和頭像也會(huì)隨之震動(dòng)。
近日,前端工程師華峰用300行代碼實(shí)現(xiàn)微信表情包炸裂的特效,一起來(lái)看看做出來(lái)的效果吧:
據(jù)他描述:項(xiàng)目的核心是使用到了 lottie 動(dòng)畫庫(kù)。
lottie 是 Airbnb 出品的、全平臺(tái)(Web、Android、IOS、React Native)的動(dòng)畫庫(kù),它的特點(diǎn)在于能夠直接播放使用 Adobe After Effects 制作的動(dòng)畫。設(shè)計(jì)師在 After Effects 中,利用 Bodymovin 插件把動(dòng)畫導(dǎo)出為 JSON 格式之后,開(kāi)發(fā)者就能夠通過(guò)相應(yīng)平臺(tái)的 SDK 進(jìn)行播放。
發(fā)送普通消息時(shí),用戶在輸入框輸入完消息之后,點(diǎn)擊發(fā)送,就會(huì)把該條消息追加到消息列表中,并清空輸入框中的內(nèi)容。那么這里先給發(fā)送按鈕添加點(diǎn)擊事件:
sendBtn.addEventListener("click", () => {
const msg = msgInputEle.value;
if (msg) {
appendMsg(msg);
}
});
在事件處理函數(shù)中:
來(lái)看一下 appendMsg() 函數(shù)的代碼:
function appendMsg(msg, type) {
// 創(chuàng)建消息元素
const msgEle = panelEle.appendChild(document.createElement("div"));
msgEle.classList.add("message", "mine"); // 設(shè)置為“我“發(fā)送的樣式
msgEle.innerHTML = `
<img class="avatar" src="./me.png" alt="" />
<p><span>${msg}</span></p>
`;
// 滾動(dòng)到最新消息
panelEle.scrollTop = panelEle.scrollHeight;
msgInputEle.value = "";
}
函數(shù)接收兩個(gè)參數(shù),msg 和 type,分別是要追加的消息內(nèi)容和類型,type 為可選的,不傳則認(rèn)為是普通文本消息,如果傳遞了 "stickers" 則為表情消息,現(xiàn)在還用不到它。在這個(gè)函數(shù)中主要做了下面幾件事情:
這樣就可以發(fā)送普通的文本消息了。
在發(fā)送動(dòng)畫表情之前,需要先加載動(dòng)畫表情。在 index.js 的最上方先定義表情名稱和表情動(dòng)畫文件路徑的鍵值對(duì)信息:
const stickers = {
bomb: {
path: "./3145-bomb.json",
},
pumpkin: {
path: "./43215-pumpkins-sticker-4.json",
},
};
我們會(huì)根據(jù) bomb 、 pumkin 這樣的 key 來(lái)找到對(duì)應(yīng)的動(dòng)畫路徑。接著初始化彈出層中的表情以供用戶選擇:
// 初始化表情面板,也可以在表情選擇窗彈出時(shí)再初始化
Object.keys(stickers).forEach((key) => {
const lottieEle = stickersEle.appendChild(document.createElement("span"));
// 對(duì)每個(gè)表情創(chuàng)建 lottie 播放器
const player = lottie.loadAnimation({
container: lottieEle,
renderer: "svg",
loop: true,
autoplay: false,
path: stickers[key].path,
});
// 當(dāng)選擇表情時(shí),發(fā)送消息,并設(shè)置類型為 sticker 表情消息
lottieEle.addEventListener("click", () => {
appendMsg(key, "sticker");
});
// 當(dāng)鼠標(biāo)劃過(guò)時(shí),播放動(dòng)畫預(yù)覽
lottieEle.addEventListener("mouseover", () => {
player.play();
});
// 當(dāng)鼠標(biāo)劃過(guò)時(shí),停止動(dòng)畫預(yù)覽
lottieEle.addEventListener("mouseleave", () => {
player.stop();
});
});
這里的代碼分別作了下邊這些操作:
然后后邊則注冊(cè)了幾個(gè)事件:
接著給發(fā)送表情按鈕添加事件,點(diǎn)擊時(shí),切換表情彈出層的顯示狀態(tài):
chooseStickerBtn.addEventListener("click", () => {
stickersEle.classList.toggle("show");
});
這時(shí)點(diǎn)擊發(fā)送表情按鈕就可以看到表情選擇彈出層了。現(xiàn)在還不能發(fā)送表情,因?yàn)檫€沒(méi)在 appendMsg() 函數(shù)中處理,現(xiàn)在來(lái)修改一下它里邊的代碼。首先判斷:如果是表情消息,則不在消息中的 <p> 元素里添加任何信息:
function appendMsg(msg, type) {
// ...
msgEle.innerHTML = `
<img class="avatar" src="./me.png" alt="" />
<p><span>${type === "sticker" ? "" : msg}</span></p>
`;
}
然后在它的下方,調(diào)用 playSticker() 函數(shù)來(lái)播放動(dòng)畫:
// 處理表情消息,播放相關(guān)動(dòng)畫
if (type === "sticker") {
playSticker(msg, msgEle);
}
playSticker() 函數(shù)接收兩個(gè)參數(shù),一個(gè)是表情的 key,一個(gè)是消息元素。此時(shí)的 msg 變量的內(nèi)容就是在 lottieEle 點(diǎn)擊事件中傳遞過(guò)來(lái)的表情 key。函數(shù)中的代碼如下:
function playSticker(key, msgEle) {
// 表情消息,創(chuàng)建 lottie 動(dòng)畫
const lottieEle = msgEle.querySelector("span");
lottieEle.style.width = "40px";
lottieEle.style.height = "40px";
lottie.loadAnimation({
container: lottieEle,
renderer: "svg",
loop: false,
autoplay: true,
path: stickers[key].path,
});
}
在這個(gè)函數(shù)里主要做了下邊幾項(xiàng)操作:
現(xiàn)在可以發(fā)送表情消息了,相關(guān)的動(dòng)畫也會(huì)自動(dòng)播放,接下來(lái)看一下怎么實(shí)現(xiàn)炸彈的全屏動(dòng)畫和對(duì)消息元素的晃動(dòng)效果。
發(fā)送帶全屏特效的表情
對(duì)于這種帶全屏特效的表情可以單獨(dú)進(jìn)行判斷,也可以在保存表情的對(duì)象中定義相關(guān)的操作,這里為了簡(jiǎn)單起見(jiàn),我們單獨(dú)判斷用戶是否發(fā)送了炸彈表情,然后施加相應(yīng)特效。
首先在 appendMsg() 函數(shù)里,進(jìn)行判斷,如果發(fā)送的消息是表情消息,且表情為炸彈,則播放全屏動(dòng)畫并晃動(dòng)消息:
function appendMsg(msg, type) {
if (type === "sticker") {
playSticker(msg, msgEle);
if (msg === "bomb") {
// 播放爆炸動(dòng)畫
setTimeout(() => {
playExplosion(msgEle);
}, 800);
// 晃動(dòng)消息列表
shakeMessages();
}
}
}
這里爆炸全屏動(dòng)畫延遲了 800 毫秒之后再執(zhí)行,目的是在炸彈表情播放到合適的時(shí)間時(shí),再播放全屏動(dòng)畫,播放動(dòng)畫使用了 playExplosion() 函數(shù),并傳遞了消息元素進(jìn)去。在爆炸全屏動(dòng)畫結(jié)束之后,調(diào)用 shakeMessages() 來(lái)晃動(dòng)消息。這里先看一下 playExplosion() 函數(shù)的代碼:
function playExplosion(anchor) {
const explosionAnimeEle = anchor.appendChild(document.createElement("div"));
explosionAnimeEle.style.position = "absolute";
explosionAnimeEle.style.width = "200px";
explosionAnimeEle.style.height = "100px";
explosionAnimeEle.style.right = 0;
explosionAnimeEle.style.bottom = 0;
const explosionPlayer = lottie.loadAnimation({
container: explosionAnimeEle,
renderer: "svg",
loop: false,
autoplay: true,
path: "./9990-explosion.json",
});
explosionPlayer.setSpeed(0.3);
// 播放完成后,銷毀爆炸相關(guān)的動(dòng)畫和元素
explosionPlayer.addEventListener("complete", () => {
explosionPlayer.destroy();
explosionAnimeEle.remove();
});
}
playExplosion() 函數(shù)接收一個(gè) anchor 錨點(diǎn),就是說(shuō)基于哪個(gè)位置開(kāi)始播放全屏動(dòng)畫,由于示例中的動(dòng)畫畫幅比較小,所以把它固定在了最新發(fā)送的消息的下方,這里爆炸動(dòng)畫的 anchor 就是消息元素,之后函數(shù)做了下邊的這些操作:
這樣全屏動(dòng)畫的效果就實(shí)現(xiàn)了。接下來(lái)看消息晃動(dòng)的代碼:
function shakeMessages() {
[...panelEle.children]
.reverse()
.slice(0, 5)
.forEach((messageEle) => {
const avatarEle = messageEle.querySelector("img");
const msgContentEle = messageEle.querySelector("p");
avatarEle.classList.remove("shake");
msgContentEle.classList.remove("shake");
setTimeout(() => {
avatarEle.classList.add("shake");
msgContentEle.classList.add("shake");
}, 700);
});
}
這個(gè)函數(shù)的操作是:
接下來(lái)看一下 shake class 的定義,在 style.css 中添加下方代碼:
.shake {
animation: shake 0.8s ease-in-out;
}
@keyframes shake {
from {
transform: translate3d(0, 0px, 0px);
}
10% {
transform: translate3d(6px, -6px, 0px);
}
20% {
transform: translate3d(-5px, 5px, 0px);
}
30% {
transform: translate3d(4px, -4px, 0px);
}
35% {
transform: translate3d(-3px, 3px, 0px);
}
39% {
transform: translate3d(2px, -2px, 0px);
}
41% {
transform: translate3d(-1px, 1px, 0px);
}
42% {
transform: translate3d(0px, 0px, 0px) rotate(20deg);
}
52% {
transform: rotate(-15deg);
}
60% {
transform: rotate(8deg);
}
65% {
transform: rotate(-3deg);
}
67% {
transform: rotate(1deg);
}
70% {
transform: rotate(0deg);
}
to {
transform: translate3d(0px, 0px, 0px) rotate(0);
}
}
.shake 中使用了 shake keyframes 定義的動(dòng)畫,執(zhí)行時(shí)間為 0.8s,動(dòng)畫執(zhí)行函數(shù)為 ease-in-out。Keyframes 里的代碼比較多,但是都是很簡(jiǎn)單的,就是模擬了爆炸時(shí)的效果,移動(dòng) x 軸和 y 軸的偏移,每次的偏移幅度越來(lái)越小,并且越來(lái)越快,可以看到百分比的間隔越來(lái)越小。在動(dòng)畫進(jìn)行到 42% 的時(shí)候,加了一些旋轉(zhuǎn)動(dòng)畫,這樣就有了落地時(shí)的震動(dòng)效果。由于使用 rotate() 旋轉(zhuǎn)時(shí)的軸心在元素中間,我們可以把消息氣泡的軸心修改一下來(lái)實(shí)現(xiàn)更真實(shí)的效果:
.message p {
transform-origin: left bottom;
}
.message.mine p {
transform-origin: right bottom;
}
這里把對(duì)方發(fā)送的消息的軸心設(shè)置在左下角,自己發(fā)送的消息則設(shè)置在了右下角。
本文所有地址:
現(xiàn)在,這個(gè)模擬微信 8.0 動(dòng)畫表情的功能就實(shí)現(xiàn)了。主要就是下邊幾點(diǎn):
那么問(wèn)題來(lái)了,作為編程界大佬的C語(yǔ)言能否實(shí)現(xiàn)微信對(duì)話框爆炸特效呢?這個(gè)需要大家一起探索!小編相信C語(yǔ)言的強(qiáng)大,是完全可以做到的,甚至更加簡(jiǎn)單,期待各位小伙伴一起討論~
如果你對(duì)學(xué)習(xí)編程有興趣,也想有一天別人使用你開(kāi)發(fā)的軟件或小程序、小特效,沒(méi)基礎(chǔ)也完全不用擔(dān)心,因?yàn)闄C(jī)會(huì)來(lái)了,點(diǎn)擊下方的了解更多鏈接,開(kāi)啟你的編程之旅~
在這里我們有什么?
1、海量學(xué)習(xí)資源
2、名師一對(duì)一指導(dǎo)
3、同行之間的相互切磋
4、外包項(xiàng)目拿到手軟
心動(dòng)不如行動(dòng),趕緊點(diǎn)擊下方了解更多免費(fèi)領(lǐng)取你的專屬福利吧~
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。