這篇主要講一下入門的2D canvas、console的應用、還有感覺很像UX的想法(?)

Day 8

  • Canvas
  1. 為何canvas要用JS寫? 規定,html的canvas元素只是個容器,內容必須用JS繪圖。
  2. canvas 基礎 繪圖原點是(0,0),X軸往右為正,Y軸往下為正,單位是px。
<canvas id="mycanvas"></canvas>

<script>
const canvas = document.getElementById("mycanvas");
const ctx = canvas.getContext("2d");
// 設定畫布寬高
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

ctx.beginPath(); // 開始畫
ctx.arc(80,70,60,-0.5*Math.PI,1*Math.PI); // 以(80,70)為中心點畫從-90度到180度且半徑為60的圓
ctx.fillStyle = "#666"; // 類似background-color
ctx.fill(); // 設定好顏色之後還要執行填滿
ctx.strokeStyle = "#fa0"; // 類似border-color
ctx.stroke(); // 邊框同樣要執行

ctx.fillStyle = "red"; // 重新指定顏色
ctx.strokeStyle = "green"; 
ctx.strokeRect(10,10,25,25); //從(10,10)畫一個寬高都是25的正方形邊框
ctx.fillRect(40,30,50,50); //從(40,30)畫一個寬高都是50的正方形
ctx.clearRect(45,35,20,20); //從(45,35)清空一塊寬高都是20的正方形

ctx.beginPath(); 
ctx.moveTo(50,75); // 移動原點 
ctx.arcTo(100,75,100,150,30); // 在兩個切線中間畫弧線
ctx.lineTo(125,30); //畫一條線到指定位置
ctx.closePath(); // 自動閉合
ctx.fillStyle = "blue"; 
ctx.fill(); 
ctx.stroke();

</script>

重疊效果 Context2D.globalCompositeOperation

  1. 幫自己畫網格,方便繪製
<canvas id="mycanvas"></canvas>

<style>
html, body {
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

canvas {
  border: 3px solid #000;
}
</style>

<script>
const canvas = document.getElementById("mycanvas");
const ctx = canvas.getContext("2d");
canvas.width = 500;
canvas.height = 500;

function draw() {
  ctx.beginPath();
  for(let i = 0; i < 10; i++){
    let pos = i * 50;
    ctx.moveTo(pos, 0);
    ctx.lineTo(pos, 500);
    ctx.fillText(pos, pos, 10);

    ctx.moveTo(0, pos);
    ctx.lineTo(500, pos);
    ctx.fillText(pos, 10, pos);
  };
  ctx.strokeStyle = "rgba(0, 0, 0, 0.4)";
  ctx.stroke();
};

draw();
</script>

codepen連結

Day 9

總算知道在Facebook開F12裡的警告訊息和一些工具在開發版本的提示訊息是怎麼做的了。

  • console
console.clear(); // 清空console 通常放在最前面

console.log('hello'); // 普普通通的log,除錯好幫手

console.log('Hello %s!', 'Tom'); // %s 其他語言也有的佔位符

console.log('%ctry some CSS', 'font-size:50px; color: red;'); // %c 套用CSS

console.warn('Just warning for you, surprise!!'); //黃色警告訊息

console.error('Give you some error ~'); //紅色錯誤訊息

console.info('It is time to feed fish.'); // 提示訊息,不知道為啥沒看到藍色icon

console.assert(false, 'Something wrong! Find it or die'); // 前面放Boolean,可用條件判斷,false的話會跳出錯誤訊息

const dom_p = document.querySelector('p');
console.log(dom_p);
console.dir(dom_p); // 顯示DOM節點的元素

console.count('num');
console.count('num'); //  數出指定的Label被count幾次,平常可以用來數事件觸發次數
const dogs = [{
  name: 'Snickers',
  age: 2
}, {
  name: 'hugo',
  age: 8
}];

console.table(dogs); // 以Table的形式印出陣列或物件

dogs.forEach(dog=>{
  console.group(`${dog.name}`); // 以名字為群組依據
  console.log(`This is ${dog.name}`);
  console.log(`${dog.name} is ${dog.age} years old`);
  console.log(`${dog.name} look like ${dog.age * 3} years old`);
  console.groupEnd(`${dog.name}`);
});

console.time('Fetching data'); // 開始計時,注意開始和結束的名字要一樣
fetch('https://randomuser.me/api/')
  .then(data => data.json())
  .then(data => {
    console.timeEnd('Fetching data'); // 完成,計時停止,印出計時結果
    console.log(data);
  });

Day 10

這一天的主題是"Hold Shift to Check Multiple Checkboxes",完美重現了shift的缺點,如果在沒有任何一個被勾選的情況下按著shift勾第二個,會把第二個和它後面全部選起來,總而言之改了很久,總算弄成比較直覺性的選取。

  • 使用情境:
  1. 想要選取1~3,按/沒按shift,選取1或3,再選另一個
  2. 還想選5~8,按/沒按shift,選取5或8,再選另一個
  3. 不要7~8,按著shift選7
  4. 不要2~3,按著shift選2
  • 這四個步驟已經暴露出可能令人不滿的情況,分別是:
  1. 第二步按著shift的情況下,為什麼不是從4到被選的6中間都選起來呢?
  2. 第四步執行後會發現,為什麼2以下都被清空了?

第一個讓人不滿的情況的原因是因為,我的作法主要解決了知道這個功能怎麼使用的人,可以正確的在第一步做到從1到5選取,因為是以1為起點,可以直覺地在不想要4和5的情況下按著shift選4,表示以4為起點後面都不要,等到下次再度使用時,可能是幾秒後也可能是幾分鐘後,一樣可以從第一個步驟開始,選取從起點到想要的位置。

第二個讓人不滿的情況則是因為,為了讓刪除的起點不會干擾到第一步設定的起點,所以統一做從上至下的刪除。

其實共通的原因是,第一步的選取給人一種選取群組的錯覺,不過世上沒有完美的解法,暫時就先這樣了。

其他

解構賦值 [a,b] = [x, y]

//基本用法
const [a, b] = [1, 2] // a = 1, b = 2

//先宣告後指定值,要用let才行
let a, b
[a, b] = [1, 2]

// 交換值
let a = 1, b = 2;
[b, a] = [a, b] // a = 2, b = 1

// 略過某些值
const [a, , b] = [1, 2, 3] // a = 1, b = 3

// 其餘運算
const [a, ...b] = [1, 2, 3] // a = 1, b = [2,3]

// 失敗保護
const [, , , a, b] = [1, 2, 3] // a = undefined, b = undefined

// 多維複雜陣列
const [a, [b, [c, d]]] = [1, [2, [[[3, 4], 5], 6]]] // c = [[3, 4], 5]

// 字串
const str = "hello";
const [a, b, c, d, e] = str; // [h, e, l, l o]