let inkColorData; // Variable to store the ink color data object let currentBrightness; // Set a default value for brightness let currentBrightnessChange; // Default change value var inkTool = inkTool || {}; inkTool.EventScript = function ($) { $(document).ready(function () { // Variable definitions function generateTimestamp() { return new Date().getTime(); } var timestamp = generateTimestamp(); const ink_csvFile = "https://ryokuyou.co.jp/tr/csv/live_ink-sim-starry-colors.csv" + "?timestamp=" + timestamp; const paper_target = $("#paperSelect1"); const ink_target = $("#colorSelect1, #colorSelect2"); const image_target = $("#imageSelect1"); var imagelist = [ { name: "サンプル1", url: "aHR0cHM6Ly93d3cucnlva3V5b3UuY28uanAvd3AyL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDI0LzEwL3NhbXBsZV9zdGFycnkwMS5wbmc=", realurl: "https://www.ryokuyou.co.jp/wp2/wp-content/uploads/2024/10/sample_starry01.png", }, { name: "サンプル2", url: "aHR0cHM6Ly93d3cucnlva3V5b3UuY28uanAvd3AyL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDI0LzEwL3NhbXBsZV9zdGFycnkwMi5wbmc=", realurl: "https://www.ryokuyou.co.jp/wp2/wp-content/uploads/2024/10/sample_starry02.png", }, { name: "サンプル3", url: "aHR0cHM6Ly93d3cucnlva3V5b3UuY28uanAvd3AyL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDI0LzEwL3NhbXBsZV9zdGFycnkwMy5wbmc=", realurl: "https://www.ryokuyou.co.jp/wp2/wp-content/uploads/2024/10/sample_starry03.png", }, { name: "サンプル4", url: "aHR0cHM6Ly93d3cucnlva3V5b3UuY28uanAvd3AyL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDI0LzEwL3NhbXBsZV9zdGFycnkwNC5wbmc=", realurl: "https://www.ryokuyou.co.jp/wp2/wp-content/uploads/2024/10/sample_starry04.png", }, { name: "サンプル5", url: "aHR0cHM6Ly93d3cucnlva3V5b3UuY28uanAvd3AyL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDI0LzEwL3NhbXBsZV9zdGFycnkwNS5wbmc=", realurl: "https://www.ryokuyou.co.jp/wp2/wp-content/uploads/2024/10/sample_starry05.png", }, ]; // Function definitions function readCsv(data, dataType) { const csvList = $.csv.toArrays(data); let insert = ""; const inkColorDataObj = {}; // Create an object to store ink color data function getLetter(i) { return String.fromCharCode(64 + i); } for (let i = 1; i < csvList.length; i++) { if (csvList[i][0] == 1) { if (dataType === "paper") { insert += `
  • ${csvList[i][2]} ${csvList[i][2]}
  • `; const kamiColor = csvList[i][1]; } else if (dataType === "ink") { let letterIndex = getLetter(i); // Get the letter corresponding to the current index insert += `
  • ${letterIndex}. ${csvList[i][4]}
  • `; // Store ink color data in the inkColorDataObj const inkColor = csvList[i][1]; inkColorDataObj[inkColor] = { color: csvList[i][2], defaultBrightness: parseFloat(csvList[i][7]), brightnessChange: parseFloat(csvList[i][8]), }; } } } if (dataType === "paper") { //console.log("Inserting paper data:", insert); paper_target.append(insert); } else if (dataType === "ink") { //console.log("Inserting ink data:", insert); ink_target.append(insert); } return inkColorDataObj; // Return the inkColorDataObj } // Ajax calls to load CSV files $.ajaxSetup({ dataType: "text", }); // Load ink CSV $.ajax({ url: ink_csvFile, success: function (data) { inkColorData = readCsv(data, "ink"); // Store the ink color data object //console.log("Ink CSV loaded successfully"); updateInkVisualization1(); // Call the function to set the default visualization updateInkVisualization2(); }, }); //activates the pulldown menus - works $(".pulldown").click(function () { const target = $(this).data("target"); $(this).closest(".pulldown").find(".title").toggleClass("rotated"); $("#" + target + ".subMenu").slideToggle(150); }); // Create a custom dropdown for images var customDropdown = $("#imageSelect1"); // Populate the custom dropdown with options from the imagelist array customDropdown.empty(); // Clear existing options imagelist.forEach(function (image) { var liElement = $( "
  • " ); var spanElement = $("").text(image.name); var imgElement = $("") .attr("src", image.realurl) .attr("alt", image.name); liElement.append(spanElement).prepend(imgElement); customDropdown.append(liElement); }); // Load the paper image document .getElementById("paperImage") .addEventListener("load", adjustDivHeights); function adjustDivHeights() { const paperImage = document.getElementById("paperImage"); const maskedDiv = document.getElementById("masked-div"); const maskImage = document.getElementById("mask-image"); // Adjust the height of the paperImage paperImage.style.height = `${paperImage.clientHeight}px`; // Adjust the height of the maskedDiv and the maskImage maskedDiv.style.height = `${paperImage.clientHeight}px`; maskImage.style.height = `${paperImage.clientHeight}px`; } // Set up the File Upload // Cache jQuery selectors for better performance var $imageUploadInput = $("#imageUploadInput"); var $maskImage = $("#mask-image"); var $imageSelect = $("#imageSelect1"); var $imageOptions = $("#imageOptions1"); var $customDropdown = $imageSelect; // Alias for clarity // Event Listener for File Upload $imageUploadInput.on("change", function (event) { var file = event.target.files[0]; // Validate File Selection if (!file) { console.warn("選択されたファイルはありません。"); return; } // Validate File Type (PNG) if (file.type !== "image/png") { alert("PNGファイルのみ使用可能です。PNGファイルを選択してください。"); $imageUploadInput.val(""); // Clear the input return; } // Optional: Validate File Size (e.g., Max 5MB) var maxSize = 5 * 1024 * 1024; // 5MB if (file.size > maxSize) { alert("ファイルサイズは5MB以下にしてください。"); $imageUploadInput.val(""); // Clear the input return; } var reader = new FileReader(); reader.onload = function () { var imageDataURL = reader.result; // Update the mask-image src to display the uploaded image $maskImage.attr("src", imageDataURL); $maskImage.css("display", "block"); // Ensure the image is visible // Add the uploaded image to the pulldown var $liElement = $("
  • ", { class: "image uploaded", "data-name": file.name, "data-url": imageDataURL, }); var $thumbnailImg = $("", { class: "imageThumb", src: imageDataURL, alt: "アップロードした画像", }); var $spanElement = $("", { class: "imageName", text: file.name, }); // Append the thumbnail and name to the li $liElement.append($thumbnailImg).append($spanElement); // Prepend the new li to the pulldown list $imageSelect.prepend($liElement); //update title in $imageSelect pulldown $imageSelect.closest(".pulldown").find(".title").text(file.name); // Provide visual feedback by toggling the pulldown $imageOptions.addClass("open"); // Open the pulldown setTimeout(function () { $imageOptions.removeClass("open"); // Close after 500ms }, 500); }; // Read the uploaded file as a Data URL (Base64) reader.readAsDataURL(file); }); // Optional: Handle Clicks on Pulldown Items to Display Selected Image $imageSelect.on("click", "li.image", function () { var imageUrl = $(this).data("url"); // Update the mask-image src to the selected image $maskImage.attr("src", imageUrl); $maskImage.css("display", "block"); // Ensure the image is visible // Optionally, toggle the pulldown closed $imageOptions.removeClass("open"); }); // Optional: Toggle Pulldown on Click of the Pulldown Title $(".pulldown .title").on("click", function () { var targetId = $(this).parent().data("target"); $("#" + targetId).toggleClass("open"); }); // Handle the click event on the custom dropdown for images $(document).on("click", "#imageSelect1 li.image", function () { var selectedImageName = $(this).data("name"); var imageSrc = $(this).data("url"); // Update the pulldown title with the uploaded image's name $imageOptions.find(".title").text(selectedImageName); // Determine if the image is uploaded or from the imagelist if ($(this).hasClass("uploaded")) { // If the image is uploaded, use the URL directly without Base64 decoding or protection $("#mask-image").attr("src", imageSrc); document.querySelector(".masked-div").style.maskImage = "url(" + imageSrc + ")"; $("#imageImage").attr("src", imageSrc); } else { // If the image is from the imagelist, apply anti-download protection var decodedUrl = atob(imageSrc); // Fetch the image data as Blob fetch(decodedUrl) .then((response) => response.blob()) .then((blob) => { // Create a temporary Blob URL var blobUrl = URL.createObjectURL(blob); // Use the Blob URL in place of the original URL $("#mask-image").attr("src", blobUrl); document.querySelector(".masked-div").style.maskImage = "url(" + blobUrl + ")"; $("#imageImage").attr("src", blobUrl); }) .catch((err) => { console.error("Image fetch failed", err); }); } // Update other UI elements $imageOptions.find(".title").text(selectedImageName); // $("#imageDiv1").removeClass().addClass(selectedImageName); }); // Handle the click event on the custom dropdown for papers $(document).on("click", "#paperSelect1 li.paper", function () { $(this).closest("#PaperOptions1").find(".title").text($(this).text()); var paperSrc = $(this).find("img.paperThumb").attr("src"); //console.log("Selected paper source:", paperSrc); $("#paperImage").attr("src", paperSrc); // Update the background image of the .masked-div element document.querySelector(".masked-div").style.backgroundImage = "url(" + paperSrc + ")"; // Add paper name to results panel var kamiName = $(this).find("img.paperThumb").attr("alt"); //console.log("Selected paper value:", kamiName); $(".paper-result").html("紙名: " + kamiName); const selectedPaperColor = $(this).attr("data-name"); $("#paperDiv1").removeClass().addClass(selectedPaperColor); }); // Add event listener to detect color selection for overlay $(document).on("click", "#inkOptions1.pulldown ul.subMenu li", function () { $(this).closest("#inkOptions1").find(".title").text($(this).text()); const colVal = $(this).attr("data-hex"); const mixVal = $(this).attr("data-mix"); const defaultBrightness = $(this).attr("data-brightness"); //$("#overlay1").css("background", colVal); $("#overlay1").css("background", "var(--noisebg), " + colVal); $("#overlay1").css("filter", "brightness(" + defaultBrightness + ")"); console.log("filter: brightness: ", defaultBrightness); // Check the value in the console $("#overlay1").css("mix-blend-mode", mixVal); // Set the ink name and density value to the results panel const inkName1 = $(this).text(); $(".ink-result1").html(`基本色1: ${inkName1}`); const selectedDensity = $('input[name="button-group"]:checked').val(); const selectedInkColor = $(this).attr("data-name"); $("#overlay1").removeClass().addClass(selectedInkColor); const inkData = inkColorData[selectedInkColor]; // if (inkData && typeof inkData === "object" && inkData.hasOwnProperty(`defaultBrightness`)) { if (inkData) { // const defBrightness = inkData.defaultBrightness; // $("#overlay1").css("filter", `brightness(${defBrightness})`); currentBrightness = inkColorData[selectedInkColor].defaultBrightness; currentBrightnessChange = inkColorData[selectedInkColor].brightnessChange; } else { //console.log("Error: Invalid or missing brightness data."); } }); $(document).on("click", "#inkOptions2.pulldown ul.subMenu li", function () { $(this).closest("#inkOptions2").find(".title").text($(this).text()); const colVal = $(this).attr("data-hex"); const mixVal = $(this).attr("data-mix"); $("#overlay2").css("background-color", colVal); //console.log("Mix Blend Mode 2:", mixVal); // Check the value in the console $("#overlay2").css("mix-blend-mode", mixVal); // Set the ink name and density value to the results panel const inkName2 = $(this).text(); $(".ink-result2").html(`基本色2: ${inkName2}`); // Update the opacity of #overlay1 for the selected density (previously defaultBrightness) const selectedDensity = $('input[name="button-group"]:checked').val(); const selectedInkColor = $(this).attr("data-name"); $("#overlay2").removeClass().addClass(selectedInkColor); const inkData = inkColorData[selectedInkColor]; if ( inkData && typeof inkData === "object" && inkData.hasOwnProperty(`defaultBrightness`) ) { const defBrightness = inkData[`opacity${selectedDensity}`]; $("#overlay2").css("opacity", defBrightness); } else { //console.log("Error: Invalid ink data or missing opacity value."); } }); // Function to update the ink visualization based on selected density function updateInkVisualization1() { const selectedDensity = $('input[name="button-group"]:checked').data( "density" ); //console.log("Selected Density:", selectedDensity); // Get the selected ink color, if any const selectedInkColorElement = $( "#inkOptions1.pulldown ul.subMenu li.active" ); const selectedInkColor = selectedInkColorElement.length ? selectedInkColorElement.attr("data-name") : null; //console.log("Selected Ink Color:", selectedInkColor); // If no ink color is selected, you can choose to set a default color or skip the update if (!selectedInkColor) { //console.log("No ink color selected."); return; // Exit the function without updating the ink visualization } const inkData = inkColorData[selectedInkColor]; // Retrieve the ink data for the selected color // Check if inkData is valid and contains the required opacity values if ( !inkData || typeof inkData !== "object" || isNaN(inkData[`opacity${selectedDensity}`]) ) { //console.log("Error: Invalid ink data or missing opacity value."); return; // Exit the function to prevent further errors } const defBrightness = inkData[`filter: brightness(${defaultBrightness})`]; //console.log("Selected Opacity:", defBrightness); $("#overlay1").css("opacity", defBrightness); // Update the opacity of #overlay1 // Update the ink visualization with the selected opacity $(".ink").css({ "background-color": inkData.color, "mix-blend-mode": inkData.mixblendmode, }); } function updateInkVisualization2() { const selectedDensity = $('input[name="button-group"]:checked').data( "density" ); //console.log("Selected Density:", selectedDensity); // Get the selected ink color, if any const selectedInkColorElement = $( "#inkOptions2.pulldown ul.subMenu li.active" ); const selectedInkColor = selectedInkColorElement.length ? selectedInkColorElement.attr("data-name") : null; //console.log("Selected Ink Color:", selectedInkColor); // If no ink color is selected, you can choose to set a default color or skip the update if (!selectedInkColor) { //console.log("No ink color selected."); return; // Exit the function without updating the ink visualization } const inkData = inkColorData[selectedInkColor]; // Retrieve the ink data for the selected color // Check if inkData is valid and contains the required opacity values if ( !inkData || typeof inkData !== "object" || isNaN(inkData[`opacity${selectedDensity}`]) ) { //console.log("Error: Invalid ink data or missing opacity value."); return; // Exit the function to prevent further errors } const defBrightness = inkData[`filter: brightness(${defaultBrightness})`]; //console.log("Selected Opacity:", defBrightness); $("#overlay2").css("opacity", defBrightness); // Update the opacity of #overlay1 // Update the ink visualization with the selected opacity $(".ink").css({ "background-color": inkData.color, "filter": inkData.defBrightness, }); } // Event listener for ink color options $(document).on("click", "#inkOptions1.pulldown ul.subMenu li", function () { // Remove "active" class from all ink color options $("#inkOptions1.pulldown ul.subMenu li").removeClass("active"); // Add "active" class to the selected ink color option $(this).addClass("active"); // Update the ink visualization updateInkVisualization1(); }); // Event listener for ink color options $(document).on("click", "#inkOptions2.pulldown ul.subMenu li", function () { // Remove "active" class from all ink color options $("#inkOptions2.pulldown ul.subMenu li").removeClass("active"); // Add "active" class to the selected ink color option $(this).addClass("active"); // Update the ink visualization updateInkVisualization2(); }); // Attach event handlers to the radio buttons $('input[name="button-group"]').on("change", function () { // Get the selected density from the data-density attribute of the checked radio button const selectedDensity = $('input[name="button-group"]:checked').data( "density" ); //console.log("Selected Density:", selectedDensity); // Update the ink visualization updateInkVisualization1(); updateInkVisualization2(); }); // Call the update function initially to set the default visualization updateInkVisualization1(); updateInkVisualization2(); }); }; const pulldownElements = document.querySelectorAll(".pulldown"); pulldownElements.forEach((pulldown) => { pulldown.addEventListener("click", function (event) { // Close all other pulldowns pulldownElements.forEach((otherPulldown) => { if (otherPulldown !== pulldown) { otherPulldown.classList.remove("open"); } }); // Toggle the 'open' class on the clicked pulldown pulldown.classList.toggle("open"); }); }); jQuery(document).ready(function ($) { inkTool.EventScript($); }); // Disable context menu if (!/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) { document.querySelectorAll("#paperDiv1, #imageSelect1").forEach(function (image) { image.addEventListener("contextmenu", function (e) { e.preventDefault(); }, false ); }); } document.addEventListener("DOMContentLoaded", () => { const container = document.getElementById("paperDiv1"); // The container div const overlay = document.getElementById("overlay1"); // Overlay div const imageDiv = document.getElementById("image-div"); // Image div holding the image const brtpc = 0.1; // Brightness percentage adjustment const hoverToggleButton = document .getElementById("hover-toggle-button") .querySelector("button"); // Get the button inside the div let hoverEnabled = false; // Start with hover disabled // Handle button click for hover effect toggle hoverToggleButton.addEventListener("click", () => { // Toggle the aria-pressed state const isPressed = hoverToggleButton.getAttribute("aria-pressed") === "true"; hoverToggleButton.setAttribute("aria-pressed", !isPressed); hoverToggleButton.classList.add("active"); if (isPressed) { hoverToggleButton.classList.remove("active"); } hoverEnabled = !isPressed; // Update hoverEnabled based on button state if (hoverEnabled) { // Enable the 3D tilt effect by adding event listeners container.addEventListener("mousemove", handleMouseMove); container.addEventListener("mouseleave", resetTransform); container.addEventListener("touchmove", handleTouchMove); container.addEventListener("touchend", resetTransform); container.addEventListener("touchstart", resetTransform); } else { // Disable the 3D tilt effect by removing event listeners container.removeEventListener("mousemove", handleMouseMove); container.removeEventListener("mouseleave", resetTransform); container.removeEventListener("touchmove", handleTouchMove); container.removeEventListener("touchend", resetTransform); container.removeEventListener("touchstart", resetTransform); // Reset the div's position and appearance overlay.style.transform = "rotateX(0) rotateY(0)"; imageDiv.style.transform = "rotateX(0) rotateY(0)"; overlay.style.filter = `brightness(${brightness})`; } }); let lastMouseMove = 0; let lastTouchMove = 0; // To limit touch events to ~60fps const handleMove = (x, y, rect) => { const rotateX = (0.5 - y / rect.height) * 10; const rotateY = (0.5 - x / rect.width) * 10; requestAnimationFrame(() => { const transformValue = `rotateX(${rotateX}deg) rotateY(${rotateY}deg)`; overlay.style.transform = transformValue; imageDiv.style.transform = transformValue; }); let brightness; const midpoint = rect.height / 2; if (y < midpoint) { const factor = (midpoint - y) / midpoint; brightness = currentBrightness + (currentBrightnessChange * factor); console.log("if y < midpoint", brightness); // Debug log } else { const factor = (y - midpoint) / midpoint; brightness = currentBrightness - (currentBrightnessChange * factor); console.log("else y < midpoint", brightness); // Debug log } // Apply the calculated brightness filter overlay.style.filter = `brightness(${brightness})`; console.log("Applied brightness:", overlay.style.filter); // Debug log the applied filter }; // Handle mouse movement (desktop) const handleMouseMove = (e) => { const now = Date.now(); if (now - lastMouseMove < 16) return; // Limit to ~60fps lastMouseMove = now; const rect = container.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; handleMove(x, y, rect); }; // Handle touch movement (mobile) const handleTouchMove = (e) => { const now = Date.now(); if (now - lastTouchMove < 16) return; // Limit to ~60fps lastTouchMove = now; const rect = container.getBoundingClientRect(); const touch = e.touches[0]; // Get the first touch point const x = touch.clientX - rect.left; const y = touch.clientY - rect.top; handleMove(x, y, rect); }; // Reset transformation on mouse or touch leave/end const resetTransform = () => { overlay.style.transition = "transform 0.2s ease, filter 0.2s ease"; imageDiv.style.transition = "transform 0.2s ease"; overlay.style.transform = "rotateX(0) rotateY(0)"; imageDiv.style.transform = "rotateX(0) rotateY(0)"; overlay.style.filter = `brightness(${currentBrightness})`; }; });