天北京也飄雪 ?? 了! 在日常 Web 開發中實現飄雪效果時,我們首先想到的是通過 JavaScript 來實現。現代 CSS 這么強大,能否直接使用 CSS 來實現呢。經過調研后,鑒于現代 CSS 的強大,確實可以使用純 CSS 來實現飄雪動畫效果。
CSS 關鍵幀和動畫是實現飄雪動畫的關鍵,使用動畫延遲、位置變換可以讓視覺感知更為明顯。同時讓圖標獨立于布局,可以實現雪花像真正的雪花一樣飄動。
主要的雪花實現方案有:
1)HTML 元素:
使用多個 HTML 元素來繪制雪花,這個實現起來比較簡單,使用雪花 ICON 或者雪花字符(44 或 ?)來充當雪花,這種實現起來比較簡單,看著會比較真實。
2)背景圖片:
使用背景圖片,即 CSS 的 radial-gradient() 函數來繪制雪花,這個可以實現對每個雪花的樣式靈活可控
CSS radial-gradient() 函數創建一個 <image>,用來展示由 原點(漸變中心) 輻射開的顏色漸變。這個方法得到的是一個 CSS 數據類型的對象,這是一種特殊的 <image>。
基本語法:
radial-gradient( [ x [, y] ] [ circle | ellipse ] [ extent-keyword ] at [ position ] , [color-stop [, length | persentage]]+ )
本文采用 CSS radial-gradient() 來實現雪花,通過 html:5 和 div.snow 來快速創建頁面框架:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div class="snow"></div>
</body>
</html>
為了效果更真實,同時給 .snow 元素增加了兩個偽元素 ::before 和 ::after 來增強效果。
.snow,
.snow::before,
.snow::after {
background-image:
radial-gradient( 4px 4px at 259px 455px, white 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 6px 6px at 347px 72px, rgba(255, 255, 255, 0.9) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 3px 3px at 345px 235px, rgba(255, 255, 255, 0.8) 50%, rgba(0, 0, 0, 0) ),
radial-gradient(3px 3px at 152px 121px, white 50%, rgba(0, 0, 0, 0)),
radial-gradient(5px 5px at 408px 540px, white 50%, rgba(0, 0, 0, 0)),
radial-gradient( 6px 6px at 131px 307px, rgba(255, 255, 255, 0.9) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 3px 3px at 100px 410px, rgba(255, 255, 255, 0.9) 50%, rgba(0, 0, 0, 0) ),
radial-gradient(4px 4px at 88px 302px, white 50%, rgba(0, 0, 0, 0)),
radial-gradient(4px 4px at 582px 533px, white 50%, rgba(0, 0, 0, 0)),
radial-gradient( 5px 5px at 488px 476px, rgba(255, 255, 255, 0.6) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 6px 6px at 20px 470px, rgba(255, 255, 255, 0.9) 50%, rgba(0, 0, 0, 0) ),
radial-gradient(6px 6px at 303px 513px, white 50%, rgba(0, 0, 0, 0)),
radial-gradient( 6px 6px at 50px 491px, rgba(255, 255, 255, 0.6) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 4px 4px at 414px 30px, rgba(255, 255, 255, 0.9) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 3px 3px at 287px 589px, rgba(255, 255, 255, 0.8) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 4px 4px at 7px 238px, rgba(255, 255, 255, 0.8) 50%, rgba(0, 0, 0, 0) ),
radial-gradient(5px 5px at 99px 579px, white 50%, rgba(0, 0, 0, 0)),
radial-gradient(6px 6px at 118px 66px, white 50%, rgba(0, 0, 0, 0)),
radial-gradient(5px 5px at 51px 396px, white 50%, rgba(0, 0, 0, 0)),
radial-gradient( 6px 6px at 101px 21px, rgba(255, 255, 255, 0.6) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 6px 6px at 228px 115px, rgba(255, 255, 255, 0.6) 50%, rgba(0, 0, 0, 0) ),
radial-gradient(4px 4px at 74px 168px, white 50%, rgba(0, 0, 0, 0)),
radial-gradient( 3px 3px at 158px 9px, rgba(255, 255, 255, 0.7) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 5px 5px at 338px 147px, rgba(255, 255, 255, 0.7) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 5px 5px at 567px 57px, rgba(255, 255, 255, 0.8) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 5px 5px at 210px 99px, rgba(255, 255, 255, 0.7) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 6px 6px at 338px 556px, rgba(255, 255, 255, 0.9) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 4px 4px at 536px 350px, rgba(255, 255, 255, 0.6) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 3px 3px at 281px 36px, rgba(255, 255, 255, 0.8) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 6px 6px at 139px 151px, rgba(255, 255, 255, 0.8) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 6px 6px at 494px 202px, rgba(255, 255, 255, 0.6) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 4px 4px at 594px 262px, rgba(255, 255, 255, 0.6) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 4px 4px at 338px 239px, rgba(255, 255, 255, 0.9) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 3px 3px at 389px 480px, rgba(255, 255, 255, 0.9) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 4px 4px at 85px 391px, rgba(255, 255, 255, 0.7) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 6px 6px at 271px 181px, rgba(255, 255, 255, 0.7) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 3px 3px at 425px 237px, rgba(255, 255, 255, 0.6) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 3px 3px at 239px 399px, rgba(255, 255, 255, 0.9) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 4px 4px at 387px 592px, rgba(255, 255, 255, 0.9) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 3px 3px at 307px 461px, rgba(255, 255, 255, 0.6) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 3px 3px at 458px 142px, rgba(255, 255, 255, 0.8) 50%, rgba(0, 0, 0, 0) ),
radial-gradient(6px 6px at 593px 136px, white 50%, rgba(0, 0, 0, 0)),
radial-gradient( 6px 6px at 458px 363px, rgba(255, 255, 255, 0.7) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 6px 6px at 74px 549px, rgba(255, 255, 255, 0.9) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 5px 5px at 543px 462px, rgba(255, 255, 255, 0.9) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 4px 4px at 496px 547px, rgba(255, 255, 255, 0.6) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 3px 3px at 239px 523px, rgba(255, 255, 255, 0.6) 50%, rgba(0, 0, 0, 0) ),
radial-gradient(4px 4px at 216px 249px, white 50%, rgba(0, 0, 0, 0)),
radial-gradient( 6px 6px at 120px 195px, rgba(255, 255, 255, 0.9) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 6px 6px at 130px 551px, rgba(255, 255, 255, 0.7) 50%, rgba(0, 0, 0, 0) ),
radial-gradient(6px 6px at 328px 533px, white 50%, rgba(0, 0, 0, 0)),
radial-gradient( 6px 6px at 531px 461px, rgba(255, 255, 255, 0.8) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 4px 4px at 58px 311px, rgba(255, 255, 255, 0.7) 50%, rgba(0, 0, 0, 0) ),
radial-gradient(3px 3px at 139px 296px, white 50%, rgba(0, 0, 0, 0)),
radial-gradient( 3px 3px at 57px 364px, rgba(255, 255, 255, 0.6) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 4px 4px at 576px 512px, rgba(255, 255, 255, 0.9) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 5px 5px at 248px 262px, rgba(255, 255, 255, 0.8) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 6px 6px at 576px 244px, rgba(255, 255, 255, 0.6) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 4px 4px at 452px 483px, rgba(255, 255, 255, 0.9) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 6px 6px at 154px 175px, rgba(255, 255, 255, 0.8) 50%, rgba(0, 0, 0, 0) ),
radial-gradient(3px 3px at 593px 286px, white 50%, rgba(0, 0, 0, 0)),
radial-gradient( 6px 6px at 255px 543px, rgba(255, 255, 255, 0.9) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 5px 5px at 50px 443px, rgba(255, 255, 255, 0.9) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 5px 5px at 23px 71px, rgba(255, 255, 255, 0.9) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 3px 3px at 182px 435px, rgba(255, 255, 255, 0.6) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 4px 4px at 155px 384px, rgba(255, 255, 255, 0.8) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 5px 5px at 160px 594px, rgba(255, 255, 255, 0.7) 50%, rgba(0, 0, 0, 0) ),
radial-gradient(5px 5px at 213px 144px, white 50%, rgba(0, 0, 0, 0)),
radial-gradient( 3px 3px at 533px 373px, rgba(255, 255, 255, 0.6) 50%, rgba(0, 0, 0, 0) ),
radial-gradient( 4px 4px at 519px 365px, rgba(255, 255, 255, 0.6) 50%, rgba(0, 0, 0, 0) );
}
通過給偽元素 ::before 和 ::after 增加動畫延遲、透明度、過濾效果,增加動畫效果和層次。
.snow,
.snow::before,
.snow::after {
animation: snow 3s linear infinite;
}
.snow::before {
opacity: 0.4;
animation-duration: 6s;
animation-direction: reverse;
filter: blur(3px);
}
.snow::after {
opacity: 0.65;
animation-duration: 9s;
animation-direction: reverse;
filter: blur(1.5px);
}
最近有一個需求,在flink程序中接受一段java源代碼,需要在flink程序中編譯這段代碼并執行,返回執行結果。
很多編譯方案都是將java文件和生成的class文件放在臨時磁盤上,但flink程序作為一個長期運行的任務,如果監控發現不及時,很可能出現臨時目錄滿了的情況,所以最好做成一個純內存編譯,提升任務的穩定性。
jdk中有JavaCompiler接口用來編譯java源碼,其中getTask方法用來生成一個編譯任務。其中的參數,compilationUnits用來表示需要編譯的內容;JavaFileManager用來管理各種文件;options用來傳遞編譯的參數(比如-classpath/-d等javac命令的參數)。
所有的文件都用JavaFileObject來表示,因此需要實現自己的類,用內存保存java源碼,用內存保存生成的class文件內容。
private static class StringSourceSimpleJavaFileObject extends SimpleJavaFileObject {
private final String code;
StringSourceSimpleJavaFileObject(String name, String code) {
super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
this.code = code;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return code;
}
@Override
public String toString() {
return code;
}
}
private static class OutputClassJavaFileObject extends SimpleJavaFileObject {
private final ByteArrayOutputStream outputStream;
protected OutputClassJavaFileObject(String className, Kind kind) {
super(URI.create("mem:///" + className.replace('.', '/') + kind.extension), kind);
this.outputStream = new ByteArrayOutputStream();
}
public OutputStream openOutputStream() throws IOException {
return this.outputStream;
}
public byte[] getBytes() {
return this.outputStream.toByteArray();
}
}
需要一個自定義的FileManager,當生成class文件時,使用自定義類。
需要注意的時,編譯一個源碼文件時,可能會因為內部類等原因,會生成多個class文件。
private static class FileManager extends ForwardingJavaFileManager<StandardJavaFileManager> {
private Map<String, OutputClassJavaFileObject> outputs = new LinkedHashMap<>();
FileManager(StandardJavaFileManager target) {
super(target);
}
@Override
public JavaFileObject getJavaFileForOutput(Location location, String className, JavaFileObject.Kind kind, FileObject sibling) {
final OutputClassJavaFileObject file = new OutputClassJavaFileObject(className, kind);
outputs.put(className, file);
return file;
}
public byte[] getOutputClassBytes(String className) {
OutputClassJavaFileObject file = outputs.get(className);
if (file != null) {
return file.getBytes();
}
return null;
}
public Map<String, byte[]> getOutputClassBytes() {
Map<String, byte[]> result = new LinkedHashMap<>();
for (Map.Entry<String, OutputClassJavaFileObject> entry : outputs.entrySet()) {
byte[] bytes = entry.getValue().getBytes();
if (bytes != null && bytes.length > 0) {
result.put(entry.getKey(), bytes);
}
}
return result;
}
}
public static byte[] compile(String className, String classSource, String classPath) {
logger.info("compile, className = {}, classPath = {}, sourceLength = {}", className, classPath, classSource.length());
long start = System.currentTimeMillis();
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
JavaFileObject file = new StringSourceSimpleJavaFileObject(className, classSource);
Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(file);
StandardJavaFileManager standardFileManager = compiler.getStandardFileManager(null, null, null);
FileManager fileManager = new FileManager(standardFileManager);
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
StringWriter out = new StringWriter();
Iterable<String> options = null;
if (classPath != null && classPath.length() > 0) {
options = Arrays.asList("-cp", classPath);
}
JavaCompiler.CompilationTask task = compiler.getTask(out, fileManager, diagnostics, options, null, compilationUnits);
boolean success = task.call();
byte[] result = null;
if (success) {
result = fileManager.getOutputClassBytes(className);
logger.info("compile, ok, className = {}", className);
} else {
logger.error("compile, error, className = {}", className);
logger.error("compile, error, className = {}, diagnostics = {}", className, formatDiagnostics(diagnostics));
}
logger.info("compile, className = {}, success = {}, cost = {} ms, byteCodeLength = {}", className, success,
System.currentTimeMillis() - start, result == null ? 0 : result.length);
return result;
}
https://stackoverflow.com/questions/7989135/is-it-possible-to-programmatically-compile-java-source-code-in-memory-only
https://docs.oracle.com/javase/7/docs/api/javax/tools/JavaCompiler.html
|燒腦廣告(shukewenzhai)
轉眼間,就進入了12月,2020年只剩下了不到一個月的時間。回望這一年,感覺格外特殊和短暫。每年年末都充滿了總結和感慨,這一年里,你經歷了什么?收獲了什么?改變了什么?
在年末這一節點,百度旗下的人工智能小度聯合代理商鯨夢發布了一支溫情短片《一人,一屋,一年度》,記錄了一位年輕人2020年的點滴生活,送給那些在大城市獨自打拼的年輕人。
▽
詳情復制鏈接打開:https://v.qq.com/x/page/b3207rt8nup.html
這支短片采用了固定畫幅,畫面只呈現了一扇窗戶、一張書桌、一個小度,通過主角的第一視角回顧了一位年輕人2020年里經歷的無聊、學習、挫折、堅持、努力......
2020年的年初,很多人和片中的主人公一樣,因為疫情被困在家里,百無聊賴中開始學習烹飪等技能。到年中時,疫情得到控制,人們生活走向正規,開始找回工作狀態,卻因為各種原因而面對和承受挫敗和壓力。下半年時,有些人失敗了離職了,但有些人仍然在堅持,或是找到了方向。
也許獨自在大城市生活,真的很辛苦。但既然都到這了,就再往前走走看吧。說不定走著走著,就看見花開了。
2020年是特殊的一年,這一年有太多大事件帶給人們無可言說的感動和感慨。以往的年末,許多品牌的年度廣告都傾向于用宏觀角度回顧一年的現象和精彩,更不用說今年。但小度這支年度廣告,卻用微觀視角聚焦到了真實個體上,回看了一個普通人的一年。
日歷翻回到2020年1月,窗外飄著細雪,她端著一杯不再熱乎的水呆呆地看著小度正播報的新聞,后悔著不該不回家過年。到2月時,在家待久無聊了,她開始跟著視頻學起了烹飪,可自己的廚藝天分并沒有想象的那么好,還是在深夜里吃著泡面看劇更適合自己。4月時,窗外的樹葉綠了,天空放晴了,她也終于能開心地去上班了。
年中時,在無數個只有小度的音樂陪伴的深夜,加班的她開始自我懷疑。沒了工作的她,打算離開這座大城市,就像窗外的樹葉離開樹一樣。但不甘心的她還是覺得堅持一下,也不知道是不是因為受了當時熱播的《三十而立》的影響。她為自己添置了更多的陪伴,決定再好好拼一把。最終,她成功做出了一個小蛋糕,也算是為2020年畫上了一個句號吧。
這支短片沒有配音,只有一扇傳遞時間流逝的窗,一個沒有露臉的人,一張擺著雜物的桌子,和幾句簡單的文案,卻能讓廣告外的我們不自覺地聯想到主人公當時的情緒和想法。因為,廣告中所呈現的這些事都能讓我們感同身受、引發共鳴——宅家、學習、加班、辭職、拼搏......這支短片里的主人公沒有露臉,反而更讓人有代入感。那個看著窗外的視角,就像自己的眼睛,我們在眼前這張桌上吃飯刷劇加班累倒。
窗外是有千萬人來來往往的大世界,窗內只是藏著自己喜怒哀樂的小家。這個小家或許很樸素,一張桌子上擺著書籍、香薰、小盆栽,窗戶上貼著寫有小目標的便利貼,還有一只小貓和一臺小度陪伴自己。這些小確幸填滿了這間屋子,也填滿了每個在大城市奮斗的年輕人的生活和心靈。
“一人、一屋、一年度”,這支短片中雖然呈現的東西很少也很簡單,但讓人感受到的情緒和共鳴卻很多很復雜。
標題的“一人、一屋、一年度”一語雙關,既呈現了一個普通人在一間屋子里度過的一年,也呈現了一年中,小度在這間屋子里如何陪伴一個人,以此來詮釋品牌 slogan“小度在家,陪伴在家”的含義。
此外,小度還邀請知名插畫師寂地為自己描繪了一組插畫,寂地溫暖的畫風描繪了有小度陪伴的四季美好。
春天里萬物蘇醒,
小懶蟲也該動起來做點事了
一個人的夏夜
聽著小度播放的抒情音樂,
放松了心情
金黃的秋天
通過小度和爸媽視頻,
表示收到了家里寄來的溫暖
飄雪的冬天
和愛人相擁看一個電影,
小度讓倆人湊得更近了
自今年品牌升級以來,小度始終在強調“陪伴”這一概念。無論是短片還是系列插畫,小度的產品一直放置在桌子的一角,并根據不同情節和場景呈現出了多樣的產品功能。在不同的時間和生活中,小度都自然地融入其中,成為了一個安靜的陪伴者。四季改變,但小度的陪伴一直不變。
看到這里,或許你已然明白也認可了小度的這支簡單卻溫暖的年度短片。這支年度短片不像一般意義上的年度短片那般恢宏,但它記錄了萬千普通人平凡的精彩。之所以小度要選擇這樣的方式,是因為它只想要傳遞出“小度在家,陪伴在家”的信念。
這支短片捕捉了大多數在大城市打拼的年輕人的生活日常,平淡的重復中又有著些許溫暖的小確幸。小度默默地立在桌子上,成為生活中的小確幸,一直陪伴著主人,就像這支年度短片一樣的安靜簡單。
小度想要帶給人們這樣一種無壓力的輕聲陪伴。
這支廣告按品牌產品的露出程度來說,已經能算是一直強植入的廣告了,但卻沒有違和感和不適感。
1月時,小度播放著疫情新聞;2月,小度播放著烘培教程視頻;4月,小度顯示著天氣氣溫;6月,小度播放著舒緩的音樂;8月,小度和主人深夜對話;9月,小度實時更新節氣壁紙;10月,小度推薦了熱播電視劇的海報......
在這無數個時刻,小度不再只是一個冰冷的人工智能機器,而是能給予陪伴的小度。
短片最后的小彩蛋,呈現出了真實的小度。它或許不能像電影里那般智能高效,但也是這些小不足,讓小度更具有真實感和親切感。連人工智能都沒法做到完美無缺,會犯小錯誤,會有做不到的事,你也不要太辛苦自己啦。
新的一年,再繼續加油吧!
*請認真填寫需求信息,我們會在24小時內與您取得聯系。