# Javascript and Animation Studies
## Community Statement
* It's less about Crafts but more about Creativty.
* Less about Coding but more about Thinking.
* Inspiration & Personal Heros
* https://taliacotton.com/
* https://compform.net/introduction/
* http://www.thegreeneyl.com/
* http://yhsong.com/
* https://yuinchien.com/
* https://antonandirene.com/
* https://studiodumbar.com/
* https://www.joycenho.com/
* http://zz-is.it/
* http://www.generative-gestaltung.de/2/
## Resources
https://developers.google.com/web
## JS libraries
* CSS Animation
* Anime.js
* JQuery
* Scroll Reveal
* Physical Engine
* Matter.js - tutorial - 欣葶
* https://www.youtube.com/watch?v=urR596FsU68&list=PLRqwX-V7Uu6bLh3T_4wtrmVHOrOEM1ig_&index=1
* 2D (HTML Canvas)
* Paper.js
* Pts.js – Creative Coding
* P5.js
* Sound
* Tone.js - 靜儀
* Data Viz
* D3.js - tutorial - 璦翎
* https://www.coursera.org/learn/information-visualization-programming-d3js
* 3D/WebGL
* Three.js - 怡萱
* http://test.domojyun.net/MEMO/3D/threejs.html
* https://ithelp.ithome.com.tw/articles/10192566
* Aframe.io (VR/AR)
* Machine Learning
* Ml5js
# Week1: HTML+CSS+JS
### HTML, CSS, JS
http://m105.nthu.edu.tw/~s105011127/spin/
### Environment
* Code: VSCode
* FileZilla: mxxx.nthu.edu.tw
### 進行方式
* 分周次講不同的js
* Care 設計的部分
* 不Care 程式太複雜的地方:資料結構或優化效能(除非電腦會燒起來)
* 不會因為你沒研究出來就生氣
### Hello Website
```html=
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<h1>This is a Heading</h1>
<p>This is a paragraph.</p>
</body>
</html>
```
### CSS 進來!
```css=
<link rel="stylesheet" href="styles.css">
```
### 編碼
```css=
@charset "utf-8";
<meta charset="utf-8">
```
### 字體
https://fonts.google.com/specimenTab?standard-styles
```css=
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Oswald:wght@335;432&display=swap" rel="stylesheet">
font-family: 'Oswald', sans-serif;
```
### CSS
https://www.w3schools.com/css/default.asp
### CSS Animation
```css=
animation: animaionName 1s infinite;
@keyframe{
0%{}
100%{}
}
```
### nth-child()
```css=
p:nth-child(odd){};
P:nth-child(even){};
```
### hover()
```css=
p:hover{};
```
### Jquery Library
```html=
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script src="???.js"></script>
```
### p5.js
```html=
<script src="https://cdn.jsdelivr.net/npm/p5@1.3.1/lib/p5.js"></script>
<script src="???.js"></script>
```
### 今天的code連結
> https://drive.google.com/file/d/1nxGW08DQHclUkEUemtYhCmSe7SmKGucX/view?usp=sharing
# Week2: CSS Advanced
### CSS Advanced
#### Box
![](https://i.imgur.com/61llFpM.png)
https://www.w3schools.com/css/css_border.asp
Intro
* CSS Borders
* CSS Lists
* CSS Position
* CSS z-index
* CSS Overflow
* CSS Float
* CSS Pseudo-classes (before, after)
https://w3c.hexschool.com/blog/5667df85
* CSS Navigation Bar
* CSS Dropdown
* CSS Website Layout
Advanced
* Rounded Corners
* Gradients
* Shadows
* Text Effects
* 2D Transforms
* 3D Transforms
* RWD Intro vs AWD
https://medium.com/@282714/%E4%B8%8D%E6%9C%83%E5%AF%ABcss%E4%B9%9F%E8%83%BD%E6%87%82-%E5%A6%82%E4%BD%95%E9%81%B8%E6%93%87rwd%E9%82%84%E6%98%AFawd-2b4057e92d4
* RWD Viewport
* RWD Grid View
* RWD Media Queries
* RWD Framework
## Sass
Sass syntax / Scss
![](https://i.imgur.com/TQGrJjt.png)
在VScode內有我們的好朋友:Live Sass Compiler
https://sass-lang.com/documentation/at-rules/function
#### Hello World
**css**
```css=
.nav{
background: #ccc;
}
.nav li {
display: inline-block;
}
.nav li a{
display: block;
padding: 15px;
text-decoration: none;
color: #000;
}
.nav li img{
width: 100%;
}
```
**sass**
```sass=
.nav
background: #ccc
li
display: inline-block
a
display: block
padding: 15px
text-decoration: none
color: #000
img
width: 100%
```
**scss**
```sass=
.nav{
background: #ccc;
li {
display: inline;
a {
display: block;
padding: 15px;
text-decoration: none;
color: #000;
}
img {
width: 100%;
}
}
}
```
# Week3: SCSS + JS Intro
SCSS is our good friend, who is a close neighbor to CSS, who is an annoying shit.
## Variable
**css**
```css=
body {
font: 100% Helvetica, sans-serif;
color: #333;
}
```
**sass**
```sass=
$font-stack: Helvetica, sans-serif
$primary-color: #333
body
font: 100% $font-stack
color: $primary-color
```
**scss**
```sass=
$font-stack: Helvetica, sans-serif;
$primary-color: #333;
body {
font: 100% $font-stack;
color: $primary-color;
}
```
## Function
除了變數之外,讓開發 Sass 更像在寫程式的特性就是 function 了,可以將重複使用的長度、大小計算等邏輯,抽象化成 function 的形式,如下面例子是使用 function 的 SCSS:
語法: `@function $var(args){ @return }`
`$var`為自定義變數,後綴加上一個以上的參數`args`,通常作為計算用途。
**scss**
```sass=
@function pow($base, $exponent) {
$result: 1;
@for $_ from 1 through $exponent {
$result: $result * $base;
}
@return $result;
}
.sidebar {
float: left;
margin-left: pow(4, 3) * 1px;
}
```
### for loop
語法: `@for` $var `from` Num1 `through/to` Num2
`$var` 可以自定義變數,每次回傳數字類型的結果。
`through` 包含Num2在內的範圍
`to` 不包含Num2在內,例如1 `to` 24只會回傳到23為止
```sass=
@for $i from 0 through 24 {
.flex_#{$i} {
flex: $i;
}
}
```
### each
語法: `@each` $var `in` Array
`$var`可以自定義變數,每次回傳Array對應的值。
Array 陣列,可以直接在`in`的後面接'icon_1', 'icon_2'...
或者直接另外定義變數存放:
```sass=
$iconSet: ['icon_1', 'icon_2', 'icon_3'];
```
**scss**
```sass=
$iconSet: ['icon_1', 'icon_2', 'icon_3'];
@each $currentIcon in $iconSet {
.icon_#{$currentIcon} {
background: url('../img/#{$currentIcon}.svg') no-repeat center;
}
}
```
**css**
```css=
/* 編譯後的結果 */
.icon_icon_1 {
background: url("../img/icon_1.svg") no-repeat center;
}
.icon_icon_2 {
background: url("../img/icon_2.svg") no-repeat center;
}
.icon_icon_3 {
background: url("../img/icon_3.svg") no-repeat center;
}
```
### if
語法: `@if` $var `==` value `(and, or)`(value2)
`==` 等於
`>` 大於
`>=` 大於或等於
`<` 小於
`<=` 小於或等於
`!=` 不等於
`and` 以及
`or` 或者
```sass=
@for $i from 0 through 3 {
.flex_#{$i} {
flex: $i;
@if $i == 0 {
height: 100%;
} @else if $i >= 2 {
color: #fff;
} @else if $i != 3 {
color: #333;
}
}
}
```
**css**
```css=
/* 編譯後的結果 */
.flex_0 {
flex: 0;
height: 100%; /* $i = 0 時加入的條件 */
color: #333; /* $i 不等於 3 時加入的條件 */
}
.flex_1 {
flex: 1;
color: #333; /* $i 不等於 3 時加入的條件 */
}
.flex_2 {
flex: 2;
color: #fff; /* $i 符合大於或等於 2 的條件 */
color: #333; /* $i 符合不等於 3 的條件 */
}
.flex_3 {
flex: 3;
color: #fff;
}
```
看得出來$i = 2時color被編譯了兩次結果對吧?
而瀏覽器會以最後一個結果為主,這就可能造成不是我們要的樣式覆蓋了正確的樣式,也會讓編譯資源佔據不少垃圾影響效能。
## Nesting
**scss**
```sass=
nav {
ul {
margin: 0;
padding: 0;
list-style: none;
}
li { display: inline-block; }
a {
display: block;
padding: 6px 12px;
text-decoration: none;
}
}
```
**css**
```css=
nav ul {
margin: 0;
padding: 0;
list-style: none;
}
nav li {
display: inline-block;
}
nav a {
display: block;
padding: 6px 12px;
text-decoration: none;
}
```
## Mixins
當有一段 CSS 設定經常性地被重複使用,甚至可以根據不同「參數」對應出相似的樣式,就可以將這段設定獨立寫成一個 mixin 方便取用,參考下面的例子:
**scss**
```sass=
@mixin square($size, $radius: 0) {
width: $size;
height: $size;
@if $radius != 0 {
border-radius: $radius;
}
}
.avatar {
@include square(100px, $radius: 4px);
}
.card {
@include square(300px, $radius: 2px);
}
```
**css**
```css=
.avatar {
width: 100px;
height: 100px;
border-radius: 4px;
}
.card {
width: 300px;
height: 300px;
border-radius: 2px;
}
```
## Extends
有一種狀況是當有一個選擇器需要包含另一個選擇器中的所有樣式,或是許多選擇器具有相同樣式時,為了避免要一直重寫同一組相同的 CSS 樣式,在 Sass 中我們可以使用 Extends 的寫法。
上面這段話稍微有點抽象,換句話說就是 Extends 可以將所有相同樣式的內容合併,直接舉個例子:
**scss**
```sass=
%message-shared {
border: 1px solid #ccc;
padding: 10px;
color: #333;
}
%equal-heights {
display: flex;
flex-wrap: wrap;
}
.message {
@extend %message-shared;
}
.success {
@extend %message-shared;
border-color: green;
}
.error {
@extend %message-shared;
border-color: red;
}
.warning {
@extend %message-shared;
border-color: yellow;
}
```
**css**
```css=
.warning, .error, .success, .message {
border: 1px solid #ccc;
padding: 10px;
color: #333;
}
.success {
border-color: green;
}
.error {
border-color: red;
}
.warning {
border-color: yellow;
}
```
## Flexbox
```css=
.container {
display: flex;
flex-direction: row; /* 預設值是row,代表橫向排列,column則是垂直 */
}
```
![](https://i.imgur.com/JSB4TiR.png)
### 利用mixin和extend的flexbox
**scss**
```sass=
.container {
width: 100%;
height: auto;
}
@mixin flexBox($direction) {
display: flex;
flex-direction: $direction;
}
@mixin flexAlign($alignItems, $justifyContent) {
align-items: $alignItems;
justify-content: $justifyContent;
}
.new-container {
@include flexBox(column);
@include flexAlign(flex-start, flex-start);
@extend .container;
}
```
**css**
```css=
.container, .new-container {
width: 100%;
height: auto;
}
.new-container {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;
}
```
## data-attribute
**html**
```html=
<div class="tab__container" data-panel-count="1">...</div>
```
而且你還試圖去Google了程式碼中的data-panel-count卻發現根本找不到任何解答對吧?正常,因為「data-」之後那串字都是我們工程師自己命名的你當然找不到!
data-attribute原意是HTML5中提供給開發人員做選擇器之類的用途,不僅是Javascript可以任意調用,CSS也一樣可以:
**CSS**
```css=
.container[data-width="10rem"] {
width: 10rem;
}
.container[data-inset="0.5rem"] {
box-sizing: border-box;
padding: 0.5rem;
}
```
**SASS: Function**
```sass=
@for $i form 0 through 20 {
/* #{} 的字符代表連接變數使用,{}中可以有運算式 */
[data-inset="#{$i * 0.1}rem"] {
padding: #{$i * 0.1}rem;
}
}
```
## CSS Grid
https://kanboo.github.io/2018/06/27/CSS-Grid/
## Interactivity
### DOM
文件物件模型 (DOM)
文件物件模型(Document Object Model, DOM)是 HTML、XML 和 SVG 文件的程式介面。它提供了一個文件(樹)的結構化表示法,並定義讓程式可以存取並改變文件架構、風格和內容的方法。DOM 提供了文件以擁有屬性與函式的節點與物件組成的結構化表示。節點也可以附加事件處理程序,一旦觸發事件就會執行處理程序。 本質上,它將網頁與腳本或程式語言連結在一起。
### Library
```html=
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script src="???.js"></script>
```
### Mouse X, Mouse Y in JS/CSS
### Variable & Constants:
```javascript=
var name= "John"; ///很爛不要用它
let lastName = 'Doe'; ///可以改動的值
const version= '1.3'; ///cannot be changed
```
### Mouse-x, Mouse-y
**HTML**
```html=
<div class="mover"></div>
```
**JS**
```javascript=
let root = document.documentElement;
root.addEventListener("mousemove", e => {
root.style.setProperty('--mouse-x', e.clientX + "px");
root.style.setProperty('--mouse-y', e.clientY + "px");
});
```
**SCSS**
```sass=
.mover {
width: 50px;
height: 50px;
background: red;
position: absolute;
left: var(--mouse-x);
top: var(--mouse-y);
}
```
### Mouse Background
**HTML**
```html=
<div class="module" id="module">
</div>
```
**SCSS**
```sass=
.module {
width: 300px;
height: 300px;
border: 1px solid white;
background-image: url(https://images.unsplash.com/photo-1499162526249-f5b8b9ba9923?ixlib=rb-0.3.5&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ&s=865bf5c0b77ceb22e88de9fd41c5a671);
background-size: 1000px;
}
body {
height: 100vh;
margin: 0;
display: flex;
justify-content: center;
align-items: center;
background: #000;
}
```
**JS**
```javascript=
$(document).ready(function(){
const el = document.querySelector("#module");
el.addEventListener("mousemove", (e) => {
el.style.backgroundPositionX = -e.offsetX + "px";
el.style.backgroundPositionY = -e.offsetY + "px";
});
});
```
![](https://i.imgur.com/tvvEHkO.png)
### 上傳FileZilla
### Further Studies
https://css-tricks.com/lets-make-one-of-those-fancy-scrolling-animations-used-on-apple-product-pages/?fbclid=IwAR38t8JjS-qL4gHKuEyYTiKLjNFhSulale6XJliH5LpW1Z9ky8AGRBlcnBA
https://css-tricks.com/adding-particle-effects-to-dom-elements-with-canvas/?fbclid=IwAR3kbVZ99KEl_eYqCkSFL8jsUFgTJQEApgN0mZbuOPAJ-QZfUx9uPSxnjis
### Next Week
http://www.generative-gestaltung.de/
# Week4: Animation Magic!
http://m105.nthu.edu.tw/~s105011127/FreeFridayForum/
We will review several ways to acheive the effect we want using CSS, JS and extended libraries.
## CSS vs JS vs Jquery vs JS libraries
HTML Boilerplate
```html=
<link rel="stylesheet" href="main.css">
<script src="script.js"></script>
```
### CSS Transition +JS
**html**
```html=
<div class="box"></div>
```
**scss**
```scss=
.box{
width:100px;
height: 100px;
background: #00FF00;
transform: translate(0,0);
transition: transform 500ms;
}
.move{
transform:translate(100px, 100px);
}
```
**js**
```javascript=
var box = document.querySelector('.box');
box.addEventListener('click', function() {
box.classList.toggle('move');
});
```
**import**
```html=
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
```
### CSS Animation
**SASS**
```CSS=
animation: movingBox 1300ms infinite alternate;
@keyframes movingBox {
0% {
transform: translate(0, 0);
opacity: 0.3;}
25% {
opacity: 0.9;}
50% {
transform: translate(100px, 100px);
opacity: 0.2;}
100% {
transform: translate(30px, 30px);
opacity: 0.8;}
}
```
## JS Manipulating CSS
```javascript=
var target = document.querySelector('.box');
var player = target.animate([
{transform: 'translate(0)'},
{transform: 'translate(100px, 100px)'}
], 500);
player.addEventListener('finish', function() {
target.style.transform = 'translate(100px, 100px)';
});
```
## Only JS
```javascript=
var id = null;
var box = document.querySelector('.box');
box.addEventListener('click', function () {
myMove();
});
function myMove() {
var elem = document.querySelector(".box");
var pos = 0;
clearInterval(id);
id = setInterval(frame, 10);
function frame() {
if (pos == 100) {
clearInterval(id);
} else {
pos++;
elem.style.top = pos + 'px';
elem.style.left = pos + 'px';
}
}
}
```
:::success
以下是我們真正的好朋友!
:::
## Best Friends 1: CSS library
https://animate.style/
import
```html=
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>
```
easy use
**HTML**
```html=
<div class="animate__animated animate__bounce"></div>
```
**CSS**
```css=
.box{
animation: bounce 2s;
}
```
```javascript=
const animateCSS = (element, animation, prefix = 'animate__') =>
// We create a Promise and return it
new Promise((resolve, reject) => {
const animationName = `${prefix}${animation}`;
const node = document.querySelector(element);
node.classList.add(`${prefix}animated`, animationName);
// When the animation ends, we clean the classes and resolve the Promise
function handleAnimationEnd(event) {
event.stopPropagation();
node.classList.remove(`${prefix}animated`, animationName);
resolve('Animation ended');
}
node.addEventListener('animationend', handleAnimationEnd, {
once: true
});
});
```
```javascript=
animateCSS('.box', 'bounce');
```
|屬性 |說明|
|---|---|
|animation-name| 動畫名稱|
|animation-duration| 動畫持續時間,預設 0,單位 s 或 ms。|
|animation-delay| 動畫延遲播放時間,預設 0,單位 s 或 ms。|
|animation-iteration-count| 動畫播放次數,預設 1。其他還有 infinite...|
|animation-timing-function| 動畫加速度函式,預設 ease。其他還有: linear、ease-in、ease-out、ease-in-out、step-start、step-end、steps(int,start/end)、cubic-bezier(n,n,n,n)。|
|animation-direction| 動畫播放方向,預設 normal。其他還有 reverse、alternate、alternate-reverse。|
|animation-fill-mode| 動畫播放前後模式,預設 none。其他還有 forwards、backwards、both。|
animation-play-state| 動畫播放或暫停狀態,預設 running。其他還有 paused。|
## Best Friend 2: AOJ
除了滑鼠觸發(上周我們有做過)之外,另一個網頁常見的觸發方式,就是Scroll,想不想做出這種效果:https://www.youtube.com/watch?v=ptfUwPJbGlQ
https://michalsnik.github.io/aos/
## Visualization Options
SVG
* https://codepen.io/aurer/pen/jEGbA
* https://codepen.io/ghepting/pen/xnezB
教學
* https://blog.techbridge.cc/2019/11/06/svg-animation-in-10mins/?fbclid=IwAR3n3WQ3bO1LkbjXWgI2LHo_bS1iB_tNnZJhxl3n2t19JaSfrGE2ahsHDfw
Canvas
* https://codepen.io/ge1doot/details/vOYOVz
* https://codepen.io/soulwire/details/Ffvlo
WebGL
* https://epok.tech/work/tendrils/
* https://codepen.io/shubniggurath/pen/XWpYpON
## P5 is your best CANVAS friend
```html=
<script src="https://cdn.jsdelivr.net/npm/p5@1.3.1/lib/p5.js"></script>
```
## SVG and Friends
# Week5: Animation & Your Friend Javascript
## JS Intros
## Statement & Variable
```javascript=
let quantity = 3;
let number = 0.75;
let string = 'Hi, Ivy!';
let boolean = true;
```
## Change Content
**html**
```html=
<h1>Elderflower</h1>
<div id="content">
<h2>Custom Signage</h2>
<div id="cost">Cost: $5 per tile</div>
</div>
```
**scss**
```scss=
h1{
color: red;
}
#cost{
color: blue;
}
```
**js**
```javascript=
let price;
let quantity;
let total;
price = 5;
quantity = 14;
total = price*quantity;
let el = document.getElementById('cost');
el.textContent = '$' + total;
```
## Change Content with HTML
**js**
```javascript=
let message = "<p>I don't know what this is<p>"
el.innerHTML = message;
```
## 關於變數的規則
* 需要是字母、$或_開始,絕對不能是數字開始
* 可以包含_但不能包含-或.
* 不能是keywords or reversed words
* 有大小寫之分
* 通常follow Camal Case (firstName, lastNameIs)
## Change Content with Array
**js**
```javascript=
let message;
message = ['dog', 'cat', 'shit']
el.textContent = message[0];
let message = new Array('dog', 'cat', 'shit');
```
**js**
```javascript=
let message = ['dog', 'cat', 'shit'];
message[2] = 'cow' + 'piggy';
```
## Function
```javascript=
function updateMessage(){
el.textContent = message[2];
}
updateMessage();
```
## Object
```javascript=
let hotel={
name: 'Royal',
rooms: 40,
booked: 25,
gym: true,
roomTypes: ['twin', 'double', 'suite'];
}
```
---
https://happycoding.io/tutorials/p5js/web-dev?fbclid=IwAR2EHEsXwpHmZZsB9Q3Mqi5QZEYyMB_sgnssFMQJFgmkSqztzll2YyZ4q2I
Some of the tutorials are from coursera NYU: Information Visualization Programming with D3.js
### Operators
```javascript=
let result = 3+2; ///+*/-
result+=4; ///result=result+4;
let name = firstName + lastName;
let result = 3>=2;
let isEqual = months === 4;
```
### Function
```javascript=
function add(v1,v2){
return v1+v2
}
const add = (v1, v2) => v1+v2;
let result = add(5,3);
```
### Conditional
```javascript=
let color;
if(v1===10){
color="blue"
}else{
color="red"
}
let color=v1===10?"blue":"red";
```
### Loop
```javascript=
for(let i=1; i<21; i+=1){
console.log(i)
}
let i=1
while(i<21){
console.log(i)
i+=1;
if(i>=21)
break;
}
```
### Intro to Java
```javascript=
const KG_PER_KILO = 0.45;
const INCH_TO_METER = 0.0254;
let Name = 'John';
let Weight = 196;
let Height = 90;
let client = {
Name : 'Jane',
Weight : 196,
Height : 90
}
function getBMI(client){
let weightInKg = client.Weight * KG_PER_KILO;
let heightInMt = client.Height * INCH_TO_METER;
let BMI = weightInKg / heightInMt / heightInMt;
return BMI
}
function getBMI(client){
let weightInKg = Weight * KG_PER_KILO;
let heightInMt = Height * INCH_TO_METER;
let BMI = weightInKg / heightInMt / heightInMt;
return BMI
}
document.write(client.Name + ":" + getBMI(client));
```
### Control Structures
```javascript=
let clients =[
{
Name : 'John',
Weight : 196,
Height : 90
},
{
Name : 'Jane',
Weight : 186,
Height : 70
},
{
Name : 'James',
Weight : 206,
Height : 60
}
]
for(let i=0; i<clients.length; i++){
let client = clients[i];
let bmi = getBMI(client)
if(bmi> 25){
document.write(client.Name + ":" + bmi + "</br>")
}
}
```
# Week6: D3.js
### 流程
1. D3簡介
2. 案例分享
3. 視覺化步驟
4. Select介紹
5. 內容更改介紹
7. 新增/移除元素介紹
9. 屬性更改介紹
(恭喜你已經學完D3基本操作了!)
11. 長條圖實作
### D3簡介
* [程式前沿](https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/635116/)
### 實作案例
* [Best D3 Websites](https://www.awwwards.com/sites/daesk)
* [Globalance World (私心喜歡的應用)](https://fe.globalanceworld.com/)
吃D3!
```html=
<script src="https://d3js.org/d3.v4.min.js"></script>
```
### Visualization Steps & D3 APIs
##### **1. Transform Data**
`d3.cross`: cross- multiplication over two collctions
`d3.max`: maximum value in a field
##### **2. Map Data to Image Space**
`d3.scaleLinear`: maps linearly between the two values
`d3.scaleTime`: helps you to work with time values
##### **3. Compute Layouts and Paths**
`d3.path`: drawing maps, line chart
`d3.treemap`: treemap
##### **4. Draw the chart**
`d3.select`: select things
`d3.append`: add new elements
### D3 Selection
D3 selection is a API that we're going to use, to select elements on our HTML page.
```html=
<body>
<div>
<h1>Title</h1>
<button></button>
<button></button>
</div>
</body>
```
**Select first element**
```javascript=
d3.select(selector)
d3.select("p")
d3.select("#dog")
d3.select("p")
.select(".main")
let selection = d3
.select("p")
.select(".main")
```
**Select All elements**
```javascript=
let selection = d3
.selectAll("p")
.selectAll(".main")
```
Return with D3 wrapper, able to use other APIs of the three on top of it
### D3 Changing Content
#### Get vs Set
```javascript=
.select("")
.method() ///get
.method(value) ///set
```
#### Get
```javascript=
let x = d3.select("p").text()
```
#### Set
```javascript=
d3.select("p").text("this is the content")
d3.select("p").html("This <b>contetn</b>")
```
#### Onclick
**html**
```html=
<p class="paragraph">This is an example paragraph></p>
<button onclick="change1()">Change First</button>
<button onclick="change2()">Change All</button>
<button onclick="change3()">Change html</button>
<button onclick="change4()">Change All</button>
```
**javascript**
```javascript=
function change1(){
let d = d3.select(".paragraph")
d.text("New Text")
}
function change2(){
d3.selectAll("p").text("New Text 2")
}
function change3(){
d3.selectAll("p").html("<b>bold</b> normal")
}
function change4(){
d3.select("p").text("<b>bold</b> normal")
}
```
### Adding and Removing Elements
#### API|selection.append (Add Elements)
###### Syntax: 獲得空元素
```html=
selection
.append(tag)
```
###### Syntax: 利用.text .html 對內容進行更動
```html=
d3.select('ul')
.append('li')
.text('Item4')
```
###### result
```html=
<ul>
<li>Item 1<li>
<li>Item 2<li>
<li>Item 3<li>
<li>Item 4<li> #新增項
</ul>
```
#### API|selection.remove (Remove Elements)
select element you want to remove directly
否則會把整個 < ul > 刪掉,使得其他 button 失效
###### Syntax
```html=
selection
.remove()
```
###### example: selectAll
```html=
d3.selectAll('li')
.remove()
```
```html=
<ul>
</ul>
```
###### example: select
```html=
d3.select('li')
.remove()
```
```html=
<ul>
<li>Item 2<li>
<li>Item 3<li>
<li>Item 4<li>
</ul>
```
#### css小複習
```html=
Attributes <img src='logo.png' />
Style <p style='color:red' />
```
#### API|selection.attr
###### Syntax
```html=
selection
.attr(attribute, value)
```
###### example
```html=
d3.select('img')
.attr('src', 'newLogo.png')
```
#### API|selection.style
###### Syntax
```html=
selection
.style(property, value)
```
###### example
```html=
d3.select('p')
.style('color', 'red') #可以直接改動 property
```
### 長條圖實作
###### index.html
```html=
<!DOCTYPE html>
<html>
<head>
<title>D3 Pratice</title>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css">
</head>
<body>
</body>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
var title = "Comments on Posts";
d3.select("body")
.append("h3")
.text(title);
d3.csv('https://raw.githubusercontent.com/sdaityari/my_git_project/master/posts.csv', d3.autoType).then(function (data) {
d3.select("body")
.selectAll("div")
.data(data)
.enter()
.append("div")
.style("width", function(d) { return d.amount * 40 + "px"; })
.style("height", "15px");
});
</script>
</html>
```
###### css吃進來
```css=
body {
background-color: #3c3c3c;
color: #cfcfcf;
}
div {
line-height: 15px;
margin-bottom: 3px;
background-color: grey;
text-align: right;
padding-right: 5px;
font-size: 10px;
color: #cfcfcf;
}
```
# Week7: Three.js
### 首先
先測試自己的瀏覽器可不可以跑WebGl
https://get.webgl.org/
### 用法
要在螢幕上顯示 3D 圖形,在 Three.js 中需要以下的基本元素:
* 場景(Scene):供其他元素設置的空間。
* 攝影機(Camera):在場景中建立觀察點,並確定觀察方向、角度。
* 物體(Objects):在場景中添加被觀察的物體。
* 光源(Light):在場景中用來照亮物體的光。
* 渲染器(Renderer):將所要呈現的場景渲染到畫面上。
## 實作一
##### 1. 建立場景、攝影機、渲染器
```html=
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
// 設定渲染器渲染範圍以及背景顏色
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.setClearColor(new THREE.Color('rgb(255, 255, 255)'))
//將渲染器append到body裡
document.body.appendChild( renderer.domElement );
```
##### 2. 建立物件(mesh)
Object根據構成方式分成Mesh、Points
而Object具有Geometry、Material等特質可以操作
```html=
var geometry = new THREE.BoxGeometry( 1, 1, 1 );
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
```
##### 3. 建立材質
可調整像是顏色(color)、紋理(texture)、透明度(opacity)等數值。其中有些材質屬性能對光源產生反應,像是發光度(shininess)、鏡面反射程度(specular)等等,會決定物體會像金屬或像塑膠。
```html=
//方法1:指定內建的材質
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
//方法2:把材質貼圖mapping到物件上
const texture = new THREE.TextureLoader().load( 'textures/crate.gif' );
const geometry = new THREE.BoxGeometry( 200, 200, 200 );
const material = new THREE.MeshBasicMaterial( { map: texture } );
```
##### 4. 調整攝影機
```html=
camera = new THREE.PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
0.1,
100
)
camera.position.set(10, 10, 10) // 相機位置
camera.lookAt(scene.position) // 相機焦點
````
相機可以當作是一個觀察點,決定了我們從哪個位置、方向、角度來觀察場景中的畫面,在 Three.js 中主要有兩種比較常用的[相機](https://dezchuang.github.io/ironman-three.js/day02_threeBasic/bothCamera/index.html)。(可點進去按右上角的switchCamera來切換相機體驗差異。)
![](https://i.imgur.com/9tdL8HY.png)
* 透視投影相機(PerspectiveCamera)
THREE.PerspectiveCamera(fov, aspect, near, far);
* 正交投影相機(OrthographicCamera)
THREE.OrthographicCamera(left, right, top, bottom, near, far);
關於攝影機的補充名詞
* 視角(fov, field of view):又稱為視野、視場,指的是我們能從畫面上看到的視野範圍,一般在遊戲中會設定在 60 ~ 90 度。
* 畫面寬高比(aspect):渲染結果的畫面比例,一般都是使用 window.innerWidth / window.innerHeight 。
* 近面距離(near):從距離相機多近的地方開始渲染,一般推薦使用 0.1。
* 遠面距離(far):相機能看得多遠,一般推薦使用 1000,可視需求調整,設置過大會影響效能。
* camera.lookAt:指相機會盯著何處,一般靜止觀察的相機都是設定為 camera.lookAt(scene.position),就是觀察場景固定的位置。但若今天你要讓相機動態追蹤某個物體,那你可以在渲染時改變 camera.lookeAt 中的參數為特定物體的某個基準座標,可以參考[官網範例](https://threejs.org/examples/?q=lookat#misc_lookat)。
##### 5. 加入燈光
打光在3D世界中是個超超超重要的大學問!
不需光源就被渲染在畫面上的材質:MeshBasicMaterial、MeshNormalMaterial
能與光源互動的材質:MeshLambertMaterial、MeshPhongMaterial 。
在 Three.js 中提供了包括環境光(AmbientLight)、點光源(PointLight)、 聚光燈 (SpotLight)、方向光(DirectionalLight)、半球光(HemisphereLight)等多種光源。
```html=
let pointLight = new THREE.PointLight(0xffffff)
pointLight.position.set(10, 10, -10)
scene.add(pointLight)
```
##### 6. 呼叫 renderer.render 繪製場景。
在 Three.js 中多種渲染器可以選擇(WebGLRender、CanvasRenderer、SVGRenderer 等等),但一般而言都是使用 WebGLRenderer,因為它支援較多功能,像是材質、陰影等等,在後面的程式碼中會看到常透過渲染器來設定預設背景顏色、場景尺寸、陰影效果等。
小補充:three.js也是使用**[requestAnimationFrame](https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/dev-guides/hh920765(v=vs.85)?redirectedfrom=MSDN)** 來進行動畫幀數的配置
完整的程式碼:
```htmlembedded=
//html
<script src="https://threejs.org/build/three.js"></script>
//js
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor(new THREE.Color('rgb(255, 255, 255)'));
document.body.appendChild( renderer.domElement );
var geometry = new THREE.BoxGeometry( 1, 1, 1 );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 5;
let pointLight = new THREE.PointLight(0xffffff)
pointLight.position.set(20, 10, 10)
scene.add(pointLight)
var animate = function () {
requestAnimationFrame( animate );
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render( scene, camera );
};
animate();
```
## 實作二
### 滑鼠控制3D物件
```html=
document.addEventListener( 'mousemove', onDocumentMouseMove );
```
# Week8: Matter.js
因為筆記長度限制,開了新筆記在[這裡](https://hackmd.io/ti1kH6o3THCH8d-iLukNuQ?view)