【问题标题】:Detect that canvas element is outside of canvas boundary检测画布元素在画布边界之外
【发布时间】:2018-08-20 11:23:44
【问题描述】:

我正在做一个项目,管理员可以创建一个卡片模板,他们可以在其中插入占位符变量,如 {first_name}{last_name}{website} 等。然后通过让用户填写来创建卡片他们的名字,姓氏等。所以基本上占位符将替换为用户提供的实际内容。为此,我从管理员创建的模板创建 SVG 图像,并将这些占位符变量替换为服务器端的用户数据。

问题是,如果用户提供的内容太长,那么它可能会超出画布边界,因此在打印实际卡片时可能会被截断。

有没有办法检测到,在替换占位符后,画布元素延伸到画布边界之外?如果是这样,有没有办法找到该元素并使其缩小直到它适合边界?基本上,我想要this 之类的东西,但在服务器端。

这是我用来生成 SVG 图像的一些示例代码:

$message_string = array('{first_name}','{last_name}');
$replace_string = array('Fist Name of User','Last Name Of User');
$front_svg_url = $svg_url.$res_code[0]['front_side_svg_image'];
$front_raw_svg = file_get_contents($front_svg_url);
$front_side_svg = str_ireplace($message_string, $replace_string, $front_raw_svg);
$file_name = uniqid($prefix).".svg";
$file_handle = fopen("$folder_name/".$file_name, 'w');
fwrite($file_handle, $front_side_svg);
fclose($file_handle);

在服务器端我只是替换变量,所以我不确定如何在服务器上实现这一点。我对任何可以实现我预期输出的想法持开放态度。

【问题讨论】:

    标签: javascript php canvas svg fabricjs


    【解决方案1】:

    你可以使用PHP函数imageftfbox(GD lib应该启用)。

    它返回坐标数组 [x0,y0, x1,y1, x2,y2, x3,y3]。

    根据它们,您可以确定它是否超出了您的 SVG 元素放置,以下是您如何执行此操作的示例:

    function cutStringToPix($str, $svgWidth, $fontSize = 14, $font='times_new_roman.ttf', $delimiter = '') 
      $font = './fonts/' .$font;
      $sWidth = $svgWidth;
      $newStr = $str;
      $words = $delimiter
         ? explode($delimiter, $str)
         : str_split($str);
      $wordsCnt = count($words);
    
      // Reduce your string until it fits
      for (;$sWidth >= $svgWidth && $wordsCnt; $wordsCnt--) {
        $newStr = implode(' ', array_slice($words, 0, $wordsCnt));
        $bbox = imagettfbbox($fontSize, 0, $font, $newStr);
        $sWidth = $bbox[2] - $bbox[0];
      };
      return $newStr;
    }
    // Now use your $newStr
    

    好吧,那是你的 example 来自评论

    它使用 TimesNewRoman 字体,您需要为它找到 TTF(for instance this...) 并将其保存在服务器上的“fonts”目录中(相对于您想要存储 'cutStringToPix' 函数的 lib.php)作为 'times_new_roman.ttf '

    那么你的 SVG 形成部​​分将是这样的:

    //include 'cutStringPix' func
    
    $message_string = array('{first_name}','{last_name}');
    $replace_string = array('Fist Name of User','Last Name Of User');
    $front_svg_url = $svg_url.$res_code[0]['front_side_svg_image'];
    $front_raw_svg = file_get_contents($front_svg_url);
    //so what we adding:
    $replace_string = cutStringToPix($replace_string, 162, 13);
    
    $front_side_svg = str_ireplace($message_string, $replace_string, $front_raw_svg);
    $file_name = uniqid($prefix).".svg";
    

    【讨论】:

    • 如果您可以使用 svg 提供示例,那么它可能会更清楚。您可以查看此 svg:codepen.io/dhavalsisodiya/pen/bvGGvp 那么我应该如何使用该 svg 实现您的方法?例如。 {qr_code_value} 值可能太长,因此可能超出边界。
    • 不管是不是svg。你有一个宽度以像素为单位的图像,你的 {qr_code_value} 是一个可以在 php 中检查的变量,($str),你的示例 svg 的宽度 = 255,{qr_code_value} 偏移量是 93,所以对你来说 $svgWidth = 162. 现在你需要在你的服务器上加载times_new_roman.ttf,并使用我发布的那个例子来减少“str_ireplace”之前的{qr_code_value}
    • 是的。忘记在示例 13 中添加 fontSize,所以 imagettfbbox 的第一个参数应该是 13(不是 14)
    猜你喜欢
    • 2014-01-05
    • 2018-07-09
    • 1970-01-01
    • 2023-03-24
    • 2016-10-08
    • 1970-01-01
    • 2021-12-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多