iT邦幫忙

0

【前端動手玩創意】卡片製作,才不是!是卡片製作器!(10)

  • 分享至 

  • xImage
  •  

目錄

【前端動手玩創意】等待的轉圈圈效果 (1)
【前端動手玩創意】google五星評分的星星(2)
【前端動手玩創意】CSS-3D卡片翻轉效果(3) (今天難度頗高,想挑戰再進來!)
【前端動手玩創意】一句CSS做出好看的hero section!(4)
【前端動手玩創意】創造一個Skill bar(5)
【前端動手玩創意】遮蔽廣告(D卡未登入)腳本、自定義新增名單(6)
【前端動手玩創意】前端canvas截圖的招式!竟然有三招,可存成SVG或PNG (7)
【前端動手玩創意】讓你的PDF檔案更難被抓取(8)
【前端動手玩創意】哇操!你敢信?花式寫todo-list,body裡面一行都沒有也能搞?(9)
【前端動手玩創意】卡片製作,才不是!是卡片製作器!(10)

前情提要

常常看到好看的卡片效果,今天我們就來寫一個hero section吧!
但是……等一下什麼!你說你已經看到標題!
沒錯!已經來到前端動手玩創意系列的第十篇,我們累積了那麼多,特別的第十篇才不要帶你寫「卡片製作」,
我們要來搞一個card maker,呼應了大前端時代模組化的風格(๑ • ‿ • ๑ )。

到底什麼是製作你的製作呢?我們來看看效果:

效果預覽

沒錯就是這樣子,可以輸入圖片網址、讓人看不懂的日文(我也不懂那啥意思XD)
就可以跳出一張很有感覺的hero section!
甚至還寫了調整圖片的移動軸:

還可以下載!?這真的是太讚了,完全就是實現動手玩創意的絕佳精神呀~~

程式碼內容

<!DOCTYPE html>
<html>
  <head>
    <title>Card Maker</title>
    <style>
      body {
        display: flex;
        flex-direction: row;
      }

      .input-container {
        display: flex;
        flex-direction: column;
        margin-right: 20px;
      }

      .input-container label {
        margin-bottom: 10px;
      }

      .card-container {
        position: relative;
        width: 600px;
        height: 600px;
        margin-right: 20px;
      }

      .card-container canvas {
        position: absolute;
        top: 0;
        left: 0;
      }

      .download-button {
        margin-top: 10px;
      }

      .ui-panel {
        display: flex;
        flex-direction: column;
      }

      .ui-panel label {
        margin-bottom: 10px;
      }

      .ui-panel input[type="range"] {
        margin-bottom: 20px;
      }

      .hero-image {
        position: relative;
        width: 100%;
        height: 100%;
        background-size: cover;
        background-position: center;
      }

      .hero-text {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        text-align: center;
        color: white;
      }
    </style>
  </head>
  <body>
    <div class="input-container">
      <label for="image-input">Image URL:</label>
      <input type="text" id="image-input" />
      <label for="text-input">Text:</label>
      <input type="text" id="text-input0" />
      <input type="text" id="text-input" />
      <button id="confirm-button">Confirm</button>
    </div>

    <div class="card-container">
      <div class="hero-image">
        <div class="hero-text">
          <h1 id="card-title"></h1>
          <p id="card-text"></p>
        </div>
      </div>

      <div class="ui-panel">
        <label for="brightness-slider">亮度</label>
        <input
          type="range"
          id="brightness-slider"
          min="-1"
          max="1"
          value="0"
          step="0.1"
        />

        <label for="saturation-slider">飽和度</label>
        <input
          type="range"
          id="saturation-slider"
          min="-1"
          max="1"
          value="0"
          step="0.1"
        />

        <label for="size-slider">大小</label>
        <input
          type="range"
          id="size-slider"
          min="0.5"
          max="2"
          value="1"
          step="0.1"
        />
      </div>

      <button class="download-button" id="download-button">Download</button>

      <canvas id="card-canvas"></canvas>
    </div>

    <script>
      const imageInput = document.getElementById("image-input");
      const textInput = document.getElementById("text-input");
      const textInput0 = document.getElementById("text-input0");
      const confirmButton = document.getElementById("confirm-button");
      const cardTitle = document.getElementById("card-title");
      const cardText = document.getElementById("card-text");
      const downloadButton = document.getElementById("download-button");
      const cardCanvas = document.getElementById("card-canvas");

      confirmButton.addEventListener("click", () => {
        // Update the card title and text
        cardTitle.innerText = textInput0.value;
        cardText.innerText = textInput.value;

        // Update the hero image background
        const imageUrl = imageInput.value;
        const heroImage = document.querySelector(".hero-image");
        heroImage.style.backgroundImage = `linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url("${imageUrl}")`;

        // Generate the card image
        const cardImage = new Image();

        cardImage.onload = () => {
          // Get the canvas context and set its dimensions
const ctx = cardCanvas.getContext('2d');
          const canvasWidth = (cardCanvas.width =
            heroImage.clientWidth * parseFloat(sizeSlider.value));
          const canvasHeight = (cardCanvas.height =
            heroImage.clientHeight * parseFloat(sizeSlider.value));

          // Draw the hero image onto the canvas
ctx.drawImage(heroImage, 0, 0, cardCanvas.width, cardCanvas.height);


          // Apply brightness and saturation filters to the canvas
          applyFilters(
            context,
            parseFloat(brightnessSlider.value),
            parseFloat(saturationSlider.value)
          );

          // Update the download button href attribute with the canvas data URL
          downloadButton.href = cardCanvas.toDataURL("image/png");
        };
      });

      function applyFilters(context, brightness, saturation) {
        // Convert brightness and saturation values to filter functions
        const brightnessFilter = createBrightnessFilter(brightness);
        const saturationFilter = createSaturationFilter(saturation);

        // Apply the filters to the canvas
        context.filter = `${brightnessFilter} ${saturationFilter}`;
        context.drawImage(cardCanvas, 0, 0);
        context.filter = "none";
      }

      function createBrightnessFilter(value) {
        // Use a matrix filter to adjust brightness
        const brightnessMatrix = [
          1,
          0,
          0,
          0,
          value,
          0,
          1,
          0,
          0,
          value,
          0,
          0,
          1,
          0,
          value,
          0,
          0,
          0,
          1,
          0,
        ];

        return `brightness(${value})`;
      }

      function createSaturationFilter(value) {
        // Use a matrix filter to adjust saturation
        const saturationMatrix = [
          0.3086 * (1 - value) + value,
          0.6094 * (1 - value),
          0.082 * (1 - value),
          0,
          0,
          0.3086 * (1 - value),
          0.6094 * (1 - value) + value,
          0.082 * (1 - value),
          0,
          0,
          0.3086 * (1 - value),
          0.6094 * (1 - value),
          0.082 * (1 - value) + value,
          0,
          0,
          0,
          0,
          0,
          1,
          0,
        ];

        return `saturate(${value})`;
      }

      const brightnessSlider = document.getElementById("brightness-slider");
      const saturationSlider = document.getElementById("saturation-slider");
      const sizeSlider = document.getElementById("size-slider");

      brightnessSlider.addEventListener("input", () => {
        applyFilters(
          cardCanvas.getContext("2d"),
          parseFloat(brightnessSlider.value),
          parseFloat(saturationSlider.value)
        );
      });

      saturationSlider.addEventListener("input", () => {
        applyFilters(
          cardCanvas.getContext("2d"),
          parseFloat(brightnessSlider.value),
          parseFloat(saturationSlider.value)
        );
      });

      sizeSlider.addEventListener("input", () => {
        cardCanvas.width = heroImage.clientWidth * parseFloat(sizeSlider.value);
        cardCanvas.height =
          heroImage.clientHeight * parseFloat(sizeSlider.value);
        applyFilters(
          cardCanvas.getContext("2d"),
          parseFloat(brightnessSlider.value),
          parseFloat(saturationSlider.value)
        );
      });
      
      const image = document.querySelector('.hero-image');

brightnessSlider.addEventListener('change', () => {
  image.style.filter = `brightness(${brightnessSlider.value}) saturate(${saturationSlider.value})`;
});

saturationSlider.addEventListener('change', () => {
  image.style.filter = `brightness(${brightnessSlider.value}) saturate(${saturationSlider.value})`;
});

sizeSlider.addEventListener('change', () => {
  image.style.transform = `scale(${sizeSlider.value})`;
});
const canvas = document.getElementById('card-canvas');

     downloadButton.addEventListener('click', () => {
  const link = document.createElement('a');
  link.download = 'image.png';
  link.href = canvas.toDataURL();
  link.click();
});
    </script>
  </body>
</html>

觀念筆記

目前代碼的部分canvas還沒轉好,晚點應該會修正為用html2canvas套件來抓。
不過可以先玩玩看卡片製作的部分唷!

心得

很有趣的小項目,其實學前端什麼專業知識、構造函數、模組那些都太無聊了,
講真的如果只是自己做開心的,
那用什麼技術與概念又何妨呢是吧?人生就是輕鬆玩樂不需要一直給自己找碴,生活還不夠苦嗎XD
前端最有趣的就是你怎麼寫,畫面就怎麼回饋給你,
比這個人生online還要好操控多惹d(`・∀・)b

就當作遊戲來跟著這個系列探索世界吧!!
請繼續關注,
跟著我們這個系列繼續動手玩創意!!未來還有更多更新鮮的花招呢(。◕∀◕。)


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言